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;
109 for (attnum = 0; attnum < desc->
natts; attnum++)
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;
199 LLVMValueRef v_minimalslot;
222 LLVMBuildStructGEP(b, v_tuplep,
225 l_ptr(LLVMInt8Type()),
228 l_load_struct_gep(b, v_tuplep,
238 LLVMBuildICmp(b, LLVMIntNE,
246 v_maxatt = LLVMBuildAnd(b,
257 l_load_struct_gep(b, v_tuplep,
260 LLVMInt32Type(),
"t_hoff");
266 l_ptr(LLVMInt8Type()),
276 LLVMValueRef v_off_start;
278 v_off_start = LLVMBuildLoad(b, v_slotoffp,
"v_slot_off");
279 v_off_start = LLVMBuildZExt(b, v_off_start,
TypeSizeT,
"");
280 LLVMBuildStore(b, v_off_start, v_offp);
284 for (attnum = 0; attnum < natts; attnum++)
286 attcheckattnoblocks[
attnum] =
287 l_bb_append_v(v_deform_fn,
"block.attr.%d.attcheckattno", attnum);
289 l_bb_append_v(v_deform_fn,
"block.attr.%d.start", attnum);
291 l_bb_append_v(v_deform_fn,
"block.attr.%d.attisnull", attnum);
292 attcheckalignblocks[
attnum] =
293 l_bb_append_v(v_deform_fn,
"block.attr.%d.attcheckalign", attnum);
295 l_bb_append_v(v_deform_fn,
"block.attr.%d.align", attnum);
297 l_bb_append_v(v_deform_fn,
"block.attr.%d.store", attnum);
308 if ((natts - 1) <= guaranteed_column_number)
311 LLVMBuildBr(b, b_adjust_unavail_cols);
312 LLVMPositionBuilderAtEnd(b, b_adjust_unavail_cols);
313 LLVMBuildBr(b, b_find_start);
317 LLVMValueRef v_params[3];
321 LLVMBuildICmp(b, LLVMIntULT,
323 l_int16_const(natts),
325 b_adjust_unavail_cols,
329 LLVMPositionBuilderAtEnd(b, b_adjust_unavail_cols);
331 v_params[0] = v_slot;
332 v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(),
"");
333 v_params[2] = l_int32_const(natts);
334 LLVMBuildCall(b,
llvm_pg_func(mod,
"slot_getmissingattrs"),
336 LLVMBuildBr(b, b_find_start);
339 LLVMPositionBuilderAtEnd(b, b_find_start);
341 v_nvalid = LLVMBuildLoad(b, v_nvalidp,
"");
351 LLVMValueRef v_switch = LLVMBuildSwitch(b, v_nvalid,
354 for (attnum = 0; attnum < natts; attnum++)
356 LLVMValueRef v_attno = l_int16_const(attnum);
358 LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[attnum]);
365 LLVMBuildBr(b, attcheckattnoblocks[0]);
368 LLVMPositionBuilderAtEnd(b, b_dead);
369 LLVMBuildUnreachable(b);
375 for (attnum = 0; attnum < natts; attnum++)
378 LLVMValueRef v_incby;
380 LLVMValueRef l_attno = l_int16_const(attnum);
381 LLVMValueRef v_attdatap;
382 LLVMValueRef v_resultp;
385 LLVMPositionBuilderAtEnd(b, attcheckattnoblocks[attnum]);
393 LLVMBuildStore(b, l_sizet_const(0), v_offp);
401 if (attnum <= guaranteed_column_number)
403 LLVMBuildBr(b, attstartblocks[attnum]);
407 LLVMValueRef v_islast;
409 v_islast = LLVMBuildICmp(b, LLVMIntUGE,
413 LLVMBuildCondBr(b, v_islast, b_out, attstartblocks[attnum]);
415 LLVMPositionBuilderAtEnd(b, attstartblocks[attnum]);
422 if (!att->attnotnull)
424 LLVMBasicBlockRef b_ifnotnull;
425 LLVMBasicBlockRef b_ifnull;
426 LLVMBasicBlockRef b_next;
427 LLVMValueRef v_attisnull;
428 LLVMValueRef v_nullbyteno;
429 LLVMValueRef v_nullbytemask;
430 LLVMValueRef v_nullbyte;
431 LLVMValueRef v_nullbit;
433 b_ifnotnull = attcheckalignblocks[
attnum];
434 b_ifnull = attisnullblocks[
attnum];
436 if (attnum + 1 == natts)
439 b_next = attcheckattnoblocks[attnum + 1];
441 v_nullbyteno = l_int32_const(attnum >> 3);
442 v_nullbytemask = l_int8_const(1 << ((attnum) & 0x07));
443 v_nullbyte = l_load_gep1(b, v_bits, v_nullbyteno,
"attnullbyte");
445 v_nullbit = LLVMBuildICmp(b,
447 LLVMBuildAnd(b, v_nullbyte, v_nullbytemask,
""),
451 v_attisnull = LLVMBuildAnd(b, v_hasnulls, v_nullbit,
"");
453 LLVMBuildCondBr(b, v_attisnull, b_ifnull, b_ifnotnull);
455 LLVMPositionBuilderAtEnd(b, b_ifnull);
460 LLVMBuildGEP(b, v_tts_nulls, &l_attno, 1,
""));
464 LLVMBuildGEP(b, v_tts_values, &l_attno, 1,
""));
466 LLVMBuildBr(b, b_next);
467 attguaranteedalign =
false;
472 LLVMBuildBr(b, attcheckalignblocks[attnum]);
473 LLVMPositionBuilderAtEnd(b, attisnullblocks[attnum]);
474 LLVMBuildBr(b, attcheckalignblocks[attnum]);
476 LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attnum]);
479 if (att->attalign == TYPALIGN_INT)
480 alignto = ALIGNOF_INT;
481 else if (att->attalign == TYPALIGN_CHAR)
483 else if (att->attalign == TYPALIGN_DOUBLE)
484 alignto = ALIGNOF_DOUBLE;
485 else if (att->attalign == TYPALIGN_SHORT)
486 alignto = ALIGNOF_SHORT;
503 (known_alignment < 0 || known_alignment !=
TYPEALIGN(alignto, known_alignment)))
514 if (att->attlen == -1)
516 LLVMValueRef v_possible_padbyte;
517 LLVMValueRef v_ispad;
521 attguaranteedalign =
false;
523 v_off = LLVMBuildLoad(b, v_offp,
"");
526 l_load_gep1(b, v_tupdata_base, v_off,
"padbyte");
528 LLVMBuildICmp(b, LLVMIntEQ,
529 v_possible_padbyte, l_int8_const(0),
531 LLVMBuildCondBr(b, v_ispad,
532 attalignblocks[attnum],
533 attstoreblocks[attnum]);
537 LLVMBuildBr(b, attalignblocks[attnum]);
540 LLVMPositionBuilderAtEnd(b, attalignblocks[attnum]);
544 LLVMValueRef v_off_aligned;
545 LLVMValueRef v_off = LLVMBuildLoad(b, v_offp,
"");
548 LLVMValueRef v_alignval = l_sizet_const(alignto - 1);
551 LLVMValueRef v_lh = LLVMBuildAdd(b, v_off, v_alignval,
"");
554 LLVMValueRef v_rh = l_sizet_const(~(alignto - 1));
556 v_off_aligned = LLVMBuildAnd(b, v_lh, v_rh,
"aligned_offset");
558 LLVMBuildStore(b, v_off_aligned, v_offp);
566 if (known_alignment >= 0)
568 Assert(known_alignment != 0);
569 known_alignment =
TYPEALIGN(alignto, known_alignment);
572 LLVMBuildBr(b, attstoreblocks[attnum]);
573 LLVMPositionBuilderAtEnd(b, attstoreblocks[attnum]);
577 LLVMPositionBuilderAtEnd(b, attcheckalignblocks[attnum]);
578 LLVMBuildBr(b, attalignblocks[attnum]);
579 LLVMPositionBuilderAtEnd(b, attalignblocks[attnum]);
580 LLVMBuildBr(b, attstoreblocks[attnum]);
582 LLVMPositionBuilderAtEnd(b, attstoreblocks[attnum]);
590 if (attguaranteedalign)
592 Assert(known_alignment >= 0);
593 LLVMBuildStore(b, l_sizet_const(known_alignment), v_offp);
600 known_alignment = -1;
601 attguaranteedalign =
false;
603 else if (att->attnotnull && attguaranteedalign && known_alignment >= 0)
611 known_alignment += att->attlen;
613 else if (att->attnotnull && (att->attlen % alignto) == 0)
621 known_alignment = alignto;
622 Assert(known_alignment > 0);
623 attguaranteedalign =
false;
627 known_alignment = -1;
628 attguaranteedalign =
false;
634 LLVMValueRef v_off = LLVMBuildLoad(b, v_offp,
"");
637 LLVMBuildGEP(b, v_tupdata_base, &v_off, 1,
"");
641 v_resultp = LLVMBuildGEP(b, v_tts_values, &l_attno, 1,
"");
644 LLVMBuildStore(b, l_int8_const(0),
645 LLVMBuildGEP(b, v_tts_nulls, &l_attno, 1,
""));
653 LLVMValueRef v_tmp_loaddata;
654 LLVMTypeRef vartypep =
655 LLVMPointerType(LLVMIntType(att->attlen * 8), 0);
658 LLVMBuildPointerCast(b, v_attdatap, vartypep,
"");
659 v_tmp_loaddata = LLVMBuildLoad(b, v_tmp_loaddata,
"attr_byval");
660 v_tmp_loaddata = LLVMBuildZExt(b, v_tmp_loaddata,
TypeSizeT,
"");
662 LLVMBuildStore(b, v_tmp_loaddata, v_resultp);
666 LLVMValueRef v_tmp_loaddata;
674 LLVMBuildStore(b, v_tmp_loaddata, v_resultp);
680 v_incby = l_sizet_const(att->attlen);
682 else if (att->attlen == -1)
684 v_incby = LLVMBuildCall(b,
688 l_callsite_ro(v_incby);
689 l_callsite_alwaysinline(v_incby);
691 else if (att->attlen == -2)
693 v_incby = LLVMBuildCall(b,
695 &v_attdatap, 1,
"strlen");
697 l_callsite_ro(v_incby);
700 v_incby = LLVMBuildAdd(b, v_incby, l_sizet_const(1),
"");
708 if (attguaranteedalign)
710 Assert(known_alignment >= 0);
711 LLVMBuildStore(b, l_sizet_const(known_alignment), v_offp);
715 LLVMValueRef v_off = LLVMBuildLoad(b, v_offp,
"");
717 v_off = LLVMBuildAdd(b, v_off, v_incby,
"increment_offset");
718 LLVMBuildStore(b, v_off, v_offp);
725 if (attnum + 1 == natts)
728 LLVMBuildBr(b, b_out);
732 LLVMBuildBr(b, attcheckattnoblocks[attnum + 1]);
738 LLVMPositionBuilderAtEnd(b, b_out);
741 LLVMValueRef v_off = LLVMBuildLoad(b, v_offp,
"");
742 LLVMValueRef v_flags;
744 LLVMBuildStore(b, l_int16_const(natts), v_nvalidp);
745 v_off = LLVMBuildTrunc(b, v_off, LLVMInt32Type(),
"");
746 LLVMBuildStore(b, v_off, v_slotoffp);
747 v_flags = LLVMBuildLoad(b, v_flagsp,
"tts_flags");
748 v_flags = LLVMBuildOr(b, v_flags, l_int16_const(
TTS_FLAG_SLOW),
"");
749 LLVMBuildStore(b, v_flags, v_flagsp);
753 LLVMDisposeBuilder(b);
#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK
#define FIELDNO_MINIMALTUPLETABLESLOT_TUPLE
#define TupleDescAttr(tupdesc, i)
const TupleTableSlotOps TTSOpsBufferHeapTuple
const TupleTableSlotOps TTSOpsVirtual
#define FIELDNO_TUPLETABLESLOT_ISNULL
#define FIELDNO_HEAPTUPLETABLESLOT_OFF
LLVMTypeRef StructHeapTupleTableSlot
#define FIELDNO_HEAPTUPLETABLESLOT_TUPLE
char * llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
FormData_pg_attribute * Form_pg_attribute
#define FIELDNO_TUPLETABLESLOT_NVALID
#define FIELDNO_TUPLETABLESLOT_FLAGS
LLVMTypeRef StructMinimalTupleTableSlot
LLVMTypeRef StructTupleTableSlot
#define TYPEALIGN(ALIGNVAL, LEN)
LLVMModuleRef llvm_mutable_module(LLVMJitContext *context)
#define FIELDNO_MINIMALTUPLETABLESLOT_OFF
#define FIELDNO_HEAPTUPLEHEADERDATA_HOFF
#define Assert(condition)
#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2
#define FIELDNO_TUPLETABLESLOT_VALUES
const TupleTableSlotOps TTSOpsHeapTuple
LLVMValueRef AttributeTemplate
void llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
const TupleTableSlotOps TTSOpsMinimalTuple
#define FIELDNO_HEAPTUPLEDATA_DATA
#define FIELDNO_HEAPTUPLEHEADERDATA_BITS
LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname)