21#include <llvm-c/Core.h>
43 LLVMTypeRef deform_sig;
44 LLVMValueRef v_deform_fn;
46 LLVMBasicBlockRef b_entry;
47 LLVMBasicBlockRef b_adjust_unavail_cols;
48 LLVMBasicBlockRef b_find_start;
50 LLVMBasicBlockRef b_out;
51 LLVMBasicBlockRef b_dead;
52 LLVMBasicBlockRef *attcheckattnoblocks;
53 LLVMBasicBlockRef *attstartblocks;
54 LLVMBasicBlockRef *attisnullblocks;
55 LLVMBasicBlockRef *attcheckalignblocks;
56 LLVMBasicBlockRef *attalignblocks;
57 LLVMBasicBlockRef *attstoreblocks;
61 LLVMValueRef v_tupdata_base;
62 LLVMValueRef v_tts_values;
63 LLVMValueRef v_tts_nulls;
64 LLVMValueRef v_slotoffp;
65 LLVMValueRef v_flagsp;
66 LLVMValueRef v_nvalidp;
67 LLVMValueRef v_nvalid;
68 LLVMValueRef v_maxatt;
72 LLVMValueRef v_tupleheaderp;
73 LLVMValueRef v_tuplep;
74 LLVMValueRef v_infomask1;
75 LLVMValueRef v_infomask2;
80 LLVMValueRef v_hasnulls;
83 int guaranteed_column_number = -1;
86 int known_alignment = 0;
89 bool attguaranteedalign =
true;
103 lc = LLVMGetModuleContext(mod);
129 guaranteed_column_number =
attnum;
134 LLVMTypeRef param_types[1];
138 deform_sig = LLVMFunctionType(LLVMVoidTypeInContext(lc),
139 param_types,
lengthof(param_types), 0);
141 v_deform_fn = LLVMAddFunction(mod,
funcname, deform_sig);
142 LLVMSetLinkage(v_deform_fn, LLVMInternalLinkage);
143 LLVMSetParamAlignment(LLVMGetParam(v_deform_fn, 0), MAXIMUM_ALIGNOF);
147 LLVMAppendBasicBlockInContext(lc, v_deform_fn,
"entry");
148 b_adjust_unavail_cols =
149 LLVMAppendBasicBlockInContext(lc, v_deform_fn,
"adjust_unavail_cols");
151 LLVMAppendBasicBlockInContext(lc, v_deform_fn,
"find_startblock");
153 LLVMAppendBasicBlockInContext(lc, v_deform_fn,
"outblock");
155 LLVMAppendBasicBlockInContext(lc, v_deform_fn,
"deadblock");
157 b = LLVMCreateBuilderInContext(lc);
159 attcheckattnoblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
160 attstartblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
161 attisnullblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
162 attcheckalignblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
163 attalignblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
164 attstoreblocks =
palloc(
sizeof(LLVMBasicBlockRef) * natts);
168 LLVMPositionBuilderAtEnd(
b, b_entry);
171 v_offp = LLVMBuildAlloca(
b,
TypeSizeT,
"v_offp");
173 v_slot = LLVMGetParam(v_deform_fn, 0);
186 LLVMValueRef v_heapslot;
200 LLVMValueRef v_minimalslot;
207 v_slotoffp = l_struct_gep(
b,
237 l_ptr(LLVMInt8TypeInContext(lc)),
253 LLVMBuildICmp(
b, LLVMIntNE,
257 l_int16_const(lc, 0),
261 v_maxatt = LLVMBuildAnd(
b,
277 LLVMInt32TypeInContext(lc),
"t_hoff");
279 v_tupdata_base = l_gep(
b,
280 LLVMInt8TypeInContext(lc),
283 l_ptr(LLVMInt8TypeInContext(lc)),
293 LLVMValueRef v_off_start;
295 v_off_start = l_load(
b, LLVMInt32TypeInContext(lc), v_slotoffp,
"v_slot_off");
296 v_off_start = LLVMBuildZExt(
b, v_off_start,
TypeSizeT,
"");
297 LLVMBuildStore(
b, v_off_start, v_offp);
303 attcheckattnoblocks[
attnum] =
304 l_bb_append_v(v_deform_fn,
"block.attr.%d.attcheckattno",
attnum);
306 l_bb_append_v(v_deform_fn,
"block.attr.%d.start",
attnum);
308 l_bb_append_v(v_deform_fn,
"block.attr.%d.attisnull",
attnum);
309 attcheckalignblocks[
attnum] =
310 l_bb_append_v(v_deform_fn,
"block.attr.%d.attcheckalign",
attnum);
312 l_bb_append_v(v_deform_fn,
"block.attr.%d.align",
attnum);
314 l_bb_append_v(v_deform_fn,
"block.attr.%d.store",
attnum);
325 if ((natts - 1) <= guaranteed_column_number)
328 LLVMBuildBr(
b, b_adjust_unavail_cols);
329 LLVMPositionBuilderAtEnd(
b, b_adjust_unavail_cols);
330 LLVMBuildBr(
b, b_find_start);
334 LLVMValueRef v_params[3];
339 LLVMBuildICmp(
b, LLVMIntULT,
341 l_int16_const(lc, natts),
343 b_adjust_unavail_cols,
347 LLVMPositionBuilderAtEnd(
b, b_adjust_unavail_cols);
349 v_params[0] = v_slot;
350 v_params[1] = LLVMBuildZExt(
b, v_maxatt, LLVMInt32TypeInContext(lc),
"");
351 v_params[2] = l_int32_const(lc, natts);
356 LLVMBuildBr(
b, b_find_start);
359 LLVMPositionBuilderAtEnd(
b, b_find_start);
361 v_nvalid = l_load(
b, LLVMInt16TypeInContext(lc), v_nvalidp,
"");
371 LLVMValueRef v_switch = LLVMBuildSwitch(
b, v_nvalid,
376 LLVMValueRef v_attno = l_int16_const(lc,
attnum);
378 LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[
attnum]);
384 LLVMBuildBr(
b, attcheckattnoblocks[0]);
387 LLVMPositionBuilderAtEnd(
b, b_dead);
388 LLVMBuildUnreachable(
b);
397 LLVMValueRef v_incby;
399 LLVMValueRef l_attno = l_int16_const(lc,
attnum);
400 LLVMValueRef v_attdatap;
401 LLVMValueRef v_resultp;
404 LLVMPositionBuilderAtEnd(
b, attcheckattnoblocks[
attnum]);
412 LLVMBuildStore(
b, l_sizet_const(0), v_offp);
420 if (
attnum <= guaranteed_column_number)
422 LLVMBuildBr(
b, attstartblocks[
attnum]);
426 LLVMValueRef v_islast;
428 v_islast = LLVMBuildICmp(
b, LLVMIntUGE,
432 LLVMBuildCondBr(
b, v_islast, b_out, attstartblocks[
attnum]);
434 LLVMPositionBuilderAtEnd(
b, attstartblocks[
attnum]);
443 LLVMBasicBlockRef b_ifnotnull;
444 LLVMBasicBlockRef b_ifnull;
445 LLVMBasicBlockRef b_next;
446 LLVMValueRef v_attisnull;
447 LLVMValueRef v_nullbyteno;
448 LLVMValueRef v_nullbytemask;
449 LLVMValueRef v_nullbyte;
450 LLVMValueRef v_nullbit;
452 b_ifnotnull = attcheckalignblocks[
attnum];
453 b_ifnull = attisnullblocks[
attnum];
458 b_next = attcheckattnoblocks[
attnum + 1];
460 v_nullbyteno = l_int32_const(lc,
attnum >> 3);
461 v_nullbytemask = l_int8_const(lc, 1 << ((
attnum) & 0x07));
462 v_nullbyte = l_load_gep1(
b, LLVMInt8TypeInContext(lc), v_bits, v_nullbyteno,
"attnullbyte");
464 v_nullbit = LLVMBuildICmp(
b,
466 LLVMBuildAnd(
b, v_nullbyte, v_nullbytemask,
""),
470 v_attisnull = LLVMBuildAnd(
b, v_hasnulls, v_nullbit,
"");
472 LLVMBuildCondBr(
b, v_attisnull, b_ifnull, b_ifnotnull);
474 LLVMPositionBuilderAtEnd(
b, b_ifnull);
479 l_gep(
b, LLVMInt8TypeInContext(lc), v_tts_nulls, &l_attno, 1,
""));
483 l_gep(
b,
TypeSizeT, v_tts_values, &l_attno, 1,
""));
485 LLVMBuildBr(
b, b_next);
486 attguaranteedalign =
false;
491 LLVMBuildBr(
b, attcheckalignblocks[
attnum]);
492 LLVMPositionBuilderAtEnd(
b, attisnullblocks[
attnum]);
493 LLVMBuildBr(
b, attcheckalignblocks[
attnum]);
495 LLVMPositionBuilderAtEnd(
b, attcheckalignblocks[
attnum]);
507 (known_alignment < 0 || known_alignment !=
TYPEALIGN(alignto, known_alignment)))
520 LLVMValueRef v_possible_padbyte;
521 LLVMValueRef v_ispad;
525 attguaranteedalign =
false;
530 l_load_gep1(
b, LLVMInt8TypeInContext(lc), v_tupdata_base, v_off,
"padbyte");
532 LLVMBuildICmp(
b, LLVMIntEQ,
533 v_possible_padbyte, l_int8_const(lc, 0),
535 LLVMBuildCondBr(
b, v_ispad,
541 LLVMBuildBr(
b, attalignblocks[
attnum]);
544 LLVMPositionBuilderAtEnd(
b, attalignblocks[
attnum]);
548 LLVMValueRef v_off_aligned;
549 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
552 LLVMValueRef v_alignval = l_sizet_const(alignto - 1);
555 LLVMValueRef v_lh = LLVMBuildAdd(
b, v_off, v_alignval,
"");
558 LLVMValueRef v_rh = l_sizet_const(~(alignto - 1));
560 v_off_aligned = LLVMBuildAnd(
b, v_lh, v_rh,
"aligned_offset");
562 LLVMBuildStore(
b, v_off_aligned, v_offp);
570 if (known_alignment >= 0)
572 Assert(known_alignment != 0);
573 known_alignment =
TYPEALIGN(alignto, known_alignment);
576 LLVMBuildBr(
b, attstoreblocks[
attnum]);
577 LLVMPositionBuilderAtEnd(
b, attstoreblocks[
attnum]);
581 LLVMPositionBuilderAtEnd(
b, attcheckalignblocks[
attnum]);
582 LLVMBuildBr(
b, attalignblocks[
attnum]);
583 LLVMPositionBuilderAtEnd(
b, attalignblocks[
attnum]);
584 LLVMBuildBr(
b, attstoreblocks[
attnum]);
586 LLVMPositionBuilderAtEnd(
b, attstoreblocks[
attnum]);
594 if (attguaranteedalign)
596 Assert(known_alignment >= 0);
597 LLVMBuildStore(
b, l_sizet_const(known_alignment), v_offp);
604 known_alignment = -1;
605 attguaranteedalign =
false;
607 else if (att->
attnotnull && attguaranteedalign && known_alignment >= 0)
615 known_alignment += att->
attlen;
625 known_alignment = alignto;
626 Assert(known_alignment > 0);
627 attguaranteedalign =
false;
631 known_alignment = -1;
632 attguaranteedalign =
false;
638 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
641 l_gep(
b, LLVMInt8TypeInContext(lc), v_tupdata_base, &v_off, 1,
"");
645 v_resultp = l_gep(
b,
TypeSizeT, v_tts_values, &l_attno, 1,
"");
648 LLVMBuildStore(
b, l_int8_const(lc, 0),
657 LLVMValueRef v_tmp_loaddata;
658 LLVMTypeRef vartype = LLVMIntTypeInContext(lc, att->
attlen * 8);
659 LLVMTypeRef vartypep = LLVMPointerType(vartype, 0);
662 LLVMBuildPointerCast(
b, v_attdatap, vartypep,
"");
663 v_tmp_loaddata = l_load(
b, vartype, v_tmp_loaddata,
"attr_byval");
664 v_tmp_loaddata = LLVMBuildZExt(
b, v_tmp_loaddata,
TypeSizeT,
"");
666 LLVMBuildStore(
b, v_tmp_loaddata, v_resultp);
670 LLVMValueRef v_tmp_loaddata;
678 LLVMBuildStore(
b, v_tmp_loaddata, v_resultp);
684 v_incby = l_sizet_const(att->
attlen);
686 else if (att->
attlen == -1)
693 l_callsite_ro(v_incby);
694 l_callsite_alwaysinline(v_incby);
696 else if (att->
attlen == -2)
701 &v_attdatap, 1,
"strlen");
703 l_callsite_ro(v_incby);
706 v_incby = LLVMBuildAdd(
b, v_incby, l_sizet_const(1),
"");
714 if (attguaranteedalign)
716 Assert(known_alignment >= 0);
717 LLVMBuildStore(
b, l_sizet_const(known_alignment), v_offp);
721 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
723 v_off = LLVMBuildAdd(
b, v_off, v_incby,
"increment_offset");
724 LLVMBuildStore(
b, v_off, v_offp);
734 LLVMBuildBr(
b, b_out);
738 LLVMBuildBr(
b, attcheckattnoblocks[
attnum + 1]);
744 LLVMPositionBuilderAtEnd(
b, b_out);
747 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
748 LLVMValueRef v_flags;
750 LLVMBuildStore(
b, l_int16_const(lc, natts), v_nvalidp);
751 v_off = LLVMBuildTrunc(
b, v_off, LLVMInt32TypeInContext(lc),
"");
752 LLVMBuildStore(
b, v_off, v_slotoffp);
753 v_flags = l_load(
b, LLVMInt16TypeInContext(lc), v_flagsp,
"tts_flags");
754 v_flags = LLVMBuildOr(
b, v_flags, l_int16_const(lc,
TTS_FLAG_SLOW),
"");
755 LLVMBuildStore(
b, v_flags, v_flagsp);
759 LLVMDisposeBuilder(
b);
#define TYPEALIGN(ALIGNVAL, LEN)
#define Assert(condition)
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
LLVMTypeRef StructMinimalTupleTableSlot
LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname)
char * llvm_expand_funcname(struct LLVMJitContext *context, const char *basename)
LLVMTypeRef llvm_pg_var_func_type(const char *varname)
LLVMTypeRef StructTupleTableSlot
LLVMTypeRef TypeStorageBool
LLVMTypeRef StructHeapTupleTableSlot
LLVMModuleRef llvm_mutable_module(LLVMJitContext *context)
LLVMValueRef AttributeTemplate
LLVMTypeRef StructHeapTupleHeaderData
LLVMTypeRef StructHeapTupleData
void llvm_copy_attributes(LLVMValueRef v_from, LLVMValueRef v_to)
LLVMTypeRef LLVMGetFunctionType(LLVMValueRef r)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int 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