← Back to Overview

src/backend/jit/llvm/llvmjit_expr.c

Coverage: 18/18 lines (100.0%)
Total Lines
18
modified
Covered
18
100.0%
Uncovered
0
0.0%
Keyboard navigation
llvm_compile_expr() lines 80-3051
Modified Lines Coverage: 18/18 lines (100.0%)
LineHitsSourceCommit
80 - llvm_compile_expr(ExprState *state) -
81 - { -
82 - PlanState *parent = state->parent; -
83 - char *funcname; -
84 - -
85 - LLVMJitContext *context = NULL; -
86 - -
87 - LLVMBuilderRef b; -
88 - LLVMModuleRef mod; -
89 - LLVMContextRef lc; -
90 - LLVMValueRef eval_fn; -
91 - LLVMBasicBlockRef entry; -
92 - LLVMBasicBlockRef *opblocks; -
93 - -
94 - /* state itself */ -
95 - LLVMValueRef v_state; -
96 - LLVMValueRef v_econtext; -
97 - LLVMValueRef v_parent; -
98 - -
99 - /* returnvalue */ -
100 - LLVMValueRef v_isnullp; -
101 - -
102 - /* tmp vars in state */ -
103 - LLVMValueRef v_tmpvaluep; -
104 - LLVMValueRef v_tmpisnullp; -
105 - -
106 - /* slots */ -
107 - LLVMValueRef v_innerslot; -
108 - LLVMValueRef v_outerslot; -
109 - LLVMValueRef v_scanslot; -
110 - LLVMValueRef v_oldslot; -
111 - LLVMValueRef v_newslot; -
112 - LLVMValueRef v_resultslot; -
113 - -
114 - /* nulls/values of slots */ -
115 - LLVMValueRef v_innervalues; -
116 - LLVMValueRef v_innernulls; -
117 - LLVMValueRef v_outervalues; -
118 - LLVMValueRef v_outernulls; -
119 - LLVMValueRef v_scanvalues; -
120 - LLVMValueRef v_scannulls; -
121 - LLVMValueRef v_oldvalues; -
122 - LLVMValueRef v_oldnulls; -
123 - LLVMValueRef v_newvalues; -
124 - LLVMValueRef v_newnulls; -
125 - LLVMValueRef v_resultvalues; -
126 - LLVMValueRef v_resultnulls; -
127 - -
128 - /* stuff in econtext */ -
129 - LLVMValueRef v_aggvalues; -
130 - LLVMValueRef v_aggnulls; -
131 - -
132 - /* RPR navigation: when true, EEOP_OUTER_VAR reloads from econtext */ 24cfb8dRow pattern recognition patch (executor and commands).
133 68 bool has_rpr_nav; 24cfb8dRow pattern recognition patch (executor and commands).
134 - 24cfb8dRow pattern recognition patch (executor and commands).
135 - instr_time starttime; -
136 - instr_time deform_starttime; -
137 - instr_time endtime; -
138 - instr_time deform_endtime; -
139 - -
140 - llvm_enter_fatal_on_oom(); -
141 - -
142 - /* -
143 - * Right now we don't support compiling expressions without a parent, as -
144 - * we need access to the EState. -
145 - */ -
146 - Assert(parent); -
147 - -
148 - /* get or create JIT context */ -
149 - if (parent->state->es_jit) -
150 - context = (LLVMJitContext *) parent->state->es_jit; -
151 - else -
152 - { -
153 - context = llvm_create_context(parent->state->es_jit_flags); -
154 - parent->state->es_jit = &context->base; -
155 - } -
156 - -
157 - INSTR_TIME_SET_CURRENT(starttime); -
158 - -
159 - mod = llvm_mutable_module(context); -
160 - lc = LLVMGetModuleContext(mod); -
161 - -
162 - b = LLVMCreateBuilderInContext(lc); -
163 - -
164 - funcname = llvm_expand_funcname(context, "evalexpr"); -
165 - -
166 - /* create function */ -
167 - eval_fn = LLVMAddFunction(mod, funcname, -
168 - llvm_pg_var_func_type("ExecInterpExprStillValid")); -
169 - LLVMSetLinkage(eval_fn, LLVMExternalLinkage); -
170 - LLVMSetVisibility(eval_fn, LLVMDefaultVisibility); -
171 - llvm_copy_attributes(AttributeTemplate, eval_fn); -
172 - -
173 - entry = LLVMAppendBasicBlockInContext(lc, eval_fn, "entry"); -
174 - -
175 - /* build state */ -
176 - v_state = LLVMGetParam(eval_fn, 0); -
177 - v_econtext = LLVMGetParam(eval_fn, 1); -
178 - v_isnullp = LLVMGetParam(eval_fn, 2); -
179 - -
180 - LLVMPositionBuilderAtEnd(b, entry); -
181 - -
182 - v_tmpvaluep = l_struct_gep(b, -
183 - StructExprState, -
184 - v_state, -
185 - FIELDNO_EXPRSTATE_RESVALUE, -
186 - "v.state.resvalue"); -
187 - v_tmpisnullp = l_struct_gep(b, -
188 - StructExprState, -
189 - v_state, -
190 - FIELDNO_EXPRSTATE_RESNULL, -
191 - "v.state.resnull"); -
192 - v_parent = l_load_struct_gep(b, -
193 - StructExprState, -
194 - v_state, -
195 - FIELDNO_EXPRSTATE_PARENT, -
196 - "v.state.parent"); -
197 - -
198 - /* build global slots */ -
199 - v_scanslot = l_load_struct_gep(b, -
200 - StructExprContext, -
201 - v_econtext, -
202 - FIELDNO_EXPRCONTEXT_SCANTUPLE, -
203 - "v_scanslot"); -
204 - v_innerslot = l_load_struct_gep(b, -
205 - StructExprContext, -
206 - v_econtext, -
207 - FIELDNO_EXPRCONTEXT_INNERTUPLE, -
208 - "v_innerslot"); -
209 - v_outerslot = l_load_struct_gep(b, -
210 - StructExprContext, -
211 - v_econtext, -
212 - FIELDNO_EXPRCONTEXT_OUTERTUPLE, -
213 - "v_outerslot"); -
214 - v_oldslot = l_load_struct_gep(b, -
215 - StructExprContext, -
216 - v_econtext, -
217 - FIELDNO_EXPRCONTEXT_OLDTUPLE, -
218 - "v_oldslot"); -
219 - v_newslot = l_load_struct_gep(b, -
220 - StructExprContext, -
221 - v_econtext, -
222 - FIELDNO_EXPRCONTEXT_NEWTUPLE, -
223 - "v_newslot"); -
224 - v_resultslot = l_load_struct_gep(b, -
225 - StructExprState, -
226 - v_state, -
227 - FIELDNO_EXPRSTATE_RESULTSLOT, -
228 - "v_resultslot"); -
229 - -
230 - /* build global values/isnull pointers */ -
231 - v_scanvalues = l_load_struct_gep(b, -
232 - StructTupleTableSlot, -
233 - v_scanslot, -
234 - FIELDNO_TUPLETABLESLOT_VALUES, -
235 - "v_scanvalues"); -
236 - v_scannulls = l_load_struct_gep(b, -
237 - StructTupleTableSlot, -
238 - v_scanslot, -
239 - FIELDNO_TUPLETABLESLOT_ISNULL, -
240 - "v_scannulls"); -
241 - v_innervalues = l_load_struct_gep(b, -
242 - StructTupleTableSlot, -
243 - v_innerslot, -
244 - FIELDNO_TUPLETABLESLOT_VALUES, -
245 - "v_innervalues"); -
246 - v_innernulls = l_load_struct_gep(b, -
247 - StructTupleTableSlot, -
248 - v_innerslot, -
249 - FIELDNO_TUPLETABLESLOT_ISNULL, -
250 - "v_innernulls"); -
251 - v_outervalues = l_load_struct_gep(b, -
252 - StructTupleTableSlot, -
253 - v_outerslot, -
254 - FIELDNO_TUPLETABLESLOT_VALUES, -
255 - "v_outervalues"); -
256 - v_outernulls = l_load_struct_gep(b, -
257 - StructTupleTableSlot, -
258 - v_outerslot, -
259 - FIELDNO_TUPLETABLESLOT_ISNULL, -
260 - "v_outernulls"); -
261 - v_oldvalues = l_load_struct_gep(b, -
262 - StructTupleTableSlot, -
263 - v_oldslot, -
264 - FIELDNO_TUPLETABLESLOT_VALUES, -
265 - "v_oldvalues"); -
266 - v_oldnulls = l_load_struct_gep(b, -
267 - StructTupleTableSlot, -
268 - v_oldslot, -
269 - FIELDNO_TUPLETABLESLOT_ISNULL, -
270 - "v_oldnulls"); -
271 - v_newvalues = l_load_struct_gep(b, -
272 - StructTupleTableSlot, -
273 - v_newslot, -
274 - FIELDNO_TUPLETABLESLOT_VALUES, -
275 - "v_newvalues"); -
276 - v_newnulls = l_load_struct_gep(b, -
277 - StructTupleTableSlot, -
278 - v_newslot, -
279 - FIELDNO_TUPLETABLESLOT_ISNULL, -
280 - "v_newnulls"); -
281 - v_resultvalues = l_load_struct_gep(b, -
282 - StructTupleTableSlot, -
283 - v_resultslot, -
284 - FIELDNO_TUPLETABLESLOT_VALUES, -
285 - "v_resultvalues"); -
286 - v_resultnulls = l_load_struct_gep(b, -
287 - StructTupleTableSlot, -
288 - v_resultslot, -
289 - FIELDNO_TUPLETABLESLOT_ISNULL, -
290 - "v_resultnulls"); -
291 - -
292 - /* aggvalues/aggnulls */ -
293 - v_aggvalues = l_load_struct_gep(b, -
294 - StructExprContext, -
295 - v_econtext, -
296 - FIELDNO_EXPRCONTEXT_AGGVALUES, -
297 - "v.econtext.aggvalues"); -
298 - v_aggnulls = l_load_struct_gep(b, -
299 - StructExprContext, -
300 - v_econtext, -
301 - FIELDNO_EXPRCONTEXT_AGGNULLS, -
302 - "v.econtext.aggnulls"); -
303 - -
304 - /* 24cfb8dRow pattern recognition patch (executor and commands).
305 - * RPR navigation opcodes (PREV/NEXT) swap ecxt_outertuple to a different 24cfb8dRow pattern recognition patch (executor and commands).
306 - * row mid-expression. The JIT code loads v_outervalues and v_outernulls 24cfb8dRow pattern recognition patch (executor and commands).
307 - * once in the entry block and reuses them for all EEOP_OUTER_VAR steps. 24cfb8dRow pattern recognition patch (executor and commands).
308 - * After a slot swap, these cached pointers become stale because the new 24cfb8dRow pattern recognition patch (executor and commands).
309 - * slot has its own tts_values/tts_isnull arrays. 24cfb8dRow pattern recognition patch (executor and commands).
310 - * 24cfb8dRow pattern recognition patch (executor and commands).
311 - * When RPR navigation opcodes are present, EEOP_OUTER_VAR reloads the 24cfb8dRow pattern recognition patch (executor and commands).
312 - * slot pointer from econtext->ecxt_outertuple on every access instead of 24cfb8dRow pattern recognition patch (executor and commands).
313 - * using the cached entry-block values. This avoids the SSA/PHI 24cfb8dRow pattern recognition patch (executor and commands).
314 - * complexity while keeping the rest of the expression JIT-compiled. 24cfb8dRow pattern recognition patch (executor and commands).
315 - * Expressions without RPR navigation use the cached values as before. 24cfb8dRow pattern recognition patch (executor and commands).
316 - */ 24cfb8dRow pattern recognition patch (executor and commands).
317 68 has_rpr_nav = false; 24cfb8dRow pattern recognition patch (executor and commands).
318 68 if (parent && IsA(parent, WindowAggState) && 24cfb8dRow pattern recognition patch (executor and commands).
319 28 ((WindowAgg *) parent->plan)->rpPattern != NULL) 24cfb8dRow pattern recognition patch (executor and commands).
320 - { 24cfb8dRow pattern recognition patch (executor and commands).
321 164 for (int opno = 0; opno < state->steps_len; opno++) 24cfb8dRow pattern recognition patch (executor and commands).
322 - { 24cfb8dRow pattern recognition patch (executor and commands).
323 148 ExprEvalOp opcode = ExecEvalStepOp(state, &state->steps[opno]); 24cfb8dRow pattern recognition patch (executor and commands).
324 - 24cfb8dRow pattern recognition patch (executor and commands).
325 148 if (opcode == EEOP_RPR_NAV_SET || 24cfb8dRow pattern recognition patch (executor and commands).
326 - opcode == EEOP_RPR_NAV_RESTORE) 24cfb8dRow pattern recognition patch (executor and commands).
327 - { 24cfb8dRow pattern recognition patch (executor and commands).
328 - has_rpr_nav = true; 24cfb8dRow pattern recognition patch (executor and commands).
329 - break; 24cfb8dRow pattern recognition patch (executor and commands).
330 - } 24cfb8dRow pattern recognition patch (executor and commands).
331 - } 24cfb8dRow pattern recognition patch (executor and commands).
332 - } 24cfb8dRow pattern recognition patch (executor and commands).
333 - 24cfb8dRow pattern recognition patch (executor and commands).
334 - /* allocate blocks for each op upfront, so we can do jumps easily */ -
335 - opblocks = palloc_array(LLVMBasicBlockRef, state->steps_len); -
336 - for (int opno = 0; opno < state->steps_len; opno++) -
337 - opblocks[opno] = l_bb_append_v(eval_fn, "b.op.%d.start", opno); -
338 - -
339 - /* jump from entry to first block */ -
340 - LLVMBuildBr(b, opblocks[0]); -
341 - -
342 - for (int opno = 0; opno < state->steps_len; opno++) -
343 - { -
344 - ExprEvalStep *op; -
345 - ExprEvalOp opcode; -
346 - LLVMValueRef v_resvaluep; -
347 - LLVMValueRef v_resnullp; -
348 - -
349 - LLVMPositionBuilderAtEnd(b, opblocks[opno]); -
350 - -
351 - op = &state->steps[opno]; -
352 - opcode = ExecEvalStepOp(state, op); -
353 - -
354 - v_resvaluep = l_ptr_const(op->resvalue, l_ptr(TypeDatum)); -
355 - v_resnullp = l_ptr_const(op->resnull, l_ptr(TypeStorageBool)); -
356 - -
357 - switch (opcode) -
358 - { -
359 - case EEOP_DONE_RETURN: -
360 - { -
361 - LLVMValueRef v_tmpisnull; -
362 - LLVMValueRef v_tmpvalue; -
363 - -
364 - v_tmpvalue = l_load(b, TypeDatum, v_tmpvaluep, ""); -
365 - v_tmpisnull = l_load(b, TypeStorageBool, v_tmpisnullp, ""); -
366 - -
367 - LLVMBuildStore(b, v_tmpisnull, v_isnullp); -
368 - -
369 - LLVMBuildRet(b, v_tmpvalue); -
370 - break; -
371 - } -
372 - -
373 - case EEOP_DONE_NO_RETURN: -
374 - LLVMBuildRet(b, l_datum_const(0)); -
375 - break; -
376 - -
377 - case EEOP_INNER_FETCHSOME: -
378 - case EEOP_OUTER_FETCHSOME: -
379 - case EEOP_SCAN_FETCHSOME: -
380 - case EEOP_OLD_FETCHSOME: -
381 - case EEOP_NEW_FETCHSOME: -
382 - { -
383 - TupleDesc desc = NULL; -
384 - LLVMValueRef v_slot; -
385 - LLVMBasicBlockRef b_fetch; -
386 - LLVMValueRef v_nvalid; -
387 - LLVMValueRef l_jit_deform = NULL; -
388 - const TupleTableSlotOps *tts_ops = NULL; -
389 - -
390 - b_fetch = l_bb_before_v(opblocks[opno + 1], -
391 - "op.%d.fetch", opno); -
392 - -
393 - if (op->d.fetch.known_desc) -
394 - desc = op->d.fetch.known_desc; -
395 - -
396 - if (op->d.fetch.fixed) -
397 - tts_ops = op->d.fetch.kind; -
398 - -
399 - /* step should not have been generated */ -
400 - Assert(tts_ops != &TTSOpsVirtual); -
401 - -
402 - if (opcode == EEOP_INNER_FETCHSOME) -
403 - v_slot = v_innerslot; -
404 - else if (opcode == EEOP_OUTER_FETCHSOME) -
405 - v_slot = v_outerslot; -
406 - else if (opcode == EEOP_SCAN_FETCHSOME) -
407 - v_slot = v_scanslot; -
408 - else if (opcode == EEOP_OLD_FETCHSOME) -
409 - v_slot = v_oldslot; -
410 - else -
411 - v_slot = v_newslot; -
412 - -
413 - /* -
414 - * Check if all required attributes are available, or -
415 - * whether deforming is required. -
416 - */ -
417 - v_nvalid = -
418 - l_load_struct_gep(b, -
419 - StructTupleTableSlot, -
420 - v_slot, -
421 - FIELDNO_TUPLETABLESLOT_NVALID, -
422 - ""); -
423 - LLVMBuildCondBr(b, -
424 - LLVMBuildICmp(b, LLVMIntUGE, v_nvalid, -
425 - l_int16_const(lc, op->d.fetch.last_var), -
426 - ""), -
427 - opblocks[opno + 1], b_fetch); -
428 - -
429 - LLVMPositionBuilderAtEnd(b, b_fetch); -
430 - -
431 - /* -
432 - * If the tupledesc of the to-be-deformed tuple is known, -
433 - * and JITing of deforming is enabled, build deform -
434 - * function specific to tupledesc and the exact number of -
435 - * to-be-extracted attributes. -
436 - */ -
437 - if (tts_ops && desc && (context->base.flags & PGJIT_DEFORM)) -
438 - { -
439 - INSTR_TIME_SET_CURRENT(deform_starttime); -
440 - l_jit_deform = -
441 - slot_compile_deform(context, desc, -
442 - tts_ops, -
443 - op->d.fetch.last_var); -
444 - INSTR_TIME_SET_CURRENT(deform_endtime); -
445 - INSTR_TIME_ACCUM_DIFF(context->base.instr.deform_counter, -
446 - deform_endtime, deform_starttime); -
447 - } -
448 - -
449 - if (l_jit_deform) -
450 - { -
451 - LLVMValueRef params[1]; -
452 - -
453 - params[0] = v_slot; -
454 - -
455 - l_call(b, -
456 - LLVMGetFunctionType(l_jit_deform), -
457 - l_jit_deform, -
458 - params, lengthof(params), ""); -
459 - } -
460 - else -
461 - { -
462 - LLVMValueRef params[2]; -
463 - -
464 - params[0] = v_slot; -
465 - params[1] = l_int32_const(lc, op->d.fetch.last_var); -
466 - -
467 - l_call(b, -
468 - llvm_pg_var_func_type("slot_getsomeattrs_int"), -
469 - llvm_pg_func(mod, "slot_getsomeattrs_int"), -
470 - params, lengthof(params), ""); -
471 - } -
472 - -
473 - LLVMBuildBr(b, opblocks[opno + 1]); -
474 - break; -
475 - } -
476 - -
477 - case EEOP_INNER_VAR: -
478 - case EEOP_OUTER_VAR: -
479 - case EEOP_SCAN_VAR: -
480 - case EEOP_OLD_VAR: -
481 - case EEOP_NEW_VAR: -
482 - { -
483 - LLVMValueRef value, -
484 - isnull; -
485 - LLVMValueRef v_attnum; -
486 - LLVMValueRef v_values; -
487 - LLVMValueRef v_nulls; -
488 - -
489 - if (opcode == EEOP_INNER_VAR) -
490 - { -
491 - v_values = v_innervalues; -
492 - v_nulls = v_innernulls; -
493 - } -
494 - else if (opcode == EEOP_OUTER_VAR) -
495 - { -
496 32 if (has_rpr_nav) 24cfb8dRow pattern recognition patch (executor and commands).
497 - { 24cfb8dRow pattern recognition patch (executor and commands).
498 - /* 24cfb8dRow pattern recognition patch (executor and commands).
499 - * RPR navigation swaps ecxt_outertuple 24cfb8dRow pattern recognition patch (executor and commands).
500 - * mid-expression. Reload slot pointer from 24cfb8dRow pattern recognition patch (executor and commands).
501 - * econtext on every access so we read from the 24cfb8dRow pattern recognition patch (executor and commands).
502 - * current (possibly swapped) slot. 24cfb8dRow pattern recognition patch (executor and commands).
503 - */ 24cfb8dRow pattern recognition patch (executor and commands).
504 20 LLVMValueRef v_tmpslot; 24cfb8dRow pattern recognition patch (executor and commands).
505 - 24cfb8dRow pattern recognition patch (executor and commands).
506 20 v_tmpslot = l_load_struct_gep(b, 24cfb8dRow pattern recognition patch (executor and commands).
507 - StructExprContext, 24cfb8dRow pattern recognition patch (executor and commands).
508 - v_econtext, 24cfb8dRow pattern recognition patch (executor and commands).
509 - FIELDNO_EXPRCONTEXT_OUTERTUPLE, 24cfb8dRow pattern recognition patch (executor and commands).
510 - "v_outerslot_reload"); 24cfb8dRow pattern recognition patch (executor and commands).
511 20 v_values = l_load_struct_gep(b, 24cfb8dRow pattern recognition patch (executor and commands).
512 - StructTupleTableSlot, 24cfb8dRow pattern recognition patch (executor and commands).
513 - v_tmpslot, 24cfb8dRow pattern recognition patch (executor and commands).
514 - FIELDNO_TUPLETABLESLOT_VALUES, 24cfb8dRow pattern recognition patch (executor and commands).
515 - "v_outervalues_reload"); 24cfb8dRow pattern recognition patch (executor and commands).
516 20 v_nulls = l_load_struct_gep(b, 24cfb8dRow pattern recognition patch (executor and commands).
517 - StructTupleTableSlot, 24cfb8dRow pattern recognition patch (executor and commands).
518 - v_tmpslot, 24cfb8dRow pattern recognition patch (executor and commands).
519 - FIELDNO_TUPLETABLESLOT_ISNULL, 24cfb8dRow pattern recognition patch (executor and commands).
520 - "v_outernulls_reload"); 24cfb8dRow pattern recognition patch (executor and commands).
521 - } 24cfb8dRow pattern recognition patch (executor and commands).
522 - else 24cfb8dRow pattern recognition patch (executor and commands).
523 - { 24cfb8dRow pattern recognition patch (executor and commands).
524 - v_values = v_outervalues; 24cfb8dRow pattern recognition patch (executor and commands).
525 - v_nulls = v_outernulls; 24cfb8dRow pattern recognition patch (executor and commands).
526 - } 24cfb8dRow pattern recognition patch (executor and commands).
527 - } -
528 - else if (opcode == EEOP_SCAN_VAR) -
529 - { -
530 - v_values = v_scanvalues; -
531 - v_nulls = v_scannulls; -
532 - } -
533 - else if (opcode == EEOP_OLD_VAR) -
534 - { -
535 - v_values = v_oldvalues; -
536 - v_nulls = v_oldnulls; -
537 - } -
538 - else -
539 - { -
540 - v_values = v_newvalues; -
541 - v_nulls = v_newnulls; -
542 - } -
543 - -
544 - v_attnum = l_int32_const(lc, op->d.var.attnum); -
545 - value = l_load_gep1(b, TypeDatum, v_values, v_attnum, ""); -
546 - isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, ""); -
547 - LLVMBuildStore(b, value, v_resvaluep); -
548 - LLVMBuildStore(b, isnull, v_resnullp); -
549 - -
550 - LLVMBuildBr(b, opblocks[opno + 1]); -
551 - break; -
552 - } -
553 - -
554 - case EEOP_INNER_SYSVAR: -
555 - case EEOP_OUTER_SYSVAR: -
556 - case EEOP_SCAN_SYSVAR: -
557 - case EEOP_OLD_SYSVAR: -
558 - case EEOP_NEW_SYSVAR: -
559 - { -
560 - LLVMValueRef v_slot; -
561 - -
562 - if (opcode == EEOP_INNER_SYSVAR) -
563 - v_slot = v_innerslot; -
564 - else if (opcode == EEOP_OUTER_SYSVAR) -
565 - v_slot = v_outerslot; -
566 - else if (opcode == EEOP_SCAN_SYSVAR) -
567 - v_slot = v_scanslot; -
568 - else if (opcode == EEOP_OLD_SYSVAR) -
569 - v_slot = v_oldslot; -
570 - else -
571 - v_slot = v_newslot; -
572 - -
573 - build_EvalXFunc(b, mod, "ExecEvalSysVar", -
574 - v_state, op, v_econtext, v_slot); -
575 - -
576 - LLVMBuildBr(b, opblocks[opno + 1]); -
577 - break; -
578 - } -
579 - -
580 - case EEOP_WHOLEROW: -
581 - build_EvalXFunc(b, mod, "ExecEvalWholeRowVar", -
582 - v_state, op, v_econtext); -
583 - LLVMBuildBr(b, opblocks[opno + 1]); -
584 - break; -
585 - -
586 - case EEOP_ASSIGN_INNER_VAR: -
587 - case EEOP_ASSIGN_OUTER_VAR: -
588 - case EEOP_ASSIGN_SCAN_VAR: -
589 - case EEOP_ASSIGN_OLD_VAR: -
590 - case EEOP_ASSIGN_NEW_VAR: -
591 - { -
592 - LLVMValueRef v_value; -
593 - LLVMValueRef v_isnull; -
594 - LLVMValueRef v_rvaluep; -
595 - LLVMValueRef v_risnullp; -
596 - LLVMValueRef v_attnum; -
597 - LLVMValueRef v_resultnum; -
598 - LLVMValueRef v_values; -
599 - LLVMValueRef v_nulls; -
600 - -
601 - if (opcode == EEOP_ASSIGN_INNER_VAR) -
602 - { -
603 - v_values = v_innervalues; -
604 - v_nulls = v_innernulls; -
605 - } -
606 - else if (opcode == EEOP_ASSIGN_OUTER_VAR) -
607 - { -
608 - v_values = v_outervalues; -
609 - v_nulls = v_outernulls; -
610 - } -
611 - else if (opcode == EEOP_ASSIGN_SCAN_VAR) -
612 - { -
613 - v_values = v_scanvalues; -
614 - v_nulls = v_scannulls; -
615 - } -
616 - else if (opcode == EEOP_ASSIGN_OLD_VAR) -
617 - { -
618 - v_values = v_oldvalues; -
619 - v_nulls = v_oldnulls; -
620 - } -
621 - else -
622 - { -
623 - v_values = v_newvalues; -
624 - v_nulls = v_newnulls; -
625 - } -
626 - -
627 - /* load data */ -
628 - v_attnum = l_int32_const(lc, op->d.assign_var.attnum); -
629 - v_value = l_load_gep1(b, TypeDatum, v_values, v_attnum, ""); -
630 - v_isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, ""); -
631 - -
632 - /* compute addresses of targets */ -
633 - v_resultnum = l_int32_const(lc, op->d.assign_var.resultnum); -
634 - v_rvaluep = l_gep(b, -
635 - TypeDatum, -
636 - v_resultvalues, -
637 - &v_resultnum, 1, ""); -
638 - v_risnullp = l_gep(b, -
639 - TypeStorageBool, -
640 - v_resultnulls, -
641 - &v_resultnum, 1, ""); -
642 - -
643 - /* and store */ -
644 - LLVMBuildStore(b, v_value, v_rvaluep); -
645 - LLVMBuildStore(b, v_isnull, v_risnullp); -
646 - -
647 - LLVMBuildBr(b, opblocks[opno + 1]); -
648 - break; -
649 - } -
650 - -
651 - case EEOP_ASSIGN_TMP: -
652 - case EEOP_ASSIGN_TMP_MAKE_RO: -
653 - { -
654 - LLVMValueRef v_value, -
655 - v_isnull; -
656 - LLVMValueRef v_rvaluep, -
657 - v_risnullp; -
658 - LLVMValueRef v_resultnum; -
659 - size_t resultnum = op->d.assign_tmp.resultnum; -
660 - -
661 - /* load data */ -
662 - v_value = l_load(b, TypeDatum, v_tmpvaluep, ""); -
663 - v_isnull = l_load(b, TypeStorageBool, v_tmpisnullp, ""); -
664 - -
665 - /* compute addresses of targets */ -
666 - v_resultnum = l_int32_const(lc, resultnum); -
667 - v_rvaluep = -
668 - l_gep(b, TypeDatum, v_resultvalues, &v_resultnum, 1, ""); -
669 - v_risnullp = -
670 - l_gep(b, TypeStorageBool, v_resultnulls, &v_resultnum, 1, ""); -
671 - -
672 - /* store nullness */ -
673 - LLVMBuildStore(b, v_isnull, v_risnullp); -
674 - -
675 - /* make value readonly if necessary */ -
676 - if (opcode == EEOP_ASSIGN_TMP_MAKE_RO) -
677 - { -
678 - LLVMBasicBlockRef b_notnull; -
679 - LLVMValueRef v_params[1]; -
680 - -
681 - b_notnull = l_bb_before_v(opblocks[opno + 1], -
682 - "op.%d.assign_tmp.notnull", opno); -
683 - -
684 - /* check if value is NULL */ -
685 - LLVMBuildCondBr(b, -
686 - LLVMBuildICmp(b, LLVMIntEQ, v_isnull, -
687 - l_sbool_const(0), ""), -
688 - b_notnull, opblocks[opno + 1]); -
689 - -
690 - /* if value is not null, convert to RO datum */ -
691 - LLVMPositionBuilderAtEnd(b, b_notnull); -
692 - v_params[0] = v_value; -
693 - v_value = -
694 - l_call(b, -
695 - llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"), -
696 - llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"), -
697 - v_params, lengthof(v_params), ""); -
698 - -
699 - /* -
700 - * Falling out of the if () with builder in b_notnull, -
701 - * which is fine - the null is already stored above. -
702 - */ -
703 - } -
704 - -
705 - /* and finally store result */ -
706 - LLVMBuildStore(b, v_value, v_rvaluep); -
707 - -
708 - LLVMBuildBr(b, opblocks[opno + 1]); -
709 - break; -
710 - } -
711 - -
712 - case EEOP_CONST: -
713 - { -
714 - LLVMValueRef v_constvalue, -
715 - v_constnull; -
716 - -
717 - v_constvalue = l_datum_const(op->d.constval.value); -
718 - v_constnull = l_sbool_const(op->d.constval.isnull); -
719 - -
720 - LLVMBuildStore(b, v_constvalue, v_resvaluep); -
721 - LLVMBuildStore(b, v_constnull, v_resnullp); -
722 - -
723 - LLVMBuildBr(b, opblocks[opno + 1]); -
724 - break; -
725 - } -
726 - -
727 - case EEOP_FUNCEXPR: -
728 - case EEOP_FUNCEXPR_STRICT: -
729 - case EEOP_FUNCEXPR_STRICT_1: -
730 - case EEOP_FUNCEXPR_STRICT_2: -
731 - { -
732 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
733 - LLVMValueRef v_fcinfo_isnull; -
734 - LLVMValueRef v_retval; -
735 - -
736 - if (opcode == EEOP_FUNCEXPR_STRICT || -
737 - opcode == EEOP_FUNCEXPR_STRICT_1 || -
738 - opcode == EEOP_FUNCEXPR_STRICT_2) -
739 - { -
740 - LLVMBasicBlockRef b_nonull; -
741 - LLVMBasicBlockRef *b_checkargnulls; -
742 - LLVMValueRef v_fcinfo; -
743 - -
744 - /* -
745 - * Block for the actual function call, if args are -
746 - * non-NULL. -
747 - */ -
748 - b_nonull = l_bb_before_v(opblocks[opno + 1], -
749 - "b.%d.no-null-args", opno); -
750 - -
751 - /* should make sure they're optimized beforehand */ -
752 - if (op->d.func.nargs == 0) -
753 - elog(ERROR, "argumentless strict functions are pointless"); -
754 - -
755 - v_fcinfo = -
756 - l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); -
757 - -
758 - /* -
759 - * set resnull to true, if the function is actually -
760 - * called, it'll be reset -
761 - */ -
762 - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); -
763 - -
764 - /* create blocks for checking args, one for each */ -
765 - b_checkargnulls = (LLVMBasicBlockRef *) -
766 - palloc(sizeof(LLVMBasicBlockRef) * op->d.func.nargs); -
767 - for (int argno = 0; argno < op->d.func.nargs; argno++) -
768 - b_checkargnulls[argno] = -
769 - l_bb_before_v(b_nonull, "b.%d.isnull.%d", opno, -
770 - argno); -
771 - -
772 - /* jump to check of first argument */ -
773 - LLVMBuildBr(b, b_checkargnulls[0]); -
774 - -
775 - /* check each arg for NULLness */ -
776 - for (int argno = 0; argno < op->d.func.nargs; argno++) -
777 - { -
778 - LLVMValueRef v_argisnull; -
779 - LLVMBasicBlockRef b_argnotnull; -
780 - -
781 - LLVMPositionBuilderAtEnd(b, b_checkargnulls[argno]); -
782 - -
783 - /* -
784 - * Compute block to jump to if argument is not -
785 - * null. -
786 - */ -
787 - if (argno + 1 == op->d.func.nargs) -
788 - b_argnotnull = b_nonull; -
789 - else -
790 - b_argnotnull = b_checkargnulls[argno + 1]; -
791 - -
792 - /* and finally load & check NULLness of arg */ -
793 - v_argisnull = l_funcnull(b, v_fcinfo, argno); -
794 - LLVMBuildCondBr(b, -
795 - LLVMBuildICmp(b, LLVMIntEQ, -
796 - v_argisnull, -
797 - l_sbool_const(1), -
798 - ""), -
799 - opblocks[opno + 1], -
800 - b_argnotnull); -
801 - } -
802 - -
803 - LLVMPositionBuilderAtEnd(b, b_nonull); -
804 - } -
805 - -
806 - v_retval = BuildV1Call(context, b, mod, fcinfo, -
807 - &v_fcinfo_isnull); -
808 - LLVMBuildStore(b, v_retval, v_resvaluep); -
809 - LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp); -
810 - -
811 - LLVMBuildBr(b, opblocks[opno + 1]); -
812 - break; -
813 - } -
814 - -
815 - case EEOP_FUNCEXPR_FUSAGE: -
816 - build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage", -
817 - v_state, op, v_econtext); -
818 - LLVMBuildBr(b, opblocks[opno + 1]); -
819 - break; -
820 - -
821 - -
822 - case EEOP_FUNCEXPR_STRICT_FUSAGE: -
823 - build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage", -
824 - v_state, op, v_econtext); -
825 - LLVMBuildBr(b, opblocks[opno + 1]); -
826 - break; -
827 - -
828 - /* -
829 - * Treat them the same for now, optimizer can remove -
830 - * redundancy. Could be worthwhile to optimize during emission -
831 - * though. -
832 - */ -
833 - case EEOP_BOOL_AND_STEP_FIRST: -
834 - case EEOP_BOOL_AND_STEP: -
835 - case EEOP_BOOL_AND_STEP_LAST: -
836 - { -
837 - LLVMValueRef v_boolvalue; -
838 - LLVMValueRef v_boolnull; -
839 - LLVMValueRef v_boolanynullp, -
840 - v_boolanynull; -
841 - LLVMBasicBlockRef b_boolisnull; -
842 - LLVMBasicBlockRef b_boolcheckfalse; -
843 - LLVMBasicBlockRef b_boolisfalse; -
844 - LLVMBasicBlockRef b_boolcont; -
845 - LLVMBasicBlockRef b_boolisanynull; -
846 - -
847 - b_boolisnull = l_bb_before_v(opblocks[opno + 1], -
848 - "b.%d.boolisnull", opno); -
849 - b_boolcheckfalse = l_bb_before_v(opblocks[opno + 1], -
850 - "b.%d.boolcheckfalse", opno); -
851 - b_boolisfalse = l_bb_before_v(opblocks[opno + 1], -
852 - "b.%d.boolisfalse", opno); -
853 - b_boolisanynull = l_bb_before_v(opblocks[opno + 1], -
854 - "b.%d.boolisanynull", opno); -
855 - b_boolcont = l_bb_before_v(opblocks[opno + 1], -
856 - "b.%d.boolcont", opno); -
857 - -
858 - v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull, -
859 - l_ptr(TypeStorageBool)); -
860 - -
861 - if (opcode == EEOP_BOOL_AND_STEP_FIRST) -
862 - LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp); -
863 - -
864 - v_boolnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
865 - v_boolvalue = l_load(b, TypeDatum, v_resvaluep, ""); -
866 - -
867 - /* check if current input is NULL */ -
868 - LLVMBuildCondBr(b, -
869 - LLVMBuildICmp(b, LLVMIntEQ, v_boolnull, -
870 - l_sbool_const(1), ""), -
871 - b_boolisnull, -
872 - b_boolcheckfalse); -
873 - -
874 - /* build block that sets anynull */ -
875 - LLVMPositionBuilderAtEnd(b, b_boolisnull); -
876 - /* set boolanynull to true */ -
877 - LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp); -
878 - /* and jump to next block */ -
879 - LLVMBuildBr(b, b_boolcont); -
880 - -
881 - /* build block checking for false */ -
882 - LLVMPositionBuilderAtEnd(b, b_boolcheckfalse); -
883 - LLVMBuildCondBr(b, -
884 - LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue, -
885 - l_datum_const(0), ""), -
886 - b_boolisfalse, -
887 - b_boolcont); -
888 - -
889 - /* -
890 - * Build block handling FALSE. Value is false, so short -
891 - * circuit. -
892 - */ -
893 - LLVMPositionBuilderAtEnd(b, b_boolisfalse); -
894 - /* result is already set to FALSE, need not change it */ -
895 - /* and jump to the end of the AND expression */ -
896 - LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]); -
897 - -
898 - /* Build block that continues if bool is TRUE. */ -
899 - LLVMPositionBuilderAtEnd(b, b_boolcont); -
900 - -
901 - v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, ""); -
902 - -
903 - /* set value to NULL if any previous values were NULL */ -
904 - LLVMBuildCondBr(b, -
905 - LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull, -
906 - l_sbool_const(0), ""), -
907 - opblocks[opno + 1], b_boolisanynull); -
908 - -
909 - LLVMPositionBuilderAtEnd(b, b_boolisanynull); -
910 - /* set resnull to true */ -
911 - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); -
912 - /* reset resvalue */ -
913 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
914 - -
915 - LLVMBuildBr(b, opblocks[opno + 1]); -
916 - break; -
917 - } -
918 - -
919 - /* -
920 - * Treat them the same for now, optimizer can remove -
921 - * redundancy. Could be worthwhile to optimize during emission -
922 - * though. -
923 - */ -
924 - case EEOP_BOOL_OR_STEP_FIRST: -
925 - case EEOP_BOOL_OR_STEP: -
926 - case EEOP_BOOL_OR_STEP_LAST: -
927 - { -
928 - LLVMValueRef v_boolvalue; -
929 - LLVMValueRef v_boolnull; -
930 - LLVMValueRef v_boolanynullp, -
931 - v_boolanynull; -
932 - -
933 - LLVMBasicBlockRef b_boolisnull; -
934 - LLVMBasicBlockRef b_boolchecktrue; -
935 - LLVMBasicBlockRef b_boolistrue; -
936 - LLVMBasicBlockRef b_boolcont; -
937 - LLVMBasicBlockRef b_boolisanynull; -
938 - -
939 - b_boolisnull = l_bb_before_v(opblocks[opno + 1], -
940 - "b.%d.boolisnull", opno); -
941 - b_boolchecktrue = l_bb_before_v(opblocks[opno + 1], -
942 - "b.%d.boolchecktrue", opno); -
943 - b_boolistrue = l_bb_before_v(opblocks[opno + 1], -
944 - "b.%d.boolistrue", opno); -
945 - b_boolisanynull = l_bb_before_v(opblocks[opno + 1], -
946 - "b.%d.boolisanynull", opno); -
947 - b_boolcont = l_bb_before_v(opblocks[opno + 1], -
948 - "b.%d.boolcont", opno); -
949 - -
950 - v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull, -
951 - l_ptr(TypeStorageBool)); -
952 - -
953 - if (opcode == EEOP_BOOL_OR_STEP_FIRST) -
954 - LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp); -
955 - v_boolnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
956 - v_boolvalue = l_load(b, TypeDatum, v_resvaluep, ""); -
957 - -
958 - LLVMBuildCondBr(b, -
959 - LLVMBuildICmp(b, LLVMIntEQ, v_boolnull, -
960 - l_sbool_const(1), ""), -
961 - b_boolisnull, -
962 - b_boolchecktrue); -
963 - -
964 - /* build block that sets anynull */ -
965 - LLVMPositionBuilderAtEnd(b, b_boolisnull); -
966 - /* set boolanynull to true */ -
967 - LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp); -
968 - /* and jump to next block */ -
969 - LLVMBuildBr(b, b_boolcont); -
970 - -
971 - /* build block checking for true */ -
972 - LLVMPositionBuilderAtEnd(b, b_boolchecktrue); -
973 - LLVMBuildCondBr(b, -
974 - LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue, -
975 - l_datum_const(1), ""), -
976 - b_boolistrue, -
977 - b_boolcont); -
978 - -
979 - /* -
980 - * Build block handling True. Value is true, so short -
981 - * circuit. -
982 - */ -
983 - LLVMPositionBuilderAtEnd(b, b_boolistrue); -
984 - /* result is already set to TRUE, need not change it */ -
985 - /* and jump to the end of the OR expression */ -
986 - LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]); -
987 - -
988 - /* build block that continues if bool is FALSE */ -
989 - LLVMPositionBuilderAtEnd(b, b_boolcont); -
990 - -
991 - v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, ""); -
992 - -
993 - /* set value to NULL if any previous values were NULL */ -
994 - LLVMBuildCondBr(b, -
995 - LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull, -
996 - l_sbool_const(0), ""), -
997 - opblocks[opno + 1], b_boolisanynull); -
998 - -
999 - LLVMPositionBuilderAtEnd(b, b_boolisanynull); -
1000 - /* set resnull to true */ -
1001 - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); -
1002 - /* reset resvalue */ -
1003 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
1004 - -
1005 - LLVMBuildBr(b, opblocks[opno + 1]); -
1006 - break; -
1007 - } -
1008 - -
1009 - case EEOP_BOOL_NOT_STEP: -
1010 - { -
1011 - LLVMValueRef v_boolvalue; -
1012 - LLVMValueRef v_negbool; -
1013 - -
1014 - /* compute !boolvalue */ -
1015 - v_boolvalue = l_load(b, TypeDatum, v_resvaluep, ""); -
1016 - v_negbool = LLVMBuildZExt(b, -
1017 - LLVMBuildICmp(b, LLVMIntEQ, -
1018 - v_boolvalue, -
1019 - l_datum_const(0), -
1020 - ""), -
1021 - TypeDatum, ""); -
1022 - -
1023 - /* -
1024 - * Store it back in resvalue. We can ignore resnull here; -
1025 - * if it was true, it stays true, and the value we store -
1026 - * in resvalue doesn't matter. -
1027 - */ -
1028 - LLVMBuildStore(b, v_negbool, v_resvaluep); -
1029 - -
1030 - LLVMBuildBr(b, opblocks[opno + 1]); -
1031 - break; -
1032 - } -
1033 - -
1034 - case EEOP_QUAL: -
1035 - { -
1036 - LLVMValueRef v_resnull; -
1037 - LLVMValueRef v_resvalue; -
1038 - LLVMValueRef v_nullorfalse; -
1039 - LLVMBasicBlockRef b_qualfail; -
1040 - -
1041 - b_qualfail = l_bb_before_v(opblocks[opno + 1], -
1042 - "op.%d.qualfail", opno); -
1043 - -
1044 - v_resvalue = l_load(b, TypeDatum, v_resvaluep, ""); -
1045 - v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1046 - -
1047 - v_nullorfalse = -
1048 - LLVMBuildOr(b, -
1049 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1050 - l_sbool_const(1), ""), -
1051 - LLVMBuildICmp(b, LLVMIntEQ, v_resvalue, -
1052 - l_datum_const(0), ""), -
1053 - ""); -
1054 - -
1055 - LLVMBuildCondBr(b, -
1056 - v_nullorfalse, -
1057 - b_qualfail, -
1058 - opblocks[opno + 1]); -
1059 - -
1060 - /* build block handling NULL or false */ -
1061 - LLVMPositionBuilderAtEnd(b, b_qualfail); -
1062 - /* set resnull to false */ -
1063 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
1064 - /* set resvalue to false */ -
1065 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
1066 - /* and jump out */ -
1067 - LLVMBuildBr(b, opblocks[op->d.qualexpr.jumpdone]); -
1068 - break; -
1069 - } -
1070 - -
1071 - case EEOP_JUMP: -
1072 - { -
1073 - LLVMBuildBr(b, opblocks[op->d.jump.jumpdone]); -
1074 - break; -
1075 - } -
1076 - -
1077 - case EEOP_JUMP_IF_NULL: -
1078 - { -
1079 - LLVMValueRef v_resnull; -
1080 - -
1081 - /* Transfer control if current result is null */ -
1082 - -
1083 - v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1084 - -
1085 - LLVMBuildCondBr(b, -
1086 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1087 - l_sbool_const(1), ""), -
1088 - opblocks[op->d.jump.jumpdone], -
1089 - opblocks[opno + 1]); -
1090 - break; -
1091 - } -
1092 - -
1093 - case EEOP_JUMP_IF_NOT_NULL: -
1094 - { -
1095 - LLVMValueRef v_resnull; -
1096 - -
1097 - /* Transfer control if current result is non-null */ -
1098 - -
1099 - v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1100 - -
1101 - LLVMBuildCondBr(b, -
1102 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1103 - l_sbool_const(0), ""), -
1104 - opblocks[op->d.jump.jumpdone], -
1105 - opblocks[opno + 1]); -
1106 - break; -
1107 - } -
1108 - -
1109 - -
1110 - case EEOP_JUMP_IF_NOT_TRUE: -
1111 - { -
1112 - LLVMValueRef v_resnull; -
1113 - LLVMValueRef v_resvalue; -
1114 - LLVMValueRef v_nullorfalse; -
1115 - -
1116 - /* Transfer control if current result is null or false */ -
1117 - -
1118 - v_resvalue = l_load(b, TypeDatum, v_resvaluep, ""); -
1119 - v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1120 - -
1121 - v_nullorfalse = -
1122 - LLVMBuildOr(b, -
1123 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1124 - l_sbool_const(1), ""), -
1125 - LLVMBuildICmp(b, LLVMIntEQ, v_resvalue, -
1126 - l_datum_const(0), ""), -
1127 - ""); -
1128 - -
1129 - LLVMBuildCondBr(b, -
1130 - v_nullorfalse, -
1131 - opblocks[op->d.jump.jumpdone], -
1132 - opblocks[opno + 1]); -
1133 - break; -
1134 - } -
1135 - -
1136 - case EEOP_NULLTEST_ISNULL: -
1137 - { -
1138 - LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1139 - LLVMValueRef v_resvalue; -
1140 - -
1141 - v_resvalue = -
1142 - LLVMBuildSelect(b, -
1143 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1144 - l_sbool_const(1), ""), -
1145 - l_datum_const(1), -
1146 - l_datum_const(0), -
1147 - ""); -
1148 - LLVMBuildStore(b, v_resvalue, v_resvaluep); -
1149 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
1150 - -
1151 - LLVMBuildBr(b, opblocks[opno + 1]); -
1152 - break; -
1153 - } -
1154 - -
1155 - case EEOP_NULLTEST_ISNOTNULL: -
1156 - { -
1157 - LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1158 - LLVMValueRef v_resvalue; -
1159 - -
1160 - v_resvalue = -
1161 - LLVMBuildSelect(b, -
1162 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1163 - l_sbool_const(1), ""), -
1164 - l_datum_const(0), -
1165 - l_datum_const(1), -
1166 - ""); -
1167 - LLVMBuildStore(b, v_resvalue, v_resvaluep); -
1168 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
1169 - -
1170 - LLVMBuildBr(b, opblocks[opno + 1]); -
1171 - break; -
1172 - } -
1173 - -
1174 - case EEOP_NULLTEST_ROWISNULL: -
1175 - build_EvalXFunc(b, mod, "ExecEvalRowNull", -
1176 - v_state, op, v_econtext); -
1177 - LLVMBuildBr(b, opblocks[opno + 1]); -
1178 - break; -
1179 - -
1180 - case EEOP_NULLTEST_ROWISNOTNULL: -
1181 - build_EvalXFunc(b, mod, "ExecEvalRowNotNull", -
1182 - v_state, op, v_econtext); -
1183 - LLVMBuildBr(b, opblocks[opno + 1]); -
1184 - break; -
1185 - -
1186 - case EEOP_BOOLTEST_IS_TRUE: -
1187 - case EEOP_BOOLTEST_IS_NOT_FALSE: -
1188 - case EEOP_BOOLTEST_IS_FALSE: -
1189 - case EEOP_BOOLTEST_IS_NOT_TRUE: -
1190 - { -
1191 - LLVMBasicBlockRef b_isnull, -
1192 - b_notnull; -
1193 - LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1194 - -
1195 - b_isnull = l_bb_before_v(opblocks[opno + 1], -
1196 - "op.%d.isnull", opno); -
1197 - b_notnull = l_bb_before_v(opblocks[opno + 1], -
1198 - "op.%d.isnotnull", opno); -
1199 - -
1200 - /* check if value is NULL */ -
1201 - LLVMBuildCondBr(b, -
1202 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1203 - l_sbool_const(1), ""), -
1204 - b_isnull, b_notnull); -
1205 - -
1206 - /* if value is NULL, return false */ -
1207 - LLVMPositionBuilderAtEnd(b, b_isnull); -
1208 - -
1209 - /* result is not null */ -
1210 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
1211 - -
1212 - if (opcode == EEOP_BOOLTEST_IS_TRUE || -
1213 - opcode == EEOP_BOOLTEST_IS_FALSE) -
1214 - { -
1215 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
1216 - } -
1217 - else -
1218 - { -
1219 - LLVMBuildStore(b, l_datum_const(1), v_resvaluep); -
1220 - } -
1221 - -
1222 - LLVMBuildBr(b, opblocks[opno + 1]); -
1223 - -
1224 - LLVMPositionBuilderAtEnd(b, b_notnull); -
1225 - -
1226 - if (opcode == EEOP_BOOLTEST_IS_TRUE || -
1227 - opcode == EEOP_BOOLTEST_IS_NOT_FALSE) -
1228 - { -
1229 - /* -
1230 - * if value is not null NULL, return value (already -
1231 - * set) -
1232 - */ -
1233 - } -
1234 - else -
1235 - { -
1236 - LLVMValueRef v_value = -
1237 - l_load(b, TypeDatum, v_resvaluep, ""); -
1238 - -
1239 - v_value = LLVMBuildZExt(b, -
1240 - LLVMBuildICmp(b, LLVMIntEQ, -
1241 - v_value, -
1242 - l_datum_const(0), -
1243 - ""), -
1244 - TypeDatum, ""); -
1245 - LLVMBuildStore(b, v_value, v_resvaluep); -
1246 - } -
1247 - LLVMBuildBr(b, opblocks[opno + 1]); -
1248 - break; -
1249 - } -
1250 - -
1251 - case EEOP_PARAM_EXEC: -
1252 - build_EvalXFunc(b, mod, "ExecEvalParamExec", -
1253 - v_state, op, v_econtext); -
1254 - LLVMBuildBr(b, opblocks[opno + 1]); -
1255 - break; -
1256 - -
1257 - case EEOP_PARAM_EXTERN: -
1258 - build_EvalXFunc(b, mod, "ExecEvalParamExtern", -
1259 - v_state, op, v_econtext); -
1260 - LLVMBuildBr(b, opblocks[opno + 1]); -
1261 - break; -
1262 - -
1263 - case EEOP_PARAM_CALLBACK: -
1264 - { -
1265 - LLVMValueRef v_func; -
1266 - LLVMValueRef v_params[3]; -
1267 - -
1268 - v_func = l_ptr_const(op->d.cparam.paramfunc, -
1269 - llvm_pg_var_type("TypeExecEvalSubroutine")); -
1270 - -
1271 - v_params[0] = v_state; -
1272 - v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); -
1273 - v_params[2] = v_econtext; -
1274 - l_call(b, -
1275 - LLVMGetFunctionType(ExecEvalSubroutineTemplate), -
1276 - v_func, -
1277 - v_params, lengthof(v_params), ""); -
1278 - -
1279 - LLVMBuildBr(b, opblocks[opno + 1]); -
1280 - break; -
1281 - } -
1282 - -
1283 - case EEOP_PARAM_SET: -
1284 - build_EvalXFunc(b, mod, "ExecEvalParamSet", -
1285 - v_state, op, v_econtext); -
1286 - LLVMBuildBr(b, opblocks[opno + 1]); -
1287 - break; -
1288 - -
1289 - case EEOP_SBSREF_SUBSCRIPTS: -
1290 - { -
1291 - int jumpdone = op->d.sbsref_subscript.jumpdone; -
1292 - LLVMValueRef v_func; -
1293 - LLVMValueRef v_params[3]; -
1294 - LLVMValueRef v_ret; -
1295 - -
1296 - v_func = l_ptr_const(op->d.sbsref_subscript.subscriptfunc, -
1297 - llvm_pg_var_type("TypeExecEvalBoolSubroutine")); -
1298 - -
1299 - v_params[0] = v_state; -
1300 - v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); -
1301 - v_params[2] = v_econtext; -
1302 - v_ret = l_call(b, -
1303 - LLVMGetFunctionType(ExecEvalBoolSubroutineTemplate), -
1304 - v_func, -
1305 - v_params, lengthof(v_params), ""); -
1306 - v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); -
1307 - -
1308 - LLVMBuildCondBr(b, -
1309 - LLVMBuildICmp(b, LLVMIntEQ, v_ret, -
1310 - l_sbool_const(1), ""), -
1311 - opblocks[opno + 1], -
1312 - opblocks[jumpdone]); -
1313 - break; -
1314 - } -
1315 - -
1316 - case EEOP_SBSREF_OLD: -
1317 - case EEOP_SBSREF_ASSIGN: -
1318 - case EEOP_SBSREF_FETCH: -
1319 - { -
1320 - LLVMValueRef v_func; -
1321 - LLVMValueRef v_params[3]; -
1322 - -
1323 - v_func = l_ptr_const(op->d.sbsref.subscriptfunc, -
1324 - llvm_pg_var_type("TypeExecEvalSubroutine")); -
1325 - -
1326 - v_params[0] = v_state; -
1327 - v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); -
1328 - v_params[2] = v_econtext; -
1329 - l_call(b, -
1330 - LLVMGetFunctionType(ExecEvalSubroutineTemplate), -
1331 - v_func, -
1332 - v_params, lengthof(v_params), ""); -
1333 - -
1334 - LLVMBuildBr(b, opblocks[opno + 1]); -
1335 - break; -
1336 - } -
1337 - -
1338 - case EEOP_CASE_TESTVAL: -
1339 - { -
1340 - LLVMValueRef v_casevaluep, -
1341 - v_casevalue; -
1342 - LLVMValueRef v_casenullp, -
1343 - v_casenull; -
1344 - -
1345 - v_casevaluep = l_ptr_const(op->d.casetest.value, -
1346 - l_ptr(TypeDatum)); -
1347 - v_casenullp = l_ptr_const(op->d.casetest.isnull, -
1348 - l_ptr(TypeStorageBool)); -
1349 - -
1350 - v_casevalue = l_load(b, TypeDatum, v_casevaluep, ""); -
1351 - v_casenull = l_load(b, TypeStorageBool, v_casenullp, ""); -
1352 - LLVMBuildStore(b, v_casevalue, v_resvaluep); -
1353 - LLVMBuildStore(b, v_casenull, v_resnullp); -
1354 - -
1355 - LLVMBuildBr(b, opblocks[opno + 1]); -
1356 - break; -
1357 - } -
1358 - -
1359 - case EEOP_CASE_TESTVAL_EXT: -
1360 - { -
1361 - LLVMValueRef v_casevalue; -
1362 - LLVMValueRef v_casenull; -
1363 - -
1364 - v_casevalue = -
1365 - l_load_struct_gep(b, -
1366 - StructExprContext, -
1367 - v_econtext, -
1368 - FIELDNO_EXPRCONTEXT_CASEDATUM, ""); -
1369 - v_casenull = -
1370 - l_load_struct_gep(b, -
1371 - StructExprContext, -
1372 - v_econtext, -
1373 - FIELDNO_EXPRCONTEXT_CASENULL, ""); -
1374 - LLVMBuildStore(b, v_casevalue, v_resvaluep); -
1375 - LLVMBuildStore(b, v_casenull, v_resnullp); -
1376 - -
1377 - LLVMBuildBr(b, opblocks[opno + 1]); -
1378 - break; -
1379 - } -
1380 - -
1381 - case EEOP_MAKE_READONLY: -
1382 - { -
1383 - LLVMBasicBlockRef b_notnull; -
1384 - LLVMValueRef v_params[1]; -
1385 - LLVMValueRef v_ret; -
1386 - LLVMValueRef v_nullp; -
1387 - LLVMValueRef v_valuep; -
1388 - LLVMValueRef v_null; -
1389 - LLVMValueRef v_value; -
1390 - -
1391 - b_notnull = l_bb_before_v(opblocks[opno + 1], -
1392 - "op.%d.readonly.notnull", opno); -
1393 - -
1394 - v_nullp = l_ptr_const(op->d.make_readonly.isnull, -
1395 - l_ptr(TypeStorageBool)); -
1396 - -
1397 - v_null = l_load(b, TypeStorageBool, v_nullp, ""); -
1398 - -
1399 - /* store null isnull value in result */ -
1400 - LLVMBuildStore(b, v_null, v_resnullp); -
1401 - -
1402 - /* check if value is NULL */ -
1403 - LLVMBuildCondBr(b, -
1404 - LLVMBuildICmp(b, LLVMIntEQ, v_null, -
1405 - l_sbool_const(1), ""), -
1406 - opblocks[opno + 1], b_notnull); -
1407 - -
1408 - /* if value is not null, convert to RO datum */ -
1409 - LLVMPositionBuilderAtEnd(b, b_notnull); -
1410 - -
1411 - v_valuep = l_ptr_const(op->d.make_readonly.value, -
1412 - l_ptr(TypeDatum)); -
1413 - -
1414 - v_value = l_load(b, TypeDatum, v_valuep, ""); -
1415 - -
1416 - v_params[0] = v_value; -
1417 - v_ret = -
1418 - l_call(b, -
1419 - llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"), -
1420 - llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"), -
1421 - v_params, lengthof(v_params), ""); -
1422 - LLVMBuildStore(b, v_ret, v_resvaluep); -
1423 - -
1424 - LLVMBuildBr(b, opblocks[opno + 1]); -
1425 - break; -
1426 - } -
1427 - -
1428 - case EEOP_IOCOERCE: -
1429 - { -
1430 - FunctionCallInfo fcinfo_out, -
1431 - fcinfo_in; -
1432 - LLVMValueRef v_fn_out, -
1433 - v_fn_in; -
1434 - LLVMValueRef v_fcinfo_out, -
1435 - v_fcinfo_in; -
1436 - LLVMValueRef v_fcinfo_in_isnullp; -
1437 - LLVMValueRef v_retval; -
1438 - LLVMValueRef v_resvalue; -
1439 - LLVMValueRef v_resnull; -
1440 - -
1441 - LLVMValueRef v_output_skip; -
1442 - LLVMValueRef v_output; -
1443 - -
1444 - LLVMBasicBlockRef b_skipoutput; -
1445 - LLVMBasicBlockRef b_calloutput; -
1446 - LLVMBasicBlockRef b_input; -
1447 - LLVMBasicBlockRef b_inputcall; -
1448 - -
1449 - fcinfo_out = op->d.iocoerce.fcinfo_data_out; -
1450 - fcinfo_in = op->d.iocoerce.fcinfo_data_in; -
1451 - -
1452 - b_skipoutput = l_bb_before_v(opblocks[opno + 1], -
1453 - "op.%d.skipoutputnull", opno); -
1454 - b_calloutput = l_bb_before_v(opblocks[opno + 1], -
1455 - "op.%d.calloutput", opno); -
1456 - b_input = l_bb_before_v(opblocks[opno + 1], -
1457 - "op.%d.input", opno); -
1458 - b_inputcall = l_bb_before_v(opblocks[opno + 1], -
1459 - "op.%d.inputcall", opno); -
1460 - -
1461 - v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out); -
1462 - v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in); -
1463 - v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData)); -
1464 - v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData)); -
1465 - -
1466 - v_fcinfo_in_isnullp = -
1467 - l_struct_gep(b, -
1468 - StructFunctionCallInfoData, -
1469 - v_fcinfo_in, -
1470 - FIELDNO_FUNCTIONCALLINFODATA_ISNULL, -
1471 - "v_fcinfo_in_isnull"); -
1472 - -
1473 - /* output functions are not called on nulls */ -
1474 - v_resnull = l_load(b, TypeStorageBool, v_resnullp, ""); -
1475 - LLVMBuildCondBr(b, -
1476 - LLVMBuildICmp(b, LLVMIntEQ, v_resnull, -
1477 - l_sbool_const(1), ""), -
1478 - b_skipoutput, -
1479 - b_calloutput); -
1480 - -
1481 - LLVMPositionBuilderAtEnd(b, b_skipoutput); -
1482 - v_output_skip = l_datum_const(0); -
1483 - LLVMBuildBr(b, b_input); -
1484 - -
1485 - LLVMPositionBuilderAtEnd(b, b_calloutput); -
1486 - v_resvalue = l_load(b, TypeDatum, v_resvaluep, ""); -
1487 - -
1488 - /* set arg[0] */ -
1489 - LLVMBuildStore(b, -
1490 - v_resvalue, -
1491 - l_funcvaluep(b, v_fcinfo_out, 0)); -
1492 - LLVMBuildStore(b, -
1493 - l_sbool_const(0), -
1494 - l_funcnullp(b, v_fcinfo_out, 0)); -
1495 - /* and call output function (can never return NULL) */ -
1496 - v_output = l_call(b, -
1497 - LLVMGetFunctionType(v_fn_out), -
1498 - v_fn_out, &v_fcinfo_out, -
1499 - 1, "funccall_coerce_out"); -
1500 - LLVMBuildBr(b, b_input); -
1501 - -
1502 - /* build block handling input function call */ -
1503 - LLVMPositionBuilderAtEnd(b, b_input); -
1504 - -
1505 - /* phi between resnull and output function call branches */ -
1506 - { -
1507 - LLVMValueRef incoming_values[2]; -
1508 - LLVMBasicBlockRef incoming_blocks[2]; -
1509 - -
1510 - incoming_values[0] = v_output_skip; -
1511 - incoming_blocks[0] = b_skipoutput; -
1512 - -
1513 - incoming_values[1] = v_output; -
1514 - incoming_blocks[1] = b_calloutput; -
1515 - -
1516 - v_output = LLVMBuildPhi(b, TypeDatum, "output"); -
1517 - LLVMAddIncoming(v_output, -
1518 - incoming_values, incoming_blocks, -
1519 - lengthof(incoming_blocks)); -
1520 - } -
1521 - -
1522 - /* -
1523 - * If input function is strict, skip if input string is -
1524 - * NULL. -
1525 - */ -
1526 - if (op->d.iocoerce.finfo_in->fn_strict) -
1527 - { -
1528 - LLVMBuildCondBr(b, -
1529 - LLVMBuildICmp(b, LLVMIntEQ, v_output, -
1530 - l_datum_const(0), ""), -
1531 - opblocks[opno + 1], -
1532 - b_inputcall); -
1533 - } -
1534 - else -
1535 - { -
1536 - LLVMBuildBr(b, b_inputcall); -
1537 - } -
1538 - -
1539 - LLVMPositionBuilderAtEnd(b, b_inputcall); -
1540 - /* set arguments */ -
1541 - /* arg0: output */ -
1542 - LLVMBuildStore(b, v_output, -
1543 - l_funcvaluep(b, v_fcinfo_in, 0)); -
1544 - LLVMBuildStore(b, v_resnull, -
1545 - l_funcnullp(b, v_fcinfo_in, 0)); -
1546 - -
1547 - /* arg1: ioparam: preset in execExpr.c */ -
1548 - /* arg2: typmod: preset in execExpr.c */ -
1549 - -
1550 - /* reset fcinfo_in->isnull */ -
1551 - LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp); -
1552 - /* and call function */ -
1553 - v_retval = l_call(b, -
1554 - LLVMGetFunctionType(v_fn_in), -
1555 - v_fn_in, &v_fcinfo_in, 1, -
1556 - "funccall_iocoerce_in"); -
1557 - -
1558 - LLVMBuildStore(b, v_retval, v_resvaluep); -
1559 - -
1560 - LLVMBuildBr(b, opblocks[opno + 1]); -
1561 - break; -
1562 - } -
1563 - -
1564 - case EEOP_IOCOERCE_SAFE: -
1565 - build_EvalXFunc(b, mod, "ExecEvalCoerceViaIOSafe", -
1566 - v_state, op); -
1567 - LLVMBuildBr(b, opblocks[opno + 1]); -
1568 - break; -
1569 - -
1570 - case EEOP_DISTINCT: -
1571 - case EEOP_NOT_DISTINCT: -
1572 - { -
1573 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
1574 - -
1575 - LLVMValueRef v_fcinfo; -
1576 - LLVMValueRef v_fcinfo_isnull; -
1577 - -
1578 - LLVMValueRef v_argnull0, -
1579 - v_argisnull0; -
1580 - LLVMValueRef v_argnull1, -
1581 - v_argisnull1; -
1582 - -
1583 - LLVMValueRef v_anyargisnull; -
1584 - LLVMValueRef v_bothargisnull; -
1585 - -
1586 - LLVMValueRef v_result; -
1587 - -
1588 - LLVMBasicBlockRef b_noargnull; -
1589 - LLVMBasicBlockRef b_checkbothargnull; -
1590 - LLVMBasicBlockRef b_bothargnull; -
1591 - LLVMBasicBlockRef b_anyargnull; -
1592 - -
1593 - b_noargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.noargnull", opno); -
1594 - b_checkbothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.checkbothargnull", opno); -
1595 - b_bothargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.bothargnull", opno); -
1596 - b_anyargnull = l_bb_before_v(opblocks[opno + 1], "op.%d.anyargnull", opno); -
1597 - -
1598 - v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); -
1599 - -
1600 - /* load args[0|1].isnull for both arguments */ -
1601 - v_argnull0 = l_funcnull(b, v_fcinfo, 0); -
1602 - v_argisnull0 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull0, -
1603 - l_sbool_const(1), ""); -
1604 - v_argnull1 = l_funcnull(b, v_fcinfo, 1); -
1605 - v_argisnull1 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull1, -
1606 - l_sbool_const(1), ""); -
1607 - -
1608 - v_anyargisnull = LLVMBuildOr(b, v_argisnull0, v_argisnull1, ""); -
1609 - v_bothargisnull = LLVMBuildAnd(b, v_argisnull0, v_argisnull1, ""); -
1610 - -
1611 - /* -
1612 - * Check function arguments for NULLness: If either is -
1613 - * NULL, we check if both args are NULL. Otherwise call -
1614 - * comparator. -
1615 - */ -
1616 - LLVMBuildCondBr(b, v_anyargisnull, b_checkbothargnull, -
1617 - b_noargnull); -
1618 - -
1619 - /* -
1620 - * build block checking if any arg is null -
1621 - */ -
1622 - LLVMPositionBuilderAtEnd(b, b_checkbothargnull); -
1623 - LLVMBuildCondBr(b, v_bothargisnull, b_bothargnull, -
1624 - b_anyargnull); -
1625 - -
1626 - -
1627 - /* Both NULL? Then is not distinct... */ -
1628 - LLVMPositionBuilderAtEnd(b, b_bothargnull); -
1629 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
1630 - if (opcode == EEOP_NOT_DISTINCT) -
1631 - LLVMBuildStore(b, l_datum_const(1), v_resvaluep); -
1632 - else -
1633 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
1634 - -
1635 - LLVMBuildBr(b, opblocks[opno + 1]); -
1636 - -
1637 - /* Only one is NULL? Then is distinct... */ -
1638 - LLVMPositionBuilderAtEnd(b, b_anyargnull); -
1639 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
1640 - if (opcode == EEOP_NOT_DISTINCT) -
1641 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
1642 - else -
1643 - LLVMBuildStore(b, l_datum_const(1), v_resvaluep); -
1644 - LLVMBuildBr(b, opblocks[opno + 1]); -
1645 - -
1646 - /* neither argument is null: compare */ -
1647 - LLVMPositionBuilderAtEnd(b, b_noargnull); -
1648 - -
1649 - v_result = BuildV1Call(context, b, mod, fcinfo, -
1650 - &v_fcinfo_isnull); -
1651 - -
1652 - if (opcode == EEOP_DISTINCT) -
1653 - { -
1654 - /* Must invert result of "=" */ -
1655 - v_result = -
1656 - LLVMBuildZExt(b, -
1657 - LLVMBuildICmp(b, LLVMIntEQ, -
1658 - v_result, -
1659 - l_datum_const(0), ""), -
1660 - TypeDatum, ""); -
1661 - } -
1662 - -
1663 - LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp); -
1664 - LLVMBuildStore(b, v_result, v_resvaluep); -
1665 - -
1666 - LLVMBuildBr(b, opblocks[opno + 1]); -
1667 - break; -
1668 - } -
1669 - -
1670 - case EEOP_NULLIF: -
1671 - { -
1672 - FunctionCallInfo fcinfo = op->d.func.fcinfo_data; -
1673 - -
1674 - LLVMValueRef v_fcinfo; -
1675 - LLVMValueRef v_fcinfo_isnull; -
1676 - LLVMValueRef v_argnull0; -
1677 - LLVMValueRef v_argnull1; -
1678 - LLVMValueRef v_anyargisnull; -
1679 - LLVMValueRef v_arg0; -
1680 - LLVMBasicBlockRef b_hasnull; -
1681 - LLVMBasicBlockRef b_nonull; -
1682 - LLVMBasicBlockRef b_argsequal; -
1683 - LLVMValueRef v_retval; -
1684 - LLVMValueRef v_argsequal; -
1685 - -
1686 - b_hasnull = l_bb_before_v(opblocks[opno + 1], -
1687 - "b.%d.null-args", opno); -
1688 - b_nonull = l_bb_before_v(opblocks[opno + 1], -
1689 - "b.%d.no-null-args", opno); -
1690 - b_argsequal = l_bb_before_v(opblocks[opno + 1], -
1691 - "b.%d.argsequal", opno); -
1692 - -
1693 - v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); -
1694 - -
1695 - /* save original arg[0] */ -
1696 - v_arg0 = l_funcvalue(b, v_fcinfo, 0); -
1697 - -
1698 - /* if either argument is NULL they can't be equal */ -
1699 - v_argnull0 = l_funcnull(b, v_fcinfo, 0); -
1700 - v_argnull1 = l_funcnull(b, v_fcinfo, 1); -
1701 - -
1702 - v_anyargisnull = -
1703 - LLVMBuildOr(b, -
1704 - LLVMBuildICmp(b, LLVMIntEQ, v_argnull0, -
1705 - l_sbool_const(1), ""), -
1706 - LLVMBuildICmp(b, LLVMIntEQ, v_argnull1, -
1707 - l_sbool_const(1), ""), -
1708 - ""); -
1709 - -
1710 - LLVMBuildCondBr(b, v_anyargisnull, b_hasnull, b_nonull); -
1711 - -
1712 - /* one (or both) of the arguments are null, return arg[0] */ -
1713 - LLVMPositionBuilderAtEnd(b, b_hasnull); -
1714 - LLVMBuildStore(b, v_argnull0, v_resnullp); -
1715 - LLVMBuildStore(b, v_arg0, v_resvaluep); -
1716 - LLVMBuildBr(b, opblocks[opno + 1]); -
1717 - -
1718 - /* build block to invoke function and check result */ -
1719 - LLVMPositionBuilderAtEnd(b, b_nonull); -
1720 - -
1721 - /* -
1722 - * If first argument is of varlena type, it might be an -
1723 - * expanded datum. We need to ensure that the value -
1724 - * passed to the comparison function is a read-only -
1725 - * pointer. However, if we end by returning the first -
1726 - * argument, that will be the original read-write pointer -
1727 - * if it was read-write. -
1728 - */ -
1729 - if (op->d.func.make_ro) -
1730 - { -
1731 - LLVMValueRef v_params[1]; -
1732 - LLVMValueRef v_arg0_ro; -
1733 - -
1734 - v_params[0] = v_arg0; -
1735 - v_arg0_ro = -
1736 - l_call(b, -
1737 - llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"), -
1738 - llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"), -
1739 - v_params, lengthof(v_params), ""); -
1740 - LLVMBuildStore(b, v_arg0_ro, -
1741 - l_funcvaluep(b, v_fcinfo, 0)); -
1742 - } -
1743 - -
1744 - v_retval = BuildV1Call(context, b, mod, fcinfo, &v_fcinfo_isnull); -
1745 - -
1746 - /* -
1747 - * If result not null and arguments are equal return null, -
1748 - * else return arg[0] (same result as if there'd been -
1749 - * NULLs, hence reuse b_hasnull). -
1750 - */ -
1751 - v_argsequal = LLVMBuildAnd(b, -
1752 - LLVMBuildICmp(b, LLVMIntEQ, -
1753 - v_fcinfo_isnull, -
1754 - l_sbool_const(0), -
1755 - ""), -
1756 - LLVMBuildICmp(b, LLVMIntEQ, -
1757 - v_retval, -
1758 - l_datum_const(1), -
1759 - ""), -
1760 - ""); -
1761 - LLVMBuildCondBr(b, v_argsequal, b_argsequal, b_hasnull); -
1762 - -
1763 - /* build block setting result to NULL, if args are equal */ -
1764 - LLVMPositionBuilderAtEnd(b, b_argsequal); -
1765 - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); -
1766 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
1767 - -
1768 - LLVMBuildBr(b, opblocks[opno + 1]); -
1769 - break; -
1770 - } -
1771 - -
1772 - case EEOP_SQLVALUEFUNCTION: -
1773 - build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction", -
1774 - v_state, op); -
1775 - LLVMBuildBr(b, opblocks[opno + 1]); -
1776 - break; -
1777 - -
1778 - case EEOP_CURRENTOFEXPR: -
1779 - build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr", -
1780 - v_state, op); -
1781 - LLVMBuildBr(b, opblocks[opno + 1]); -
1782 - break; -
1783 - -
1784 - case EEOP_NEXTVALUEEXPR: -
1785 - build_EvalXFunc(b, mod, "ExecEvalNextValueExpr", -
1786 - v_state, op); -
1787 - LLVMBuildBr(b, opblocks[opno + 1]); -
1788 - break; -
1789 - -
1790 - case EEOP_RETURNINGEXPR: -
1791 - { -
1792 - LLVMBasicBlockRef b_isnull; -
1793 - LLVMValueRef v_flagsp; -
1794 - LLVMValueRef v_flags; -
1795 - LLVMValueRef v_nullflag; -
1796 - -
1797 - b_isnull = l_bb_before_v(opblocks[opno + 1], -
1798 - "op.%d.row.isnull", opno); -
1799 - -
1800 - /* -
1801 - * The next op actually evaluates the expression. If the -
1802 - * OLD/NEW row doesn't exist, skip that and return NULL. -
1803 - */ -
1804 - v_flagsp = l_struct_gep(b, -
1805 - StructExprState, -
1806 - v_state, -
1807 - FIELDNO_EXPRSTATE_FLAGS, -
1808 - "v.state.flags"); -
1809 - v_flags = l_load(b, TypeStorageBool, v_flagsp, ""); -
1810 - -
1811 - v_nullflag = l_int8_const(lc, op->d.returningexpr.nullflag); -
1812 - -
1813 - LLVMBuildCondBr(b, -
1814 - LLVMBuildICmp(b, LLVMIntEQ, -
1815 - LLVMBuildAnd(b, v_flags, -
1816 - v_nullflag, ""), -
1817 - l_sbool_const(0), ""), -
1818 - opblocks[opno + 1], b_isnull); -
1819 - -
1820 - LLVMPositionBuilderAtEnd(b, b_isnull); -
1821 - -
1822 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
1823 - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); -
1824 - -
1825 - LLVMBuildBr(b, opblocks[op->d.returningexpr.jumpdone]); -
1826 - break; -
1827 - } -
1828 - -
1829 - case EEOP_ARRAYEXPR: -
1830 - build_EvalXFunc(b, mod, "ExecEvalArrayExpr", -
1831 - v_state, op); -
1832 - LLVMBuildBr(b, opblocks[opno + 1]); -
1833 - break; -
1834 - -
1835 - case EEOP_ARRAYCOERCE: -
1836 - build_EvalXFunc(b, mod, "ExecEvalArrayCoerce", -
1837 - v_state, op, v_econtext); -
1838 - LLVMBuildBr(b, opblocks[opno + 1]); -
1839 - break; -
1840 - -
1841 - case EEOP_ROW: -
1842 - build_EvalXFunc(b, mod, "ExecEvalRow", -
1843 - v_state, op); -
1844 - LLVMBuildBr(b, opblocks[opno + 1]); -
1845 - break; -
1846 - -
1847 - case EEOP_ROWCOMPARE_STEP: -
1848 - { -
1849 - FunctionCallInfo fcinfo = op->d.rowcompare_step.fcinfo_data; -
1850 - LLVMValueRef v_fcinfo_isnull; -
1851 - LLVMBasicBlockRef b_null; -
1852 - LLVMBasicBlockRef b_compare; -
1853 - LLVMBasicBlockRef b_compare_result; -
1854 - -
1855 - LLVMValueRef v_retval; -
1856 - -
1857 - b_null = l_bb_before_v(opblocks[opno + 1], -
1858 - "op.%d.row-null", opno); -
1859 - b_compare = l_bb_before_v(opblocks[opno + 1], -
1860 - "op.%d.row-compare", opno); -
1861 - b_compare_result = -
1862 - l_bb_before_v(opblocks[opno + 1], -
1863 - "op.%d.row-compare-result", -
1864 - opno); -
1865 - -
1866 - /* -
1867 - * If function is strict, and either arg is null, we're -
1868 - * done. -
1869 - */ -
1870 - if (op->d.rowcompare_step.finfo->fn_strict) -
1871 - { -
1872 - LLVMValueRef v_fcinfo; -
1873 - LLVMValueRef v_argnull0; -
1874 - LLVMValueRef v_argnull1; -
1875 - LLVMValueRef v_anyargisnull; -
1876 - -
1877 - v_fcinfo = l_ptr_const(fcinfo, -
1878 - l_ptr(StructFunctionCallInfoData)); -
1879 - -
1880 - v_argnull0 = l_funcnull(b, v_fcinfo, 0); -
1881 - v_argnull1 = l_funcnull(b, v_fcinfo, 1); -
1882 - -
1883 - v_anyargisnull = -
1884 - LLVMBuildOr(b, -
1885 - LLVMBuildICmp(b, -
1886 - LLVMIntEQ, -
1887 - v_argnull0, -
1888 - l_sbool_const(1), -
1889 - ""), -
1890 - LLVMBuildICmp(b, LLVMIntEQ, -
1891 - v_argnull1, -
1892 - l_sbool_const(1), ""), -
1893 - ""); -
1894 - -
1895 - LLVMBuildCondBr(b, v_anyargisnull, b_null, b_compare); -
1896 - } -
1897 - else -
1898 - { -
1899 - LLVMBuildBr(b, b_compare); -
1900 - } -
1901 - -
1902 - /* build block invoking comparison function */ -
1903 - LLVMPositionBuilderAtEnd(b, b_compare); -
1904 - -
1905 - /* call function */ -
1906 - v_retval = BuildV1Call(context, b, mod, fcinfo, -
1907 - &v_fcinfo_isnull); -
1908 - LLVMBuildStore(b, v_retval, v_resvaluep); -
1909 - -
1910 - /* if result of function is NULL, force NULL result */ -
1911 - LLVMBuildCondBr(b, -
1912 - LLVMBuildICmp(b, -
1913 - LLVMIntEQ, -
1914 - v_fcinfo_isnull, -
1915 - l_sbool_const(0), -
1916 - ""), -
1917 - b_compare_result, -
1918 - b_null); -
1919 - -
1920 - /* build block analyzing the !NULL comparator result */ -
1921 - LLVMPositionBuilderAtEnd(b, b_compare_result); -
1922 - -
1923 - /* if results equal, compare next, otherwise done */ -
1924 - LLVMBuildCondBr(b, -
1925 - LLVMBuildICmp(b, -
1926 - LLVMIntEQ, -
1927 - v_retval, -
1928 - l_datum_const(0), ""), -
1929 - opblocks[opno + 1], -
1930 - opblocks[op->d.rowcompare_step.jumpdone]); -
1931 - -
1932 - /* -
1933 - * Build block handling NULL input or NULL comparator -
1934 - * result. -
1935 - */ -
1936 - LLVMPositionBuilderAtEnd(b, b_null); -
1937 - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); -
1938 - LLVMBuildBr(b, opblocks[op->d.rowcompare_step.jumpnull]); -
1939 - -
1940 - break; -
1941 - } -
1942 - -
1943 - case EEOP_ROWCOMPARE_FINAL: -
1944 - { -
1945 - CompareType cmptype = op->d.rowcompare_final.cmptype; -
1946 - -
1947 - LLVMValueRef v_cmpresult; -
1948 - LLVMValueRef v_result; -
1949 - LLVMIntPredicate predicate; -
1950 - -
1951 - /* -
1952 - * Btree comparators return 32 bit results, need to be -
1953 - * careful about sign (used as a 64 bit value it's -
1954 - * otherwise wrong). -
1955 - */ -
1956 - v_cmpresult = -
1957 - LLVMBuildTrunc(b, -
1958 - l_load(b, TypeDatum, v_resvaluep, ""), -
1959 - LLVMInt32TypeInContext(lc), ""); -
1960 - -
1961 - switch (cmptype) -
1962 - { -
1963 - case COMPARE_LT: -
1964 - predicate = LLVMIntSLT; -
1965 - break; -
1966 - case COMPARE_LE: -
1967 - predicate = LLVMIntSLE; -
1968 - break; -
1969 - case COMPARE_GT: -
1970 - predicate = LLVMIntSGT; -
1971 - break; -
1972 - case COMPARE_GE: -
1973 - predicate = LLVMIntSGE; -
1974 - break; -
1975 - default: -
1976 - /* EQ and NE cases aren't allowed here */ -
1977 - Assert(false); -
1978 - predicate = 0; /* prevent compiler warning */ -
1979 - break; -
1980 - } -
1981 - -
1982 - v_result = LLVMBuildICmp(b, -
1983 - predicate, -
1984 - v_cmpresult, -
1985 - l_int32_const(lc, 0), -
1986 - ""); -
1987 - v_result = LLVMBuildZExt(b, v_result, TypeDatum, ""); -
1988 - -
1989 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
1990 - LLVMBuildStore(b, v_result, v_resvaluep); -
1991 - -
1992 - LLVMBuildBr(b, opblocks[opno + 1]); -
1993 - break; -
1994 - } -
1995 - -
1996 - case EEOP_MINMAX: -
1997 - build_EvalXFunc(b, mod, "ExecEvalMinMax", -
1998 - v_state, op); -
1999 - LLVMBuildBr(b, opblocks[opno + 1]); -
2000 - break; -
2001 - -
2002 - case EEOP_FIELDSELECT: -
2003 - build_EvalXFunc(b, mod, "ExecEvalFieldSelect", -
2004 - v_state, op, v_econtext); -
2005 - LLVMBuildBr(b, opblocks[opno + 1]); -
2006 - break; -
2007 - -
2008 - case EEOP_FIELDSTORE_DEFORM: -
2009 - build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm", -
2010 - v_state, op, v_econtext); -
2011 - LLVMBuildBr(b, opblocks[opno + 1]); -
2012 - break; -
2013 - -
2014 - case EEOP_FIELDSTORE_FORM: -
2015 - build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm", -
2016 - v_state, op, v_econtext); -
2017 - LLVMBuildBr(b, opblocks[opno + 1]); -
2018 - break; -
2019 - -
2020 - case EEOP_DOMAIN_TESTVAL: -
2021 - { -
2022 - LLVMValueRef v_casevaluep, -
2023 - v_casevalue; -
2024 - LLVMValueRef v_casenullp, -
2025 - v_casenull; -
2026 - -
2027 - v_casevaluep = l_ptr_const(op->d.casetest.value, -
2028 - l_ptr(TypeDatum)); -
2029 - v_casenullp = l_ptr_const(op->d.casetest.isnull, -
2030 - l_ptr(TypeStorageBool)); -
2031 - -
2032 - v_casevalue = l_load(b, TypeDatum, v_casevaluep, ""); -
2033 - v_casenull = l_load(b, TypeStorageBool, v_casenullp, ""); -
2034 - LLVMBuildStore(b, v_casevalue, v_resvaluep); -
2035 - LLVMBuildStore(b, v_casenull, v_resnullp); -
2036 - -
2037 - LLVMBuildBr(b, opblocks[opno + 1]); -
2038 - break; -
2039 - } -
2040 - -
2041 - case EEOP_DOMAIN_TESTVAL_EXT: -
2042 - { -
2043 - LLVMValueRef v_casevalue; -
2044 - LLVMValueRef v_casenull; -
2045 - -
2046 - v_casevalue = -
2047 - l_load_struct_gep(b, -
2048 - StructExprContext, -
2049 - v_econtext, -
2050 - FIELDNO_EXPRCONTEXT_DOMAINDATUM, -
2051 - ""); -
2052 - v_casenull = -
2053 - l_load_struct_gep(b, -
2054 - StructExprContext, -
2055 - v_econtext, -
2056 - FIELDNO_EXPRCONTEXT_DOMAINNULL, -
2057 - ""); -
2058 - LLVMBuildStore(b, v_casevalue, v_resvaluep); -
2059 - LLVMBuildStore(b, v_casenull, v_resnullp); -
2060 - -
2061 - LLVMBuildBr(b, opblocks[opno + 1]); -
2062 - break; -
2063 - } -
2064 - -
2065 - case EEOP_DOMAIN_NOTNULL: -
2066 - build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull", -
2067 - v_state, op); -
2068 - LLVMBuildBr(b, opblocks[opno + 1]); -
2069 - break; -
2070 - -
2071 - case EEOP_DOMAIN_CHECK: -
2072 - build_EvalXFunc(b, mod, "ExecEvalConstraintCheck", -
2073 - v_state, op); -
2074 - LLVMBuildBr(b, opblocks[opno + 1]); -
2075 - break; -
2076 - -
2077 - case EEOP_HASHDATUM_SET_INITVAL: -
2078 - { -
2079 - LLVMValueRef v_initvalue; -
2080 - -
2081 - v_initvalue = l_datum_const(op->d.hashdatum_initvalue.init_value); -
2082 - -
2083 - LLVMBuildStore(b, v_initvalue, v_resvaluep); -
2084 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
2085 - LLVMBuildBr(b, opblocks[opno + 1]); -
2086 - break; -
2087 - } -
2088 - -
2089 - case EEOP_HASHDATUM_FIRST: -
2090 - case EEOP_HASHDATUM_FIRST_STRICT: -
2091 - case EEOP_HASHDATUM_NEXT32: -
2092 - case EEOP_HASHDATUM_NEXT32_STRICT: -
2093 - { -
2094 - FunctionCallInfo fcinfo = op->d.hashdatum.fcinfo_data; -
2095 - LLVMValueRef v_fcinfo; -
2096 - LLVMValueRef v_fcinfo_isnull; -
2097 - LLVMValueRef v_retval; -
2098 - LLVMBasicBlockRef b_checkargnull; -
2099 - LLVMBasicBlockRef b_ifnotnull; -
2100 - LLVMBasicBlockRef b_ifnullblock; -
2101 - LLVMValueRef v_argisnull; -
2102 - LLVMValueRef v_prevhash = NULL; -
2103 - -
2104 - /* -
2105 - * When performing the next hash and not in strict mode we -
2106 - * perform a rotation of the previously stored hash value -
2107 - * before doing the NULL check. We want to do this even -
2108 - * when we receive a NULL Datum to hash. In strict mode, -
2109 - * we do this after the NULL check so as not to waste the -
2110 - * effort of rotating the bits when we're going to throw -
2111 - * away the hash value and return NULL. -
2112 - */ -
2113 - if (opcode == EEOP_HASHDATUM_NEXT32) -
2114 - { -
2115 - LLVMValueRef v_tmp1; -
2116 - LLVMValueRef v_tmp2; -
2117 - LLVMValueRef tmp; -
2118 - -
2119 - tmp = l_ptr_const(&op->d.hashdatum.iresult->value, -
2120 - l_ptr(TypeDatum)); -
2121 - -
2122 - /* -
2123 - * Fetch the previously hashed value from where the -
2124 - * previous hash operation stored it. -
2125 - */ -
2126 - v_prevhash = l_load(b, TypeDatum, tmp, "prevhash"); -
2127 - -
2128 - /* -
2129 - * Rotate bits left by 1 bit. Be careful not to -
2130 - * overflow uint32 when working with Datum. -
2131 - */ -
2132 - v_tmp1 = LLVMBuildShl(b, v_prevhash, l_datum_const(1), -
2133 - ""); -
2134 - v_tmp1 = LLVMBuildAnd(b, v_tmp1, -
2135 - l_datum_const(0xffffffff), ""); -
2136 - v_tmp2 = LLVMBuildLShr(b, v_prevhash, -
2137 - l_datum_const(31), ""); -
2138 - v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2, -
2139 - "rotatedhash"); -
2140 - } -
2141 - -
2142 - /* -
2143 - * Block for the actual function call, if args are -
2144 - * non-NULL. -
2145 - */ -
2146 - b_ifnotnull = l_bb_before_v(opblocks[opno + 1], -
2147 - "b.%d.ifnotnull", -
2148 - opno); -
2149 - -
2150 - /* we expect the hash function to have 1 argument */ -
2151 - if (fcinfo->nargs != 1) -
2152 - elog(ERROR, "incorrect number of function arguments"); -
2153 - -
2154 - v_fcinfo = l_ptr_const(fcinfo, -
2155 - l_ptr(StructFunctionCallInfoData)); -
2156 - -
2157 - b_checkargnull = l_bb_before_v(b_ifnotnull, -
2158 - "b.%d.isnull.0", opno); -
2159 - -
2160 - LLVMBuildBr(b, b_checkargnull); -
2161 - -
2162 - /* -
2163 - * Determine what to do if we find the argument to be -
2164 - * NULL. -
2165 - */ -
2166 - if (opcode == EEOP_HASHDATUM_FIRST_STRICT || -
2167 - opcode == EEOP_HASHDATUM_NEXT32_STRICT) -
2168 - { -
2169 - b_ifnullblock = l_bb_before_v(b_ifnotnull, -
2170 - "b.%d.strictnull", -
2171 - opno); -
2172 - -
2173 - LLVMPositionBuilderAtEnd(b, b_ifnullblock); -
2174 - -
2175 - /* -
2176 - * In strict node, NULL inputs result in NULL. Save -
2177 - * the NULL result and goto jumpdone. -
2178 - */ -
2179 - LLVMBuildStore(b, l_sbool_const(1), v_resnullp); -
2180 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
2181 - LLVMBuildBr(b, opblocks[op->d.hashdatum.jumpdone]); -
2182 - } -
2183 - else -
2184 - { -
2185 - b_ifnullblock = l_bb_before_v(b_ifnotnull, -
2186 - "b.%d.null", -
2187 - opno); -
2188 - -
2189 - LLVMPositionBuilderAtEnd(b, b_ifnullblock); -
2190 - -
2191 - -
2192 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
2193 - -
2194 - if (opcode == EEOP_HASHDATUM_NEXT32) -
2195 - { -
2196 - Assert(v_prevhash != NULL); -
2197 - -
2198 - /* -
2199 - * Save the rotated hash value and skip to the -
2200 - * next op. -
2201 - */ -
2202 - LLVMBuildStore(b, v_prevhash, v_resvaluep); -
2203 - } -
2204 - else -
2205 - { -
2206 - Assert(opcode == EEOP_HASHDATUM_FIRST); -
2207 - -
2208 - /* -
2209 - * Store a zero Datum when the Datum to hash is -
2210 - * NULL -
2211 - */ -
2212 - LLVMBuildStore(b, l_datum_const(0), v_resvaluep); -
2213 - } -
2214 - -
2215 - LLVMBuildBr(b, opblocks[opno + 1]); -
2216 - } -
2217 - -
2218 - LLVMPositionBuilderAtEnd(b, b_checkargnull); -
2219 - -
2220 - /* emit code to check if the input parameter is NULL */ -
2221 - v_argisnull = l_funcnull(b, v_fcinfo, 0); -
2222 - LLVMBuildCondBr(b, -
2223 - LLVMBuildICmp(b, -
2224 - LLVMIntEQ, -
2225 - v_argisnull, -
2226 - l_sbool_const(1), -
2227 - ""), -
2228 - b_ifnullblock, -
2229 - b_ifnotnull); -
2230 - -
2231 - LLVMPositionBuilderAtEnd(b, b_ifnotnull); -
2232 - -
2233 - /* -
2234 - * Rotate the previously stored hash value when performing -
2235 - * NEXT32 in strict mode. In non-strict mode we already -
2236 - * did this before checking for NULLs. -
2237 - */ -
2238 - if (opcode == EEOP_HASHDATUM_NEXT32_STRICT) -
2239 - { -
2240 - LLVMValueRef v_tmp1; -
2241 - LLVMValueRef v_tmp2; -
2242 - LLVMValueRef tmp; -
2243 - -
2244 - tmp = l_ptr_const(&op->d.hashdatum.iresult->value, -
2245 - l_ptr(TypeDatum)); -
2246 - -
2247 - /* -
2248 - * Fetch the previously hashed value from where the -
2249 - * previous hash operation stored it. -
2250 - */ -
2251 - v_prevhash = l_load(b, TypeDatum, tmp, "prevhash"); -
2252 - -
2253 - /* -
2254 - * Rotate bits left by 1 bit. Be careful not to -
2255 - * overflow uint32 when working with Datum. -
2256 - */ -
2257 - v_tmp1 = LLVMBuildShl(b, v_prevhash, l_datum_const(1), -
2258 - ""); -
2259 - v_tmp1 = LLVMBuildAnd(b, v_tmp1, -
2260 - l_datum_const(0xffffffff), ""); -
2261 - v_tmp2 = LLVMBuildLShr(b, v_prevhash, -
2262 - l_datum_const(31), ""); -
2263 - v_prevhash = LLVMBuildOr(b, v_tmp1, v_tmp2, -
2264 - "rotatedhash"); -
2265 - } -
2266 - -
2267 - /* call the hash function */ -
2268 - v_retval = BuildV1Call(context, b, mod, fcinfo, -
2269 - &v_fcinfo_isnull); -
2270 - -
2271 - /* -
2272 - * For NEXT32 ops, XOR (^) the returned hash value with -
2273 - * the existing hash value. -
2274 - */ -
2275 - if (opcode == EEOP_HASHDATUM_NEXT32 || -
2276 - opcode == EEOP_HASHDATUM_NEXT32_STRICT) -
2277 - v_retval = LLVMBuildXor(b, v_prevhash, v_retval, -
2278 - "xorhash"); -
2279 - -
2280 - LLVMBuildStore(b, v_retval, v_resvaluep); -
2281 - LLVMBuildStore(b, l_sbool_const(0), v_resnullp); -
2282 - -
2283 - LLVMBuildBr(b, opblocks[opno + 1]); -
2284 - break; -
2285 - } -
2286 - -
2287 - case EEOP_CONVERT_ROWTYPE: -
2288 - build_EvalXFunc(b, mod, "ExecEvalConvertRowtype", -
2289 - v_state, op, v_econtext); -
2290 - LLVMBuildBr(b, opblocks[opno + 1]); -
2291 - break; -
2292 - -
2293 - case EEOP_SCALARARRAYOP: -
2294 - build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp", -
2295 - v_state, op); -
2296 - LLVMBuildBr(b, opblocks[opno + 1]); -
2297 - break; -
2298 - -
2299 - case EEOP_HASHED_SCALARARRAYOP: -
2300 - build_EvalXFunc(b, mod, "ExecEvalHashedScalarArrayOp", -
2301 - v_state, op, v_econtext); -
2302 - LLVMBuildBr(b, opblocks[opno + 1]); -
2303 - break; -
2304 - -
2305 - case EEOP_XMLEXPR: -
2306 - build_EvalXFunc(b, mod, "ExecEvalXmlExpr", -
2307 - v_state, op); -
2308 - LLVMBuildBr(b, opblocks[opno + 1]); -
2309 - break; -
2310 - -
2311 - case EEOP_JSON_CONSTRUCTOR: -
2312 - build_EvalXFunc(b, mod, "ExecEvalJsonConstructor", -
2313 - v_state, op, v_econtext); -
2314 - LLVMBuildBr(b, opblocks[opno + 1]); -
2315 - break; -
2316 - -
2317 - case EEOP_IS_JSON: -
2318 - build_EvalXFunc(b, mod, "ExecEvalJsonIsPredicate", -
2319 - v_state, op); -
2320 - LLVMBuildBr(b, opblocks[opno + 1]); -
2321 - break; -
2322 - -
2323 - case EEOP_JSONEXPR_PATH: -
2324 - { -
2325 - JsonExprState *jsestate = op->d.jsonexpr.jsestate; -
2326 - LLVMValueRef v_ret; -
2327 - -
2328 - /* -
2329 - * Call ExecEvalJsonExprPath(). It returns the address of -
2330 - * the step to perform next. -
2331 - */ -
2332 - v_ret = build_EvalXFunc(b, mod, "ExecEvalJsonExprPath", -
2333 - v_state, op, v_econtext); -
2334 - -
2335 - /* -
2336 - * Build a switch to map the return value (v_ret above), -
2337 - * which is a runtime value of the step address to perform -
2338 - * next, to either jump_empty, jump_error, -
2339 - * jump_eval_coercion, or jump_end. -
2340 - */ -
2341 - if (jsestate->jump_empty >= 0 || -
2342 - jsestate->jump_error >= 0 || -
2343 - jsestate->jump_eval_coercion >= 0) -
2344 - { -
2345 - LLVMValueRef v_jump_empty; -
2346 - LLVMValueRef v_jump_error; -
2347 - LLVMValueRef v_jump_coercion; -
2348 - LLVMValueRef v_switch; -
2349 - LLVMBasicBlockRef b_done, -
2350 - b_empty, -
2351 - b_error, -
2352 - b_coercion; -
2353 - -
2354 - b_empty = -
2355 - l_bb_before_v(opblocks[opno + 1], -
2356 - "op.%d.jsonexpr_empty", opno); -
2357 - b_error = -
2358 - l_bb_before_v(opblocks[opno + 1], -
2359 - "op.%d.jsonexpr_error", opno); -
2360 - b_coercion = -
2361 - l_bb_before_v(opblocks[opno + 1], -
2362 - "op.%d.jsonexpr_coercion", opno); -
2363 - b_done = -
2364 - l_bb_before_v(opblocks[opno + 1], -
2365 - "op.%d.jsonexpr_done", opno); -
2366 - -
2367 - v_switch = LLVMBuildSwitch(b, -
2368 - v_ret, -
2369 - b_done, -
2370 - 3); -
2371 - /* Returned jsestate->jump_empty? */ -
2372 - if (jsestate->jump_empty >= 0) -
2373 - { -
2374 - v_jump_empty = l_int32_const(lc, jsestate->jump_empty); -
2375 - LLVMAddCase(v_switch, v_jump_empty, b_empty); -
2376 - } -
2377 - /* ON EMPTY code */ -
2378 - LLVMPositionBuilderAtEnd(b, b_empty); -
2379 - if (jsestate->jump_empty >= 0) -
2380 - LLVMBuildBr(b, opblocks[jsestate->jump_empty]); -
2381 - else -
2382 - LLVMBuildUnreachable(b); -
2383 - -
2384 - /* Returned jsestate->jump_error? */ -
2385 - if (jsestate->jump_error >= 0) -
2386 - { -
2387 - v_jump_error = l_int32_const(lc, jsestate->jump_error); -
2388 - LLVMAddCase(v_switch, v_jump_error, b_error); -
2389 - } -
2390 - /* ON ERROR code */ -
2391 - LLVMPositionBuilderAtEnd(b, b_error); -
2392 - if (jsestate->jump_error >= 0) -
2393 - LLVMBuildBr(b, opblocks[jsestate->jump_error]); -
2394 - else -
2395 - LLVMBuildUnreachable(b); -
2396 - -
2397 - /* Returned jsestate->jump_eval_coercion? */ -
2398 - if (jsestate->jump_eval_coercion >= 0) -
2399 - { -
2400 - v_jump_coercion = l_int32_const(lc, jsestate->jump_eval_coercion); -
2401 - LLVMAddCase(v_switch, v_jump_coercion, b_coercion); -
2402 - } -
2403 - /* jump_eval_coercion code */ -
2404 - LLVMPositionBuilderAtEnd(b, b_coercion); -
2405 - if (jsestate->jump_eval_coercion >= 0) -
2406 - LLVMBuildBr(b, opblocks[jsestate->jump_eval_coercion]); -
2407 - else -
2408 - LLVMBuildUnreachable(b); -
2409 - -
2410 - LLVMPositionBuilderAtEnd(b, b_done); -
2411 - } -
2412 - -
2413 - LLVMBuildBr(b, opblocks[jsestate->jump_end]); -
2414 - break; -
2415 - } -
2416 - -
2417 - case EEOP_JSONEXPR_COERCION: -
2418 - build_EvalXFunc(b, mod, "ExecEvalJsonCoercion", -
2419 - v_state, op, v_econtext); -
2420 - -
2421 - LLVMBuildBr(b, opblocks[opno + 1]); -
2422 - break; -
2423 - -
2424 - case EEOP_JSONEXPR_COERCION_FINISH: -
2425 - build_EvalXFunc(b, mod, "ExecEvalJsonCoercionFinish", -
2426 - v_state, op); -
2427 - -
2428 - LLVMBuildBr(b, opblocks[opno + 1]); -
2429 - break; -
2430 - -
2431 - case EEOP_AGGREF: -
2432 - { -
2433 - LLVMValueRef v_aggno; -
2434 - LLVMValueRef value, -
2435 - isnull; -
2436 - -
2437 - v_aggno = l_int32_const(lc, op->d.aggref.aggno); -
2438 - -
2439 - /* load agg value / null */ -
2440 - value = l_load_gep1(b, TypeDatum, v_aggvalues, v_aggno, "aggvalue"); -
2441 - isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull"); -
2442 - -
2443 - /* and store result */ -
2444 - LLVMBuildStore(b, value, v_resvaluep); -
2445 - LLVMBuildStore(b, isnull, v_resnullp); -
2446 - -
2447 - LLVMBuildBr(b, opblocks[opno + 1]); -
2448 - break; -
2449 - } -
2450 - -
2451 - case EEOP_GROUPING_FUNC: -
2452 - build_EvalXFunc(b, mod, "ExecEvalGroupingFunc", -
2453 - v_state, op); -
2454 - LLVMBuildBr(b, opblocks[opno + 1]); -
2455 - break; -
2456 - -
2457 - case EEOP_WINDOW_FUNC: -
2458 - { -
2459 - WindowFuncExprState *wfunc = op->d.window_func.wfstate; -
2460 - LLVMValueRef v_wfuncnop; -
2461 - LLVMValueRef v_wfuncno; -
2462 - LLVMValueRef value, -
2463 - isnull; -
2464 - -
2465 - /* -
2466 - * At this point aggref->wfuncno is not yet set (it's set -
2467 - * up in ExecInitWindowAgg() after initializing the -
2468 - * expression). So load it from memory each time round. -
2469 - */ -
2470 - v_wfuncnop = l_ptr_const(&wfunc->wfuncno, -
2471 - l_ptr(LLVMInt32TypeInContext(lc))); -
2472 - v_wfuncno = l_load(b, LLVMInt32TypeInContext(lc), v_wfuncnop, "v_wfuncno"); -
2473 - -
2474 - /* load window func value / null */ -
2475 - value = l_load_gep1(b, TypeDatum, v_aggvalues, v_wfuncno, -
2476 - "windowvalue"); -
2477 - isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_wfuncno, -
2478 - "windownull"); -
2479 - -
2480 - LLVMBuildStore(b, value, v_resvaluep); -
2481 - LLVMBuildStore(b, isnull, v_resnullp); -
2482 - -
2483 - LLVMBuildBr(b, opblocks[opno + 1]); -
2484 - break; -
2485 - } -
2486 - -
2487 - case EEOP_MERGE_SUPPORT_FUNC: -
2488 - build_EvalXFunc(b, mod, "ExecEvalMergeSupportFunc", -
2489 - v_state, op, v_econtext); -
2490 - LLVMBuildBr(b, opblocks[opno + 1]); -
2491 - break; -
2492 - -
2493 - case EEOP_SUBPLAN: -
2494 - build_EvalXFunc(b, mod, "ExecEvalSubPlan", -
2495 - v_state, op, v_econtext); -
2496 - LLVMBuildBr(b, opblocks[opno + 1]); -
2497 - break; -
2498 - -
2499 12 case EEOP_RPR_NAV_SET: 24cfb8dRow pattern recognition patch (executor and commands).
2500 12 build_EvalXFunc(b, mod, "ExecEvalRPRNavSet", 24cfb8dRow pattern recognition patch (executor and commands).
2501 - v_state, op, v_econtext); 24cfb8dRow pattern recognition patch (executor and commands).
2502 12 LLVMBuildBr(b, opblocks[opno + 1]); 24cfb8dRow pattern recognition patch (executor and commands).
2503 - break; 24cfb8dRow pattern recognition patch (executor and commands).
2504 - 24cfb8dRow pattern recognition patch (executor and commands).
2505 12 case EEOP_RPR_NAV_RESTORE: 24cfb8dRow pattern recognition patch (executor and commands).
2506 12 build_EvalXFunc(b, mod, "ExecEvalRPRNavRestore", 24cfb8dRow pattern recognition patch (executor and commands).
2507 - v_state, op, v_econtext); 24cfb8dRow pattern recognition patch (executor and commands).
2508 12 LLVMBuildBr(b, opblocks[opno + 1]); 24cfb8dRow pattern recognition patch (executor and commands).
2509 - break; 24cfb8dRow pattern recognition patch (executor and commands).
2510 - 24cfb8dRow pattern recognition patch (executor and commands).
2511 - case EEOP_AGG_STRICT_DESERIALIZE: -
2512 - case EEOP_AGG_DESERIALIZE: -
2513 - { -
2514 - AggState *aggstate; -
2515 - FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data; -
2516 - -
2517 - LLVMValueRef v_retval; -
2518 - LLVMValueRef v_fcinfo_isnull; -
2519 - LLVMValueRef v_tmpcontext; -
2520 - LLVMValueRef v_oldcontext; -
2521 - -
2522 - if (opcode == EEOP_AGG_STRICT_DESERIALIZE) -
2523 - { -
2524 - LLVMValueRef v_fcinfo; -
2525 - LLVMValueRef v_argnull0; -
2526 - LLVMBasicBlockRef b_deserialize; -
2527 - -
2528 - b_deserialize = l_bb_before_v(opblocks[opno + 1], -
2529 - "op.%d.deserialize", opno); -
2530 - -
2531 - v_fcinfo = l_ptr_const(fcinfo, -
2532 - l_ptr(StructFunctionCallInfoData)); -
2533 - v_argnull0 = l_funcnull(b, v_fcinfo, 0); -
2534 - -
2535 - LLVMBuildCondBr(b, -
2536 - LLVMBuildICmp(b, -
2537 - LLVMIntEQ, -
2538 - v_argnull0, -
2539 - l_sbool_const(1), -
2540 - ""), -
2541 - opblocks[op->d.agg_deserialize.jumpnull], -
2542 - b_deserialize); -
2543 - LLVMPositionBuilderAtEnd(b, b_deserialize); -
2544 - } -
2545 - -
2546 - aggstate = castNode(AggState, state->parent); -
2547 - fcinfo = op->d.agg_deserialize.fcinfo_data; -
2548 - -
2549 - v_tmpcontext = -
2550 - l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory, -
2551 - l_ptr(StructMemoryContextData)); -
2552 - v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext); -
2553 - v_retval = BuildV1Call(context, b, mod, fcinfo, -
2554 - &v_fcinfo_isnull); -
2555 - l_mcxt_switch(mod, b, v_oldcontext); -
2556 - -
2557 - LLVMBuildStore(b, v_retval, v_resvaluep); -
2558 - LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp); -
2559 - -
2560 - LLVMBuildBr(b, opblocks[opno + 1]); -
2561 - break; -
2562 - } -
2563 - -
2564 - case EEOP_AGG_STRICT_INPUT_CHECK_ARGS: -
2565 - case EEOP_AGG_STRICT_INPUT_CHECK_ARGS_1: -
2566 - case EEOP_AGG_STRICT_INPUT_CHECK_NULLS: -
2567 - { -
2568 - int nargs = op->d.agg_strict_input_check.nargs; -
2569 - NullableDatum *args = op->d.agg_strict_input_check.args; -
2570 - bool *nulls = op->d.agg_strict_input_check.nulls; -
2571 - int jumpnull; -
2572 - -
2573 - LLVMValueRef v_argsp; -
2574 - LLVMValueRef v_nullsp; -
2575 - LLVMBasicBlockRef *b_checknulls; -
2576 - -
2577 - Assert(nargs > 0); -
2578 - -
2579 - jumpnull = op->d.agg_strict_input_check.jumpnull; -
2580 - v_argsp = l_ptr_const(args, l_ptr(StructNullableDatum)); -
2581 - v_nullsp = l_ptr_const(nulls, l_ptr(TypeStorageBool)); -
2582 - -
2583 - /* create blocks for checking args */ -
2584 - b_checknulls = palloc_array(LLVMBasicBlockRef, nargs); -
2585 - for (int argno = 0; argno < nargs; argno++) -
2586 - { -
2587 - b_checknulls[argno] = -
2588 - l_bb_before_v(opblocks[opno + 1], -
2589 - "op.%d.check-null.%d", -
2590 - opno, argno); -
2591 - } -
2592 - -
2593 - LLVMBuildBr(b, b_checknulls[0]); -
2594 - -
2595 - /* strict function, check for NULL args */ -
2596 - for (int argno = 0; argno < nargs; argno++) -
2597 - { -
2598 - LLVMValueRef v_argno = l_int32_const(lc, argno); -
2599 - LLVMValueRef v_argisnull; -
2600 - LLVMBasicBlockRef b_argnotnull; -
2601 - -
2602 - LLVMPositionBuilderAtEnd(b, b_checknulls[argno]); -
2603 - -
2604 - if (argno + 1 == nargs) -
2605 - b_argnotnull = opblocks[opno + 1]; -
2606 - else -
2607 - b_argnotnull = b_checknulls[argno + 1]; -
2608 - -
2609 - if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS) -
2610 - v_argisnull = l_load_gep1(b, TypeStorageBool, v_nullsp, v_argno, ""); -
2611 - else -
2612 - { -
2613 - LLVMValueRef v_argn; -
2614 - -
2615 - v_argn = l_gep(b, StructNullableDatum, v_argsp, &v_argno, 1, ""); -
2616 - v_argisnull = -
2617 - l_load_struct_gep(b, StructNullableDatum, v_argn, -
2618 - FIELDNO_NULLABLE_DATUM_ISNULL, -
2619 - ""); -
2620 - } -
2621 - -
2622 - LLVMBuildCondBr(b, -
2623 - LLVMBuildICmp(b, -
2624 - LLVMIntEQ, -
2625 - v_argisnull, -
2626 - l_sbool_const(1), ""), -
2627 - opblocks[jumpnull], -
2628 - b_argnotnull); -
2629 - } -
2630 - -
2631 - break; -
2632 - } -
2633 - -
2634 - case EEOP_AGG_PLAIN_PERGROUP_NULLCHECK: -
2635 - { -
2636 - int jumpnull; -
2637 - LLVMValueRef v_aggstatep; -
2638 - LLVMValueRef v_allpergroupsp; -
2639 - LLVMValueRef v_pergroup_allaggs; -
2640 - LLVMValueRef v_setoff; -
2641 - -
2642 - jumpnull = op->d.agg_plain_pergroup_nullcheck.jumpnull; -
2643 - -
2644 - /* -
2645 - * pergroup_allaggs = aggstate->all_pergroups -
2646 - * [op->d.agg_plain_pergroup_nullcheck.setoff]; -
2647 - */ -
2648 - v_aggstatep = LLVMBuildBitCast(b, v_parent, -
2649 - l_ptr(StructAggState), ""); -
2650 - -
2651 - v_allpergroupsp = l_load_struct_gep(b, -
2652 - StructAggState, -
2653 - v_aggstatep, -
2654 - FIELDNO_AGGSTATE_ALL_PERGROUPS, -
2655 - "aggstate.all_pergroups"); -
2656 - -
2657 - v_setoff = l_int32_const(lc, op->d.agg_plain_pergroup_nullcheck.setoff); -
2658 - -
2659 - v_pergroup_allaggs = l_load_gep1(b, l_ptr(StructAggStatePerGroupData), -
2660 - v_allpergroupsp, v_setoff, ""); -
2661 - -
2662 - LLVMBuildCondBr(b, -
2663 - LLVMBuildICmp(b, LLVMIntEQ, -
2664 - LLVMBuildPtrToInt(b, v_pergroup_allaggs, TypeDatum, ""), -
2665 - l_datum_const(0), ""), -
2666 - opblocks[jumpnull], -
2667 - opblocks[opno + 1]); -
2668 - break; -
2669 - } -
2670 - -
2671 - case EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL: -
2672 - case EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL: -
2673 - case EEOP_AGG_PLAIN_TRANS_BYVAL: -
2674 - case EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF: -
2675 - case EEOP_AGG_PLAIN_TRANS_STRICT_BYREF: -
2676 - case EEOP_AGG_PLAIN_TRANS_BYREF: -
2677 - { -
2678 - AggState *aggstate; -
2679 - AggStatePerTrans pertrans; -
2680 - FunctionCallInfo fcinfo; -
2681 - -
2682 - LLVMValueRef v_aggstatep; -
2683 - LLVMValueRef v_fcinfo; -
2684 - LLVMValueRef v_fcinfo_isnull; -
2685 - -
2686 - LLVMValueRef v_transvaluep; -
2687 - LLVMValueRef v_transnullp; -
2688 - -
2689 - LLVMValueRef v_setoff; -
2690 - LLVMValueRef v_transno; -
2691 - -
2692 - LLVMValueRef v_aggcontext; -
2693 - -
2694 - LLVMValueRef v_allpergroupsp; -
2695 - LLVMValueRef v_current_setp; -
2696 - LLVMValueRef v_current_pertransp; -
2697 - LLVMValueRef v_curaggcontext; -
2698 - -
2699 - LLVMValueRef v_pertransp; -
2700 - -
2701 - LLVMValueRef v_pergroupp; -
2702 - -
2703 - LLVMValueRef v_retval; -
2704 - -
2705 - LLVMValueRef v_tmpcontext; -
2706 - LLVMValueRef v_oldcontext; -
2707 - -
2708 - aggstate = castNode(AggState, state->parent); -
2709 - pertrans = op->d.agg_trans.pertrans; -
2710 - -
2711 - fcinfo = pertrans->transfn_fcinfo; -
2712 - -
2713 - v_aggstatep = -
2714 - LLVMBuildBitCast(b, v_parent, l_ptr(StructAggState), ""); -
2715 - v_pertransp = l_ptr_const(pertrans, -
2716 - l_ptr(StructAggStatePerTransData)); -
2717 - -
2718 - /* -
2719 - * pergroup = &aggstate->all_pergroups -
2720 - * [op->d.agg_trans.setoff] [op->d.agg_trans.transno]; -
2721 - */ -
2722 - v_allpergroupsp = -
2723 - l_load_struct_gep(b, -
2724 - StructAggState, -
2725 - v_aggstatep, -
2726 - FIELDNO_AGGSTATE_ALL_PERGROUPS, -
2727 - "aggstate.all_pergroups"); -
2728 - v_setoff = l_int32_const(lc, op->d.agg_trans.setoff); -
2729 - v_transno = l_int32_const(lc, op->d.agg_trans.transno); -
2730 - v_pergroupp = -
2731 - l_gep(b, -
2732 - StructAggStatePerGroupData, -
2733 - l_load_gep1(b, l_ptr(StructAggStatePerGroupData), -
2734 - v_allpergroupsp, v_setoff, ""), -
2735 - &v_transno, 1, ""); -
2736 - -
2737 - -
2738 - if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL || -
2739 - opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF) -
2740 - { -
2741 - LLVMValueRef v_notransvalue; -
2742 - LLVMBasicBlockRef b_init; -
2743 - LLVMBasicBlockRef b_no_init; -
2744 - -
2745 - v_notransvalue = -
2746 - l_load_struct_gep(b, -
2747 - StructAggStatePerGroupData, -
2748 - v_pergroupp, -
2749 - FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE, -
2750 - "notransvalue"); -
2751 - -
2752 - b_init = l_bb_before_v(opblocks[opno + 1], -
2753 - "op.%d.inittrans", opno); -
2754 - b_no_init = l_bb_before_v(opblocks[opno + 1], -
2755 - "op.%d.no_inittrans", opno); -
2756 - -
2757 - LLVMBuildCondBr(b, -
2758 - LLVMBuildICmp(b, LLVMIntEQ, v_notransvalue, -
2759 - l_sbool_const(1), ""), -
2760 - b_init, -
2761 - b_no_init); -
2762 - -
2763 - /* block to init the transition value if necessary */ -
2764 - { -
2765 - LLVMValueRef params[4]; -
2766 - -
2767 - LLVMPositionBuilderAtEnd(b, b_init); -
2768 - -
2769 - v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext, -
2770 - l_ptr(StructExprContext)); -
2771 - -
2772 - params[0] = v_aggstatep; -
2773 - params[1] = v_pertransp; -
2774 - params[2] = v_pergroupp; -
2775 - params[3] = v_aggcontext; -
2776 - -
2777 - l_call(b, -
2778 - llvm_pg_var_func_type("ExecAggInitGroup"), -
2779 - llvm_pg_func(mod, "ExecAggInitGroup"), -
2780 - params, lengthof(params), -
2781 - ""); -
2782 - -
2783 - LLVMBuildBr(b, opblocks[opno + 1]); -
2784 - } -
2785 - -
2786 - LLVMPositionBuilderAtEnd(b, b_no_init); -
2787 - } -
2788 - -
2789 - if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYVAL || -
2790 - opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF || -
2791 - opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYVAL || -
2792 - opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYREF) -
2793 - { -
2794 - LLVMValueRef v_transnull; -
2795 - LLVMBasicBlockRef b_strictpass; -
2796 - -
2797 - b_strictpass = l_bb_before_v(opblocks[opno + 1], -
2798 - "op.%d.strictpass", opno); -
2799 - v_transnull = -
2800 - l_load_struct_gep(b, -
2801 - StructAggStatePerGroupData, -
2802 - v_pergroupp, -
2803 - FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL, -
2804 - "transnull"); -
2805 - -
2806 - LLVMBuildCondBr(b, -
2807 - LLVMBuildICmp(b, LLVMIntEQ, v_transnull, -
2808 - l_sbool_const(1), ""), -
2809 - opblocks[opno + 1], -
2810 - b_strictpass); -
2811 - -
2812 - LLVMPositionBuilderAtEnd(b, b_strictpass); -
2813 - } -
2814 - -
2815 - -
2816 - v_fcinfo = l_ptr_const(fcinfo, -
2817 - l_ptr(StructFunctionCallInfoData)); -
2818 - v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext, -
2819 - l_ptr(StructExprContext)); -
2820 - -
2821 - v_current_setp = -
2822 - l_struct_gep(b, -
2823 - StructAggState, -
2824 - v_aggstatep, -
2825 - FIELDNO_AGGSTATE_CURRENT_SET, -
2826 - "aggstate.current_set"); -
2827 - v_curaggcontext = -
2828 - l_struct_gep(b, -
2829 - StructAggState, -
2830 - v_aggstatep, -
2831 - FIELDNO_AGGSTATE_CURAGGCONTEXT, -
2832 - "aggstate.curaggcontext"); -
2833 - v_current_pertransp = -
2834 - l_struct_gep(b, -
2835 - StructAggState, -
2836 - v_aggstatep, -
2837 - FIELDNO_AGGSTATE_CURPERTRANS, -
2838 - "aggstate.curpertrans"); -
2839 - -
2840 - /* set aggstate globals */ -
2841 - LLVMBuildStore(b, v_aggcontext, v_curaggcontext); -
2842 - LLVMBuildStore(b, l_int32_const(lc, op->d.agg_trans.setno), -
2843 - v_current_setp); -
2844 - LLVMBuildStore(b, v_pertransp, v_current_pertransp); -
2845 - -
2846 - /* invoke transition function in per-tuple context */ -
2847 - v_tmpcontext = -
2848 - l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory, -
2849 - l_ptr(StructMemoryContextData)); -
2850 - v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext); -
2851 - -
2852 - /* store transvalue in fcinfo->args[0] */ -
2853 - v_transvaluep = -
2854 - l_struct_gep(b, -
2855 - StructAggStatePerGroupData, -
2856 - v_pergroupp, -
2857 - FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE, -
2858 - "transvalue"); -
2859 - v_transnullp = -
2860 - l_struct_gep(b, -
2861 - StructAggStatePerGroupData, -
2862 - v_pergroupp, -
2863 - FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL, -
2864 - "transnullp"); -
2865 - LLVMBuildStore(b, -
2866 - l_load(b, -
2867 - TypeDatum, -
2868 - v_transvaluep, -
2869 - "transvalue"), -
2870 - l_funcvaluep(b, v_fcinfo, 0)); -
2871 - LLVMBuildStore(b, -
2872 - l_load(b, TypeStorageBool, v_transnullp, "transnull"), -
2873 - l_funcnullp(b, v_fcinfo, 0)); -
2874 - -
2875 - /* and invoke transition function */ -
2876 - v_retval = BuildV1Call(context, b, mod, fcinfo, -
2877 - &v_fcinfo_isnull); -
2878 - -
2879 - /* -
2880 - * For pass-by-ref datatype, must copy the new value into -
2881 - * aggcontext and free the prior transValue. But if -
2882 - * transfn returned a pointer to its first input, we don't -
2883 - * need to do anything. Also, if transfn returned a -
2884 - * pointer to a R/W expanded object that is already a -
2885 - * child of the aggcontext, assume we can adopt that value -
2886 - * without copying it. -
2887 - */ -
2888 - if (opcode == EEOP_AGG_PLAIN_TRANS_INIT_STRICT_BYREF || -
2889 - opcode == EEOP_AGG_PLAIN_TRANS_STRICT_BYREF || -
2890 - opcode == EEOP_AGG_PLAIN_TRANS_BYREF) -
2891 - { -
2892 - LLVMBasicBlockRef b_call; -
2893 - LLVMBasicBlockRef b_nocall; -
2894 - LLVMValueRef v_fn; -
2895 - LLVMValueRef v_transvalue; -
2896 - LLVMValueRef v_transnull; -
2897 - LLVMValueRef v_newval; -
2898 - LLVMValueRef params[6]; -
2899 - -
2900 - b_call = l_bb_before_v(opblocks[opno + 1], -
2901 - "op.%d.transcall", opno); -
2902 - b_nocall = l_bb_before_v(opblocks[opno + 1], -
2903 - "op.%d.transnocall", opno); -
2904 - -
2905 - v_transvalue = l_load(b, TypeDatum, v_transvaluep, ""); -
2906 - v_transnull = l_load(b, TypeStorageBool, v_transnullp, ""); -
2907 - -
2908 - /* -
2909 - * DatumGetPointer(newVal) != -
2910 - * DatumGetPointer(pergroup->transValue)) -
2911 - */ -
2912 - LLVMBuildCondBr(b, -
2913 - LLVMBuildICmp(b, LLVMIntEQ, -
2914 - v_transvalue, -
2915 - v_retval, ""), -
2916 - b_nocall, b_call); -
2917 - -
2918 - /* returned datum not passed datum, reparent */ -
2919 - LLVMPositionBuilderAtEnd(b, b_call); -
2920 - -
2921 - params[0] = v_aggstatep; -
2922 - params[1] = v_pertransp; -
2923 - params[2] = v_retval; -
2924 - params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull, -
2925 - TypeParamBool, ""); -
2926 - params[4] = v_transvalue; -
2927 - params[5] = LLVMBuildTrunc(b, v_transnull, -
2928 - TypeParamBool, ""); -
2929 - -
2930 - v_fn = llvm_pg_func(mod, "ExecAggCopyTransValue"); -
2931 - v_newval = -
2932 - l_call(b, -
2933 - LLVMGetFunctionType(v_fn), -
2934 - v_fn, -
2935 - params, lengthof(params), -
2936 - ""); -
2937 - -
2938 - /* store trans value */ -
2939 - LLVMBuildStore(b, v_newval, v_transvaluep); -
2940 - LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp); -
2941 - -
2942 - l_mcxt_switch(mod, b, v_oldcontext); -
2943 - LLVMBuildBr(b, opblocks[opno + 1]); -
2944 - -
2945 - /* returned datum passed datum, no need to reparent */ -
2946 - LLVMPositionBuilderAtEnd(b, b_nocall); -
2947 - } -
2948 - -
2949 - /* store trans value */ -
2950 - LLVMBuildStore(b, v_retval, v_transvaluep); -
2951 - LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp); -
2952 - -
2953 - l_mcxt_switch(mod, b, v_oldcontext); -
2954 - -
2955 - LLVMBuildBr(b, opblocks[opno + 1]); -
2956 - break; -
2957 - } -
2958 - -
2959 - case EEOP_AGG_PRESORTED_DISTINCT_SINGLE: -
2960 - { -
2961 - AggState *aggstate = castNode(AggState, state->parent); -
2962 - AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans; -
2963 - int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct; -
2964 - -
2965 - LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctSingle"); -
2966 - LLVMValueRef v_args[2]; -
2967 - LLVMValueRef v_ret; -
2968 - -
2969 - v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState)); -
2970 - v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData)); -
2971 - -
2972 - v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, ""); -
2973 - v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); -
2974 - -
2975 - LLVMBuildCondBr(b, -
2976 - LLVMBuildICmp(b, LLVMIntEQ, v_ret, -
2977 - l_sbool_const(1), ""), -
2978 - opblocks[opno + 1], -
2979 - opblocks[jumpdistinct]); -
2980 - break; -
2981 - } -
2982 - -
2983 - case EEOP_AGG_PRESORTED_DISTINCT_MULTI: -
2984 - { -
2985 - AggState *aggstate = castNode(AggState, state->parent); -
2986 - AggStatePerTrans pertrans = op->d.agg_presorted_distinctcheck.pertrans; -
2987 - int jumpdistinct = op->d.agg_presorted_distinctcheck.jumpdistinct; -
2988 - -
2989 - LLVMValueRef v_fn = llvm_pg_func(mod, "ExecEvalPreOrderedDistinctMulti"); -
2990 - LLVMValueRef v_args[2]; -
2991 - LLVMValueRef v_ret; -
2992 - -
2993 - v_args[0] = l_ptr_const(aggstate, l_ptr(StructAggState)); -
2994 - v_args[1] = l_ptr_const(pertrans, l_ptr(StructAggStatePerTransData)); -
2995 - -
2996 - v_ret = l_call(b, LLVMGetFunctionType(v_fn), v_fn, v_args, 2, ""); -
2997 - v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); -
2998 - -
2999 - LLVMBuildCondBr(b, -
3000 - LLVMBuildICmp(b, LLVMIntEQ, v_ret, -
3001 - l_sbool_const(1), ""), -
3002 - opblocks[opno + 1], -
3003 - opblocks[jumpdistinct]); -
3004 - break; -
3005 - } -
3006 - -
3007 - case EEOP_AGG_ORDERED_TRANS_DATUM: -
3008 - build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum", -
3009 - v_state, op, v_econtext); -
3010 - LLVMBuildBr(b, opblocks[opno + 1]); -
3011 - break; -
3012 - -
3013 - case EEOP_AGG_ORDERED_TRANS_TUPLE: -
3014 - build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple", -
3015 - v_state, op, v_econtext); -
3016 - LLVMBuildBr(b, opblocks[opno + 1]); -
3017 - break; -
3018 - -
3019 - case EEOP_LAST: -
3020 - Assert(false); -
3021 - break; -
3022 - } -
3023 - } -
3024 - -
3025 - LLVMDisposeBuilder(b); -
3026 - -
3027 - /* -
3028 - * Don't immediately emit function, instead do so the first time the -
3029 - * expression is actually evaluated. That allows to emit a lot of -
3030 - * functions together, avoiding a lot of repeated llvm and memory -
3031 - * remapping overhead. -
3032 - */ -
3033 - { -
3034 - -
3035 - CompiledExprState *cstate = palloc0_object(CompiledExprState); -
3036 - -
3037 - cstate->context = context; -
3038 - cstate->funcname = funcname; -
3039 - -
3040 - state->evalfunc = ExecRunCompiledExpr; -
3041 - state->evalfunc_private = cstate; -
3042 - } -
3043 - -
3044 - llvm_leave_fatal_on_oom(); -
3045 - -
3046 - INSTR_TIME_SET_CURRENT(endtime); -
3047 - INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter, -
3048 - endtime, starttime); -
3049 - -
3050 - return true; -
3051 - } -