36{
38
39 LLVMModuleRef mod;
40 LLVMContextRef lc;
42
43 LLVMTypeRef deform_sig;
44 LLVMValueRef v_deform_fn;
45
46 LLVMBasicBlockRef b_entry;
47 LLVMBasicBlockRef b_adjust_unavail_cols;
48 LLVMBasicBlockRef b_find_start;
49
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;
58
59 LLVMValueRef v_offp;
60
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;
69
70 LLVMValueRef v_slot;
71
72 LLVMValueRef v_tupleheaderp;
73 LLVMValueRef v_tuplep;
74 LLVMValueRef v_infomask1;
75 LLVMValueRef v_infomask2;
76 LLVMValueRef v_bits;
77
78 LLVMValueRef v_hoff;
79
80 LLVMValueRef v_hasnulls;
81
82
83 int guaranteed_column_number = -1;
84
85
86 int known_alignment = 0;
87
88
89 bool attguaranteedalign = true;
90
92
93
95 return NULL;
96
97
100 return NULL;
101
103 lc = LLVMGetModuleContext(mod);
104
106
107
108
109
110
112 {
114
115
116
117
118
119
120
121
122
123
124
125
129 guaranteed_column_number =
attnum;
130 }
131
132
133 {
134 LLVMTypeRef param_types[1];
135
137
138 deform_sig = LLVMFunctionType(LLVMVoidTypeInContext(lc),
139 param_types,
lengthof(param_types), 0);
140 }
141 v_deform_fn = LLVMAddFunction(mod,
funcname, deform_sig);
142 LLVMSetLinkage(v_deform_fn, LLVMInternalLinkage);
143 LLVMSetParamAlignment(LLVMGetParam(v_deform_fn, 0), MAXIMUM_ALIGNOF);
145
146 b_entry =
147 LLVMAppendBasicBlockInContext(lc, v_deform_fn, "entry");
148 b_adjust_unavail_cols =
149 LLVMAppendBasicBlockInContext(lc, v_deform_fn, "adjust_unavail_cols");
150 b_find_start =
151 LLVMAppendBasicBlockInContext(lc, v_deform_fn, "find_startblock");
152 b_out =
153 LLVMAppendBasicBlockInContext(lc, v_deform_fn, "outblock");
154 b_dead =
155 LLVMAppendBasicBlockInContext(lc, v_deform_fn, "deadblock");
156
157 b = LLVMCreateBuilderInContext(lc);
158
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);
165
166 known_alignment = 0;
167
168 LLVMPositionBuilderAtEnd(
b, b_entry);
169
170
171 v_offp = LLVMBuildAlloca(
b,
TypeSizeT,
"v_offp");
172
173 v_slot = LLVMGetParam(v_deform_fn, 0);
174
175 v_tts_values =
177 "tts_values");
178 v_tts_nulls =
180 "tts_ISNULL");
183
185 {
186 LLVMValueRef v_heapslot;
187
188 v_heapslot =
190 v_slot,
192 "heapslot");
194 v_tupleheaderp =
196 "tupleheader");
197 }
199 {
200 LLVMValueRef v_minimalslot;
201
202 v_minimalslot =
204 v_slot,
206 "minimalslot");
207 v_slotoffp = l_struct_gep(
b,
209 v_minimalslot,
211 v_tupleheaderp =
214 v_minimalslot,
216 "tupleheader");
217 }
218 else
219 {
220
222 }
223
224 v_tuplep =
227 v_tupleheaderp,
229 "tuple");
230 v_bits =
234 v_tuplep,
236 ""),
237 l_ptr(LLVMInt8TypeInContext(lc)),
238 "t_bits");
239 v_infomask1 =
242 v_tuplep,
244 "infomask1");
245 v_infomask2 =
249 "infomask2");
250
251
252 v_hasnulls =
253 LLVMBuildICmp(
b, LLVMIntNE,
256 v_infomask1, ""),
257 l_int16_const(lc, 0),
258 "hasnulls");
259
260
261 v_maxatt = LLVMBuildAnd(
b,
263 v_infomask2,
264 "maxatt");
265
266
267
268
269
270 v_hoff =
274 v_tuplep,
276 ""),
277 LLVMInt32TypeInContext(lc), "t_hoff");
278
279 v_tupdata_base = l_gep(
b,
280 LLVMInt8TypeInContext(lc),
282 v_tuplep,
283 l_ptr(LLVMInt8TypeInContext(lc)),
284 ""),
285 &v_hoff, 1,
286 "v_tupdata_base");
287
288
289
290
291
292 {
293 LLVMValueRef v_off_start;
294
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);
298 }
299
300
302 {
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);
315 }
316
317
318
319
320
321
322
323
324
325 if ((natts - 1) <= guaranteed_column_number)
326 {
327
328 LLVMBuildBr(
b, b_adjust_unavail_cols);
329 LLVMPositionBuilderAtEnd(
b, b_adjust_unavail_cols);
330 LLVMBuildBr(
b, b_find_start);
331 }
332 else
333 {
334 LLVMValueRef v_params[3];
335 LLVMValueRef f;
336
337
339 LLVMBuildICmp(
b, LLVMIntULT,
340 v_maxatt,
341 l_int16_const(lc, natts),
342 ""),
343 b_adjust_unavail_cols,
344 b_find_start);
345
346
347 LLVMPositionBuilderAtEnd(
b, b_adjust_unavail_cols);
348
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);
357 }
358
359 LLVMPositionBuilderAtEnd(
b, b_find_start);
360
361 v_nvalid = l_load(
b, LLVMInt16TypeInContext(lc), v_nvalidp,
"");
362
363
364
365
366
367
368
369 if (true)
370 {
371 LLVMValueRef v_switch = LLVMBuildSwitch(
b, v_nvalid,
372 b_dead, natts);
373
375 {
376 LLVMValueRef v_attno = l_int16_const(lc,
attnum);
377
378 LLVMAddCase(v_switch, v_attno, attcheckattnoblocks[
attnum]);
379 }
380 }
381 else
382 {
383
384 LLVMBuildBr(
b, attcheckattnoblocks[0]);
385 }
386
387 LLVMPositionBuilderAtEnd(
b, b_dead);
388 LLVMBuildUnreachable(
b);
389
390
391
392
393
395 {
397 LLVMValueRef v_incby;
399 LLVMValueRef l_attno = l_int16_const(lc,
attnum);
400 LLVMValueRef v_attdatap;
401 LLVMValueRef v_resultp;
402
403
404 LLVMPositionBuilderAtEnd(
b, attcheckattnoblocks[
attnum]);
405
406
407
408
409
411 {
412 LLVMBuildStore(
b, l_sizet_const(0), v_offp);
413 }
414
415
416
417
418
419
420 if (
attnum <= guaranteed_column_number)
421 {
422 LLVMBuildBr(
b, attstartblocks[
attnum]);
423 }
424 else
425 {
426 LLVMValueRef v_islast;
427
428 v_islast = LLVMBuildICmp(
b, LLVMIntUGE,
429 l_attno,
430 v_maxatt,
431 "heap_natts");
432 LLVMBuildCondBr(
b, v_islast, b_out, attstartblocks[
attnum]);
433 }
434 LLVMPositionBuilderAtEnd(
b, attstartblocks[
attnum]);
435
436
437
438
439
440
442 {
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;
451
452 b_ifnotnull = attcheckalignblocks[
attnum];
453 b_ifnull = attisnullblocks[
attnum];
454
456 b_next = b_out;
457 else
458 b_next = attcheckattnoblocks[
attnum + 1];
459
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");
463
464 v_nullbit = LLVMBuildICmp(
b,
465 LLVMIntEQ,
466 LLVMBuildAnd(
b, v_nullbyte, v_nullbytemask,
""),
467 l_int8_const(lc, 0),
468 "attisnull");
469
470 v_attisnull = LLVMBuildAnd(
b, v_hasnulls, v_nullbit,
"");
471
472 LLVMBuildCondBr(
b, v_attisnull, b_ifnull, b_ifnotnull);
473
474 LLVMPositionBuilderAtEnd(
b, b_ifnull);
475
476
478 l_int8_const(lc, 1),
479 l_gep(
b, LLVMInt8TypeInContext(lc), v_tts_nulls, &l_attno, 1,
""));
480
482 l_sizet_const(0),
483 l_gep(
b,
TypeSizeT, v_tts_values, &l_attno, 1,
""));
484
485 LLVMBuildBr(
b, b_next);
486 attguaranteedalign = false;
487 }
488 else
489 {
490
491 LLVMBuildBr(
b, attcheckalignblocks[
attnum]);
492 LLVMPositionBuilderAtEnd(
b, attisnullblocks[
attnum]);
493 LLVMBuildBr(
b, attcheckalignblocks[
attnum]);
494 }
495 LLVMPositionBuilderAtEnd(
b, attcheckalignblocks[
attnum]);
496
497
498
499
500
501
502
503
504
505
506 if (alignto > 1 &&
507 (known_alignment < 0 || known_alignment !=
TYPEALIGN(alignto, known_alignment)))
508 {
509
510
511
512
513
514
515
516
517
519 {
520 LLVMValueRef v_possible_padbyte;
521 LLVMValueRef v_ispad;
522 LLVMValueRef v_off;
523
524
525 attguaranteedalign = false;
526
528
529 v_possible_padbyte =
530 l_load_gep1(
b, LLVMInt8TypeInContext(lc), v_tupdata_base, v_off,
"padbyte");
531 v_ispad =
532 LLVMBuildICmp(
b, LLVMIntEQ,
533 v_possible_padbyte, l_int8_const(lc, 0),
534 "ispadbyte");
535 LLVMBuildCondBr(
b, v_ispad,
538 }
539 else
540 {
541 LLVMBuildBr(
b, attalignblocks[
attnum]);
542 }
543
544 LLVMPositionBuilderAtEnd(
b, attalignblocks[
attnum]);
545
546
547 {
548 LLVMValueRef v_off_aligned;
549 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
550
551
552 LLVMValueRef v_alignval = l_sizet_const(alignto - 1);
553
554
555 LLVMValueRef v_lh = LLVMBuildAdd(
b, v_off, v_alignval,
"");
556
557
558 LLVMValueRef v_rh = l_sizet_const(~(alignto - 1));
559
560 v_off_aligned = LLVMBuildAnd(
b, v_lh, v_rh,
"aligned_offset");
561
562 LLVMBuildStore(
b, v_off_aligned, v_offp);
563 }
564
565
566
567
568
569
570 if (known_alignment >= 0)
571 {
572 Assert(known_alignment != 0);
573 known_alignment =
TYPEALIGN(alignto, known_alignment);
574 }
575
576 LLVMBuildBr(
b, attstoreblocks[
attnum]);
577 LLVMPositionBuilderAtEnd(
b, attstoreblocks[
attnum]);
578 }
579 else
580 {
581 LLVMPositionBuilderAtEnd(
b, attcheckalignblocks[
attnum]);
582 LLVMBuildBr(
b, attalignblocks[
attnum]);
583 LLVMPositionBuilderAtEnd(
b, attalignblocks[
attnum]);
584 LLVMBuildBr(
b, attstoreblocks[
attnum]);
585 }
586 LLVMPositionBuilderAtEnd(
b, attstoreblocks[
attnum]);
587
588
589
590
591
592
593
594 if (attguaranteedalign)
595 {
596 Assert(known_alignment >= 0);
597 LLVMBuildStore(
b, l_sizet_const(known_alignment), v_offp);
598 }
599
600
602 {
603
604 known_alignment = -1;
605 attguaranteedalign = false;
606 }
607 else if (att->
attnotnull && attguaranteedalign && known_alignment >= 0)
608 {
609
610
611
612
613
615 known_alignment += att->
attlen;
616 }
618 {
619
620
621
622
623
625 known_alignment = alignto;
626 Assert(known_alignment > 0);
627 attguaranteedalign = false;
628 }
629 else
630 {
631 known_alignment = -1;
632 attguaranteedalign = false;
633 }
634
635
636
637 {
638 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
639
640 v_attdatap =
641 l_gep(
b, LLVMInt8TypeInContext(lc), v_tupdata_base, &v_off, 1,
"");
642 }
643
644
645 v_resultp = l_gep(
b,
TypeSizeT, v_tts_values, &l_attno, 1,
"");
646
647
648 LLVMBuildStore(
b, l_int8_const(lc, 0),
650
651
652
653
654
656 {
657 LLVMValueRef v_tmp_loaddata;
658 LLVMTypeRef vartype = LLVMIntTypeInContext(lc, att->
attlen * 8);
659 LLVMTypeRef vartypep = LLVMPointerType(vartype, 0);
660
661 v_tmp_loaddata =
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,
"");
665
666 LLVMBuildStore(
b, v_tmp_loaddata, v_resultp);
667 }
668 else
669 {
670 LLVMValueRef v_tmp_loaddata;
671
672
673 v_tmp_loaddata =
675 v_attdatap,
677 "attr_ptr");
678 LLVMBuildStore(
b, v_tmp_loaddata, v_resultp);
679 }
680
681
683 {
684 v_incby = l_sizet_const(att->
attlen);
685 }
686 else if (att->
attlen == -1)
687 {
691 &v_attdatap, 1,
692 "varsize_any");
693 l_callsite_ro(v_incby);
694 l_callsite_alwaysinline(v_incby);
695 }
696 else if (att->
attlen == -2)
697 {
701 &v_attdatap, 1, "strlen");
702
703 l_callsite_ro(v_incby);
704
705
706 v_incby = LLVMBuildAdd(
b, v_incby, l_sizet_const(1),
"");
707 }
708 else
709 {
711 v_incby = NULL;
712 }
713
714 if (attguaranteedalign)
715 {
716 Assert(known_alignment >= 0);
717 LLVMBuildStore(
b, l_sizet_const(known_alignment), v_offp);
718 }
719 else
720 {
721 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
722
723 v_off = LLVMBuildAdd(
b, v_off, v_incby,
"increment_offset");
724 LLVMBuildStore(
b, v_off, v_offp);
725 }
726
727
728
729
730
732 {
733
734 LLVMBuildBr(
b, b_out);
735 }
736 else
737 {
738 LLVMBuildBr(
b, attcheckattnoblocks[
attnum + 1]);
739 }
740 }
741
742
743
744 LLVMPositionBuilderAtEnd(
b, b_out);
745
746 {
747 LLVMValueRef v_off = l_load(
b,
TypeSizeT, v_offp,
"");
748 LLVMValueRef v_flags;
749
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);
757 }
758
759 LLVMDisposeBuilder(
b);
760
761 return v_deform_fn;
762}
#define TYPEALIGN(ALIGNVAL, LEN)
const TupleTableSlotOps TTSOpsVirtual
const TupleTableSlotOps TTSOpsBufferHeapTuple
const TupleTableSlotOps TTSOpsHeapTuple
const TupleTableSlotOps TTSOpsMinimalTuple
Assert(PointerIsAligned(start, uint64))
#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