42 LLVMTypeRef deform_sig;
43 LLVMValueRef v_deform_fn;
45 LLVMBasicBlockRef b_entry;
46 LLVMBasicBlockRef b_adjust_unavail_cols;
47 LLVMBasicBlockRef b_find_start;
49 LLVMBasicBlockRef b_out;
50 LLVMBasicBlockRef b_dead;
51 LLVMBasicBlockRef *attcheckattnoblocks;
52 LLVMBasicBlockRef *attstartblocks;
53 LLVMBasicBlockRef *attisnullblocks;
54 LLVMBasicBlockRef *attcheckalignblocks;
55 LLVMBasicBlockRef *attalignblocks;
56 LLVMBasicBlockRef *attstoreblocks;
60 LLVMValueRef v_tupdata_base;
61 LLVMValueRef v_tts_values;
62 LLVMValueRef v_tts_nulls;
63 LLVMValueRef v_slotoffp;
64 LLVMValueRef v_flagsp;
65 LLVMValueRef v_nvalidp;
66 LLVMValueRef v_nvalid;
67 LLVMValueRef v_maxatt;
71 LLVMValueRef v_tupleheaderp;
72 LLVMValueRef v_tuplep;
73 LLVMValueRef v_infomask1;
74 LLVMValueRef v_infomask2;
79 LLVMValueRef v_hasnulls;
82 int guaranteed_column_number = -1;
85 int known_alignment = 0;
88 bool attguaranteedalign =
true;
124 if (att->attnotnull &&
125 !att->atthasmissing &&
127 guaranteed_column_number =
attnum;
132 LLVMTypeRef param_types[1];
136 deform_sig = LLVMFunctionType(LLVMVoidType(), param_types,
139 v_deform_fn = LLVMAddFunction(mod,
funcname, deform_sig);
140 LLVMSetLinkage(v_deform_fn, LLVMInternalLinkage);
141 LLVMSetParamAlignment(LLVMGetParam(v_deform_fn, 0), MAXIMUM_ALIGNOF);
145 LLVMAppendBasicBlock(v_deform_fn,
"entry");
146 b_adjust_unavail_cols =
147 LLVMAppendBasicBlock(v_deform_fn,
"adjust_unavail_cols");
149 LLVMAppendBasicBlock(v_deform_fn,
"find_startblock");
151 LLVMAppendBasicBlock(v_deform_fn,
"outblock");
153 LLVMAppendBasicBlock(v_deform_fn,
"deadblock");
155 b = LLVMCreateBuilder();
157 attcheckattnoblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
158 attstartblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
159 attisnullblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
160 attcheckalignblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
161 attalignblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
162 attstoreblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
166 LLVMPositionBuilderAtEnd(
b, b_entry);
169 v_offp = LLVMBuildAlloca(
b,
TypeSizeT,
"v_offp");
171 v_slot = LLVMGetParam(v_deform_fn, 0);
184 LLVMValueRef v_heapslot;
198 LLVMValueRef v_minimalslot;
221 LLVMBuildStructGEP(
b, v_tuplep,
224 l_ptr(LLVMInt8Type()),
227 l_load_struct_gep(
b, v_tuplep,
237 LLVMBuildICmp(
b, LLVMIntNE,
245 v_maxatt = LLVMBuildAnd(
b,
256 l_load_struct_gep(
b, v_tuplep,
259 LLVMInt32Type(),
"t_hoff");
265 l_ptr(LLVMInt8Type()),
275 LLVMValueRef v_off_start;
277 v_off_start = LLVMBuildLoad(
b, v_slotoffp,
"v_slot_off");
278 v_off_start = LLVMBuildZExt(
b, v_off_start,
TypeSizeT,
"");
279 LLVMBuildStore(
b, v_off_start, v_offp);
285 attcheckattnoblocks[
attnum] =
286 l_bb_append_v(v_deform_fn,
"block.attr.%d.attcheckattno",
attnum);
288 l_bb_append_v(v_deform_fn,
"block.attr.%d.start",
attnum);
290 l_bb_append_v(v_deform_fn,
"block.attr.%d.attisnull",
attnum);
291 attcheckalignblocks[
attnum] =
292 l_bb_append_v(v_deform_fn,
"block.attr.%d.attcheckalign",
attnum);
294 l_bb_append_v(v_deform_fn,
"block.attr.%d.align",
attnum);
296 l_bb_append_v(v_deform_fn,
"block.attr.%d.store",
attnum);
307 if ((natts - 1) <= guaranteed_column_number)
310 LLVMBuildBr(
b, b_adjust_unavail_cols);
311 LLVMPositionBuilderAtEnd(
b, b_adjust_unavail_cols);
312 LLVMBuildBr(
b, b_find_start);
316 LLVMValueRef v_params[3];
320 LLVMBuildICmp(
b, LLVMIntULT,
322 l_int16_const(natts),
324 b_adjust_unavail_cols,
328 LLVMPositionBuilderAtEnd(
b, b_adjust_unavail_cols);
330 v_params[0] = v_slot;
331 v_params[1] = LLVMBuildZExt(
b, v_maxatt, LLVMInt32Type(),
"");
332 v_params[2] = l_int32_const(natts);
335 LLVMBuildBr(
b, b_find_start);
338 LLVMPositionBuilderAtEnd(
b, b_find_start);
340 v_nvalid = LLVMBuildLoad(
b, v_nvalidp,
"");
350 LLVMValueRef v_switch = LLVMBuildSwitch(
b, v_nvalid,
355 LLVMValueRef v_attno = l_int16_const(
attnum);
357 LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[
attnum]);
363 LLVMBuildBr(
b, attcheckattnoblocks[0]);
366 LLVMPositionBuilderAtEnd(
b, b_dead);
367 LLVMBuildUnreachable(
b);
376 LLVMValueRef v_incby;
378 LLVMValueRef l_attno = l_int16_const(
attnum);
379 LLVMValueRef v_attdatap;
380 LLVMValueRef v_resultp;
383 LLVMPositionBuilderAtEnd(
b, attcheckattnoblocks[
attnum]);
391 LLVMBuildStore(
b, l_sizet_const(0), v_offp);
399 if (
attnum <= guaranteed_column_number)
401 LLVMBuildBr(
b, attstartblocks[
attnum]);
405 LLVMValueRef v_islast;
407 v_islast = LLVMBuildICmp(
b, LLVMIntUGE,
411 LLVMBuildCondBr(
b, v_islast, b_out, attstartblocks[
attnum]);
413 LLVMPositionBuilderAtEnd(
b, attstartblocks[
attnum]);
420 if (!att->attnotnull)
422 LLVMBasicBlockRef b_ifnotnull;
423 LLVMBasicBlockRef b_ifnull;
424 LLVMBasicBlockRef b_next;
425 LLVMValueRef v_attisnull;
426 LLVMValueRef v_nullbyteno;
427 LLVMValueRef v_nullbytemask;
428 LLVMValueRef v_nullbyte;
429 LLVMValueRef v_nullbit;
431 b_ifnotnull = attcheckalignblocks[
attnum];
432 b_ifnull = attisnullblocks[
attnum];
437 b_next = attcheckattnoblocks[
attnum + 1];
439 v_nullbyteno = l_int32_const(
attnum >> 3);
440 v_nullbytemask = l_int8_const(1 << ((
attnum) & 0x07));
441 v_nullbyte = l_load_gep1(
b, v_bits, v_nullbyteno,
"attnullbyte");
443 v_nullbit = LLVMBuildICmp(
b,
445 LLVMBuildAnd(
b, v_nullbyte, v_nullbytemask,
""),
449 v_attisnull = LLVMBuildAnd(
b, v_hasnulls, v_nullbit,
"");
451 LLVMBuildCondBr(
b, v_attisnull, b_ifnull, b_ifnotnull);
453 LLVMPositionBuilderAtEnd(
b, b_ifnull);
458 LLVMBuildGEP(
b, v_tts_nulls, &l_attno, 1,
""));
462 LLVMBuildGEP(
b, v_tts_values, &l_attno, 1,
""));
464 LLVMBuildBr(
b, b_next);
465 attguaranteedalign =
false;
470 LLVMBuildBr(
b, attcheckalignblocks[
attnum]);
471 LLVMPositionBuilderAtEnd(
b, attisnullblocks[
attnum]);
472 LLVMBuildBr(
b, attcheckalignblocks[
attnum]);
474 LLVMPositionBuilderAtEnd(
b, attcheckalignblocks[
attnum]);
477 if (att->attalign == TYPALIGN_INT)
478 alignto = ALIGNOF_INT;
479 else if (att->attalign == TYPALIGN_CHAR)
481 else if (att->attalign == TYPALIGN_DOUBLE)
482 alignto = ALIGNOF_DOUBLE;
483 else if (att->attalign == TYPALIGN_SHORT)
484 alignto = ALIGNOF_SHORT;
501 (known_alignment < 0 || known_alignment !=
TYPEALIGN(alignto, known_alignment)))
512 if (att->attlen == -1)
514 LLVMValueRef v_possible_padbyte;
515 LLVMValueRef v_ispad;
519 attguaranteedalign =
false;
521 v_off = LLVMBuildLoad(
b, v_offp,
"");
524 l_load_gep1(
b, v_tupdata_base, v_off,
"padbyte");
526 LLVMBuildICmp(
b, LLVMIntEQ,
527 v_possible_padbyte, l_int8_const(0),
529 LLVMBuildCondBr(
b, v_ispad,
535 LLVMBuildBr(
b, attalignblocks[
attnum]);
538 LLVMPositionBuilderAtEnd(
b, attalignblocks[
attnum]);
542 LLVMValueRef v_off_aligned;
543 LLVMValueRef v_off = LLVMBuildLoad(
b, v_offp,
"");
546 LLVMValueRef v_alignval = l_sizet_const(alignto - 1);
549 LLVMValueRef v_lh = LLVMBuildAdd(
b, v_off, v_alignval,
"");
552 LLVMValueRef v_rh = l_sizet_const(~(alignto - 1));
554 v_off_aligned = LLVMBuildAnd(
b, v_lh, v_rh,
"aligned_offset");
556 LLVMBuildStore(
b, v_off_aligned, v_offp);
564 if (known_alignment >= 0)
566 Assert(known_alignment != 0);
567 known_alignment =
TYPEALIGN(alignto, known_alignment);
570 LLVMBuildBr(
b, attstoreblocks[
attnum]);
571 LLVMPositionBuilderAtEnd(
b, attstoreblocks[
attnum]);
575 LLVMPositionBuilderAtEnd(
b, attcheckalignblocks[
attnum]);
576 LLVMBuildBr(
b, attalignblocks[
attnum]);
577 LLVMPositionBuilderAtEnd(
b, attalignblocks[
attnum]);
578 LLVMBuildBr(
b, attstoreblocks[
attnum]);
580 LLVMPositionBuilderAtEnd(
b, attstoreblocks[
attnum]);
588 if (attguaranteedalign)
590 Assert(known_alignment >= 0);
591 LLVMBuildStore(
b, l_sizet_const(known_alignment), v_offp);
598 known_alignment = -1;
599 attguaranteedalign =
false;
601 else if (att->attnotnull && attguaranteedalign && known_alignment >= 0)
609 known_alignment += att->attlen;
611 else if (att->attnotnull && (att->attlen % alignto) == 0)
619 known_alignment = alignto;
620 Assert(known_alignment > 0);
621 attguaranteedalign =
false;
625 known_alignment = -1;
626 attguaranteedalign =
false;
632 LLVMValueRef v_off = LLVMBuildLoad(
b, v_offp,
"");
635 LLVMBuildGEP(
b, v_tupdata_base, &v_off, 1,
"");
639 v_resultp = LLVMBuildGEP(
b, v_tts_values, &l_attno, 1,
"");
642 LLVMBuildStore(
b, l_int8_const(0),
643 LLVMBuildGEP(
b, v_tts_nulls, &l_attno, 1,
""));
651 LLVMValueRef v_tmp_loaddata;
652 LLVMTypeRef vartypep =
653 LLVMPointerType(LLVMIntType(att->attlen * 8), 0);
656 LLVMBuildPointerCast(
b, v_attdatap, vartypep,
"");
657 v_tmp_loaddata = LLVMBuildLoad(
b, v_tmp_loaddata,
"attr_byval");
658 v_tmp_loaddata = LLVMBuildZExt(
b, v_tmp_loaddata,
TypeSizeT,
"");
660 LLVMBuildStore(
b, v_tmp_loaddata, v_resultp);
664 LLVMValueRef v_tmp_loaddata;
672 LLVMBuildStore(
b, v_tmp_loaddata, v_resultp);
678 v_incby = l_sizet_const(att->attlen);
680 else if (att->attlen == -1)
682 v_incby = LLVMBuildCall(
b,
686 l_callsite_ro(v_incby);
687 l_callsite_alwaysinline(v_incby);
689 else if (att->attlen == -2)
691 v_incby = LLVMBuildCall(
b,
693 &v_attdatap, 1,
"strlen");
695 l_callsite_ro(v_incby);
698 v_incby = LLVMBuildAdd(
b, v_incby, l_sizet_const(1),
"");
706 if (attguaranteedalign)
708 Assert(known_alignment >= 0);
709 LLVMBuildStore(
b, l_sizet_const(known_alignment), v_offp);
713 LLVMValueRef v_off = LLVMBuildLoad(
b, v_offp,
"");
715 v_off = LLVMBuildAdd(
b, v_off, v_incby,
"increment_offset");
716 LLVMBuildStore(
b, v_off, v_offp);
726 LLVMBuildBr(
b, b_out);
730 LLVMBuildBr(
b, attcheckattnoblocks[
attnum + 1]);
736 LLVMPositionBuilderAtEnd(
b, b_out);
739 LLVMValueRef v_off = LLVMBuildLoad(
b, v_offp,
"");
740 LLVMValueRef v_flags;
742 LLVMBuildStore(
b, l_int16_const(natts), v_nvalidp);
743 v_off = LLVMBuildTrunc(
b, v_off, LLVMInt32Type(),
"");
744 LLVMBuildStore(
b, v_off, v_slotoffp);
745 v_flags = LLVMBuildLoad(
b, v_flagsp,
"tts_flags");
746 v_flags = LLVMBuildOr(
b, v_flags, l_int16_const(
TTS_FLAG_SLOW),
"");
747 LLVMBuildStore(
b, v_flags, v_flagsp);
751 LLVMDisposeBuilder(
b);
#define TYPEALIGN(ALIGNVAL, LEN)
elog(ERROR, "%s: %s", p2, msg)
const TupleTableSlotOps TTSOpsVirtual
const TupleTableSlotOps TTSOpsBufferHeapTuple
const TupleTableSlotOps TTSOpsHeapTuple
const TupleTableSlotOps TTSOpsMinimalTuple
#define FIELDNO_HEAPTUPLEDATA_DATA
#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK
#define FIELDNO_HEAPTUPLEHEADERDATA_HOFF
#define FIELDNO_HEAPTUPLEHEADERDATA_BITS
#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2
Assert(fmt[strlen(fmt) - 1] !='\n')
LLVMTypeRef StructMinimalTupleTableSlot
LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname)
char * llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
LLVMTypeRef StructTupleTableSlot
LLVMTypeRef StructHeapTupleTableSlot
LLVMModuleRef llvm_mutable_module(LLVMJitContext *context)
LLVMValueRef AttributeTemplate
void llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
FormData_pg_attribute * Form_pg_attribute
#define TupleDescAttr(tupdesc, i)
#define FIELDNO_HEAPTUPLETABLESLOT_OFF
#define FIELDNO_HEAPTUPLETABLESLOT_TUPLE
#define FIELDNO_TUPLETABLESLOT_ISNULL
#define FIELDNO_MINIMALTUPLETABLESLOT_TUPLE
#define FIELDNO_MINIMALTUPLETABLESLOT_OFF
#define FIELDNO_TUPLETABLESLOT_VALUES
#define FIELDNO_TUPLETABLESLOT_FLAGS
#define FIELDNO_TUPLETABLESLOT_NVALID