1 /*-------------------------------------------------------------------------
2  *
3  * llvmjit_expr.c
4  *	  JIT compile expressions.
5  *
6  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/backend/jit/llvm/llvmjit_expr.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "postgres.h"
17 
18 #include <llvm-c/Core.h>
19 #include <llvm-c/Target.h>
20 
21 #include "access/htup_details.h"
22 #include "access/nbtree.h"
23 #include "access/tupconvert.h"
24 #include "catalog/objectaccess.h"
25 #include "catalog/pg_type.h"
26 #include "executor/execdebug.h"
27 #include "executor/nodeAgg.h"
28 #include "executor/nodeSubplan.h"
29 #include "executor/execExpr.h"
30 #include "funcapi.h"
31 #include "jit/llvmjit.h"
32 #include "jit/llvmjit_emit.h"
33 #include "miscadmin.h"
34 #include "nodes/makefuncs.h"
35 #include "nodes/nodeFuncs.h"
36 #include "optimizer/planner.h"
37 #include "parser/parse_coerce.h"
38 #include "parser/parsetree.h"
39 #include "pgstat.h"
40 #include "utils/acl.h"
41 #include "utils/builtins.h"
42 #include "utils/date.h"
43 #include "utils/fmgrtab.h"
44 #include "utils/lsyscache.h"
45 #include "utils/memutils.h"
46 #include "utils/timestamp.h"
47 #include "utils/typcache.h"
48 #include "utils/xml.h"
49 
50 
51 typedef struct CompiledExprState
52 {
53 	LLVMJitContext *context;
54 	const char *funcname;
55 } CompiledExprState;
56 
57 
58 static Datum ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull);
59 
60 static LLVMValueRef BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
61 			LLVMModuleRef mod, FunctionCallInfo fcinfo,
62 			LLVMValueRef *v_fcinfo_isnull);
63 static void build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod,
64 				const char *funcname,
65 				LLVMValueRef v_state, LLVMValueRef v_econtext,
66 				ExprEvalStep *op);
67 static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod);
68 
69 
70 /*
71  * JIT compile expression.
72  */
73 bool
llvm_compile_expr(ExprState * state)74 llvm_compile_expr(ExprState *state)
75 {
76 	PlanState  *parent = state->parent;
77 	int			i;
78 	char	   *funcname;
79 
80 	LLVMJitContext *context = NULL;
81 
82 	LLVMBuilderRef b;
83 	LLVMModuleRef mod;
84 	LLVMTypeRef eval_sig;
85 	LLVMValueRef eval_fn;
86 	LLVMBasicBlockRef entry;
87 	LLVMBasicBlockRef *opblocks;
88 
89 	/* state itself */
90 	LLVMValueRef v_state;
91 	LLVMValueRef v_econtext;
92 
93 	/* returnvalue */
94 	LLVMValueRef v_isnullp;
95 
96 	/* tmp vars in state */
97 	LLVMValueRef v_tmpvaluep;
98 	LLVMValueRef v_tmpisnullp;
99 
100 	/* slots */
101 	LLVMValueRef v_innerslot;
102 	LLVMValueRef v_outerslot;
103 	LLVMValueRef v_scanslot;
104 	LLVMValueRef v_resultslot;
105 
106 	/* nulls/values of slots */
107 	LLVMValueRef v_innervalues;
108 	LLVMValueRef v_innernulls;
109 	LLVMValueRef v_outervalues;
110 	LLVMValueRef v_outernulls;
111 	LLVMValueRef v_scanvalues;
112 	LLVMValueRef v_scannulls;
113 	LLVMValueRef v_resultvalues;
114 	LLVMValueRef v_resultnulls;
115 
116 	/* stuff in econtext */
117 	LLVMValueRef v_aggvalues;
118 	LLVMValueRef v_aggnulls;
119 
120 	instr_time	starttime;
121 	instr_time	endtime;
122 
123 	llvm_enter_fatal_on_oom();
124 
125 	/* get or create JIT context */
126 	if (parent && parent->state->es_jit)
127 	{
128 		context = (LLVMJitContext *) parent->state->es_jit;
129 	}
130 	else
131 	{
132 		context = llvm_create_context(parent->state->es_jit_flags);
133 
134 		if (parent)
135 		{
136 			parent->state->es_jit = &context->base;
137 		}
138 
139 	}
140 
141 	INSTR_TIME_SET_CURRENT(starttime);
142 
143 	mod = llvm_mutable_module(context);
144 
145 	b = LLVMCreateBuilder();
146 
147 	funcname = llvm_expand_funcname(context, "evalexpr");
148 
149 	/* Create the signature and function */
150 	{
151 		LLVMTypeRef param_types[3];
152 
153 		param_types[0] = l_ptr(StructExprState);	/* state */
154 		param_types[1] = l_ptr(StructExprContext);	/* econtext */
155 		param_types[2] = l_ptr(TypeStorageBool);	/* isnull */
156 
157 		eval_sig = LLVMFunctionType(TypeSizeT,
158 									param_types, lengthof(param_types),
159 									false);
160 	}
161 	eval_fn = LLVMAddFunction(mod, funcname, eval_sig);
162 	LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
163 	LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
164 	llvm_copy_attributes(AttributeTemplate, eval_fn);
165 
166 	entry = LLVMAppendBasicBlock(eval_fn, "entry");
167 
168 	/* build state */
169 	v_state = LLVMGetParam(eval_fn, 0);
170 	v_econtext = LLVMGetParam(eval_fn, 1);
171 	v_isnullp = LLVMGetParam(eval_fn, 2);
172 
173 	LLVMPositionBuilderAtEnd(b, entry);
174 
175 	v_tmpvaluep = LLVMBuildStructGEP(b, v_state,
176 									 FIELDNO_EXPRSTATE_RESVALUE,
177 									 "v.state.resvalue");
178 	v_tmpisnullp = LLVMBuildStructGEP(b, v_state,
179 									  FIELDNO_EXPRSTATE_RESNULL,
180 									  "v.state.resnull");
181 
182 	/* build global slots */
183 	v_scanslot = l_load_struct_gep(b, v_econtext,
184 								   FIELDNO_EXPRCONTEXT_SCANTUPLE,
185 								   "v_scanslot");
186 	v_innerslot = l_load_struct_gep(b, v_econtext,
187 									FIELDNO_EXPRCONTEXT_INNERTUPLE,
188 									"v_innerslot");
189 	v_outerslot = l_load_struct_gep(b, v_econtext,
190 									FIELDNO_EXPRCONTEXT_OUTERTUPLE,
191 									"v_outerslot");
192 	v_resultslot = l_load_struct_gep(b, v_state,
193 									 FIELDNO_EXPRSTATE_RESULTSLOT,
194 									 "v_resultslot");
195 
196 	/* build global values/isnull pointers */
197 	v_scanvalues = l_load_struct_gep(b, v_scanslot,
198 									 FIELDNO_TUPLETABLESLOT_VALUES,
199 									 "v_scanvalues");
200 	v_scannulls = l_load_struct_gep(b, v_scanslot,
201 									FIELDNO_TUPLETABLESLOT_ISNULL,
202 									"v_scannulls");
203 	v_innervalues = l_load_struct_gep(b, v_innerslot,
204 									  FIELDNO_TUPLETABLESLOT_VALUES,
205 									  "v_innervalues");
206 	v_innernulls = l_load_struct_gep(b, v_innerslot,
207 									 FIELDNO_TUPLETABLESLOT_ISNULL,
208 									 "v_innernulls");
209 	v_outervalues = l_load_struct_gep(b, v_outerslot,
210 									  FIELDNO_TUPLETABLESLOT_VALUES,
211 									  "v_outervalues");
212 	v_outernulls = l_load_struct_gep(b, v_outerslot,
213 									 FIELDNO_TUPLETABLESLOT_ISNULL,
214 									 "v_outernulls");
215 	v_resultvalues = l_load_struct_gep(b, v_resultslot,
216 									   FIELDNO_TUPLETABLESLOT_VALUES,
217 									   "v_resultvalues");
218 	v_resultnulls = l_load_struct_gep(b, v_resultslot,
219 									  FIELDNO_TUPLETABLESLOT_ISNULL,
220 									  "v_resultnulls");
221 
222 	/* aggvalues/aggnulls */
223 	v_aggvalues = l_load_struct_gep(b, v_econtext,
224 									FIELDNO_EXPRCONTEXT_AGGVALUES,
225 									"v.econtext.aggvalues");
226 	v_aggnulls = l_load_struct_gep(b, v_econtext,
227 								   FIELDNO_EXPRCONTEXT_AGGNULLS,
228 								   "v.econtext.aggnulls");
229 
230 	/* allocate blocks for each op upfront, so we can do jumps easily */
231 	opblocks = palloc(sizeof(LLVMBasicBlockRef) * state->steps_len);
232 	for (i = 0; i < state->steps_len; i++)
233 		opblocks[i] = l_bb_append_v(eval_fn, "b.op.%d.start", i);
234 
235 	/* jump from entry to first block */
236 	LLVMBuildBr(b, opblocks[0]);
237 
238 	for (i = 0; i < state->steps_len; i++)
239 	{
240 		ExprEvalStep *op;
241 		ExprEvalOp	opcode;
242 		LLVMValueRef v_resvaluep;
243 		LLVMValueRef v_resnullp;
244 
245 		LLVMPositionBuilderAtEnd(b, opblocks[i]);
246 
247 		op = &state->steps[i];
248 		opcode = ExecEvalStepOp(state, op);
249 
250 		v_resvaluep = l_ptr_const(op->resvalue, l_ptr(TypeSizeT));
251 		v_resnullp = l_ptr_const(op->resnull, l_ptr(TypeStorageBool));
252 
253 		switch (opcode)
254 		{
255 			case EEOP_DONE:
256 				{
257 					LLVMValueRef v_tmpisnull,
258 								v_tmpvalue;
259 
260 					v_tmpvalue = LLVMBuildLoad(b, v_tmpvaluep, "");
261 					v_tmpisnull = LLVMBuildLoad(b, v_tmpisnullp, "");
262 
263 					LLVMBuildStore(b, v_tmpisnull, v_isnullp);
264 
265 					LLVMBuildRet(b, v_tmpvalue);
266 					break;
267 				}
268 
269 			case EEOP_INNER_FETCHSOME:
270 			case EEOP_OUTER_FETCHSOME:
271 			case EEOP_SCAN_FETCHSOME:
272 				{
273 					TupleDesc	desc = NULL;
274 					LLVMValueRef v_slot;
275 					LLVMBasicBlockRef b_fetch;
276 					LLVMValueRef v_nvalid;
277 
278 					b_fetch = l_bb_before_v(opblocks[i + 1],
279 											"op.%d.fetch", i);
280 
281 					if (op->d.fetch.known_desc)
282 						desc = op->d.fetch.known_desc;
283 
284 					if (opcode == EEOP_INNER_FETCHSOME)
285 					{
286 						PlanState  *is = innerPlanState(parent);
287 
288 						v_slot = v_innerslot;
289 
290 						if (!desc &&
291 							is &&
292 							is->ps_ResultTupleSlot &&
293 							is->ps_ResultTupleSlot->tts_fixedTupleDescriptor)
294 							desc = is->ps_ResultTupleSlot->tts_tupleDescriptor;
295 					}
296 					else if (opcode == EEOP_OUTER_FETCHSOME)
297 					{
298 						PlanState  *os = outerPlanState(parent);
299 
300 						v_slot = v_outerslot;
301 
302 						if (!desc &&
303 							os &&
304 							os->ps_ResultTupleSlot &&
305 							os->ps_ResultTupleSlot->tts_fixedTupleDescriptor)
306 							desc = os->ps_ResultTupleSlot->tts_tupleDescriptor;
307 					}
308 					else
309 					{
310 						v_slot = v_scanslot;
311 						if (!desc && parent)
312 							desc = parent->scandesc;
313 					}
314 
315 					/*
316 					 * Check if all required attributes are available, or
317 					 * whether deforming is required.
318 					 */
319 					v_nvalid =
320 						l_load_struct_gep(b, v_slot,
321 										  FIELDNO_TUPLETABLESLOT_NVALID,
322 										  "");
323 					LLVMBuildCondBr(b,
324 									LLVMBuildICmp(b, LLVMIntUGE, v_nvalid,
325 												  l_int32_const(op->d.fetch.last_var),
326 												  ""),
327 									opblocks[i + 1], b_fetch);
328 
329 					LLVMPositionBuilderAtEnd(b, b_fetch);
330 
331 					/*
332 					 * If the tupledesc of the to-be-deformed tuple is known,
333 					 * and JITing of deforming is enabled, build deform
334 					 * function specific to tupledesc and the exact number of
335 					 * to-be-extracted attributes.
336 					 */
337 					if (desc && (context->base.flags & PGJIT_DEFORM))
338 					{
339 						LLVMValueRef params[1];
340 						LLVMValueRef l_jit_deform;
341 
342 						l_jit_deform =
343 							slot_compile_deform(context, desc,
344 												op->d.fetch.last_var);
345 						params[0] = v_slot;
346 
347 						LLVMBuildCall(b, l_jit_deform,
348 									  params, lengthof(params), "");
349 
350 					}
351 					else
352 					{
353 						LLVMValueRef params[2];
354 
355 						params[0] = v_slot;
356 						params[1] = l_int32_const(op->d.fetch.last_var);
357 
358 						LLVMBuildCall(b,
359 									  llvm_get_decl(mod, FuncSlotGetsomeattrs),
360 									  params, lengthof(params), "");
361 					}
362 
363 					LLVMBuildBr(b, opblocks[i + 1]);
364 					break;
365 				}
366 
367 			case EEOP_INNER_VAR:
368 			case EEOP_OUTER_VAR:
369 			case EEOP_SCAN_VAR:
370 				{
371 					LLVMValueRef value,
372 								isnull;
373 					LLVMValueRef v_attnum;
374 					LLVMValueRef v_values;
375 					LLVMValueRef v_nulls;
376 
377 					if (opcode == EEOP_INNER_VAR)
378 					{
379 						v_values = v_innervalues;
380 						v_nulls = v_innernulls;
381 					}
382 					else if (opcode == EEOP_OUTER_VAR)
383 					{
384 						v_values = v_outervalues;
385 						v_nulls = v_outernulls;
386 					}
387 					else
388 					{
389 						v_values = v_scanvalues;
390 						v_nulls = v_scannulls;
391 					}
392 
393 					v_attnum = l_int32_const(op->d.var.attnum);
394 					value = l_load_gep1(b, v_values, v_attnum, "");
395 					isnull = l_load_gep1(b, v_nulls, v_attnum, "");
396 					LLVMBuildStore(b, value, v_resvaluep);
397 					LLVMBuildStore(b, isnull, v_resnullp);
398 
399 					LLVMBuildBr(b, opblocks[i + 1]);
400 					break;
401 				}
402 
403 			case EEOP_INNER_SYSVAR:
404 			case EEOP_OUTER_SYSVAR:
405 			case EEOP_SCAN_SYSVAR:
406 				{
407 					int			attnum = op->d.var.attnum;
408 					LLVMValueRef v_attnum;
409 					LLVMValueRef v_tuple;
410 					LLVMValueRef v_tupleDescriptor;
411 					LLVMValueRef v_params[4];
412 					LLVMValueRef v_syscol;
413 					LLVMValueRef v_slot;
414 
415 					if (opcode == EEOP_INNER_SYSVAR)
416 						v_slot = v_innerslot;
417 					else if (opcode == EEOP_OUTER_SYSVAR)
418 						v_slot = v_outerslot;
419 					else
420 						v_slot = v_scanslot;
421 
422 					Assert(op->d.var.attnum < 0);
423 
424 					v_tuple = l_load_struct_gep(b, v_slot,
425 												FIELDNO_TUPLETABLESLOT_TUPLE,
426 												"v.tuple");
427 
428 					/*
429 					 * Could optimize this a bit for fixed descriptors, but
430 					 * this shouldn't be that critical a path.
431 					 */
432 					v_tupleDescriptor =
433 						l_load_struct_gep(b, v_slot,
434 										  FIELDNO_TUPLETABLESLOT_TUPLEDESCRIPTOR,
435 										  "v.tupledesc");
436 					v_attnum = l_int32_const(attnum);
437 
438 					v_params[0] = v_tuple;
439 					v_params[1] = v_attnum;
440 					v_params[2] = v_tupleDescriptor;
441 					v_params[3] = v_resnullp;
442 					v_syscol = LLVMBuildCall(b,
443 											 llvm_get_decl(mod, FuncHeapGetsysattr),
444 											 v_params, lengthof(v_params),
445 											 "");
446 					LLVMBuildStore(b, v_syscol, v_resvaluep);
447 
448 					LLVMBuildBr(b, opblocks[i + 1]);
449 					break;
450 				}
451 
452 			case EEOP_WHOLEROW:
453 				build_EvalXFunc(b, mod, "ExecEvalWholeRowVar",
454 								v_state, v_econtext, op);
455 				LLVMBuildBr(b, opblocks[i + 1]);
456 				break;
457 
458 			case EEOP_ASSIGN_INNER_VAR:
459 			case EEOP_ASSIGN_OUTER_VAR:
460 			case EEOP_ASSIGN_SCAN_VAR:
461 				{
462 					LLVMValueRef v_value,
463 								v_isnull;
464 					LLVMValueRef v_rvaluep,
465 								v_risnullp;
466 					LLVMValueRef v_attnum,
467 								v_resultnum;
468 					LLVMValueRef v_values;
469 					LLVMValueRef v_nulls;
470 
471 					if (opcode == EEOP_ASSIGN_INNER_VAR)
472 					{
473 						v_values = v_innervalues;
474 						v_nulls = v_innernulls;
475 					}
476 					else if (opcode == EEOP_ASSIGN_OUTER_VAR)
477 					{
478 						v_values = v_outervalues;
479 						v_nulls = v_outernulls;
480 					}
481 					else
482 					{
483 						v_values = v_scanvalues;
484 						v_nulls = v_scannulls;
485 					}
486 
487 					/* load data */
488 					v_attnum = l_int32_const(op->d.assign_var.attnum);
489 					v_value = l_load_gep1(b, v_values, v_attnum, "");
490 					v_isnull = l_load_gep1(b, v_nulls, v_attnum, "");
491 
492 					/* compute addresses of targets */
493 					v_resultnum = l_int32_const(op->d.assign_var.resultnum);
494 					v_rvaluep = LLVMBuildGEP(b, v_resultvalues,
495 											 &v_resultnum, 1, "");
496 					v_risnullp = LLVMBuildGEP(b, v_resultnulls,
497 											  &v_resultnum, 1, "");
498 
499 					/* and store */
500 					LLVMBuildStore(b, v_value, v_rvaluep);
501 					LLVMBuildStore(b, v_isnull, v_risnullp);
502 
503 					LLVMBuildBr(b, opblocks[i + 1]);
504 					break;
505 				}
506 
507 			case EEOP_ASSIGN_TMP:
508 				{
509 					LLVMValueRef v_value,
510 								v_isnull;
511 					LLVMValueRef v_rvaluep,
512 								v_risnullp;
513 					LLVMValueRef v_resultnum;
514 					size_t		resultnum = op->d.assign_tmp.resultnum;
515 
516 					/* load data */
517 					v_value = LLVMBuildLoad(b, v_tmpvaluep, "");
518 					v_isnull = LLVMBuildLoad(b, v_tmpisnullp, "");
519 
520 					/* compute addresses of targets */
521 					v_resultnum = l_int32_const(resultnum);
522 					v_rvaluep =
523 						LLVMBuildGEP(b, v_resultvalues, &v_resultnum, 1, "");
524 					v_risnullp =
525 						LLVMBuildGEP(b, v_resultnulls, &v_resultnum, 1, "");
526 
527 					/* and store */
528 					LLVMBuildStore(b, v_value, v_rvaluep);
529 					LLVMBuildStore(b, v_isnull, v_risnullp);
530 
531 					LLVMBuildBr(b, opblocks[i + 1]);
532 					break;
533 				}
534 
535 			case EEOP_ASSIGN_TMP_MAKE_RO:
536 				{
537 					LLVMBasicBlockRef b_notnull;
538 					LLVMValueRef v_params[1];
539 					LLVMValueRef v_ret;
540 					LLVMValueRef v_value,
541 								v_isnull;
542 					LLVMValueRef v_rvaluep,
543 								v_risnullp;
544 					LLVMValueRef v_resultnum;
545 					size_t		resultnum = op->d.assign_tmp.resultnum;
546 
547 					b_notnull = l_bb_before_v(opblocks[i + 1],
548 											  "op.%d.assign_tmp.notnull", i);
549 
550 					/* load data */
551 					v_value = LLVMBuildLoad(b, v_tmpvaluep, "");
552 					v_isnull = LLVMBuildLoad(b, v_tmpisnullp, "");
553 
554 					/* compute addresses of targets */
555 					v_resultnum = l_int32_const(resultnum);
556 					v_rvaluep = LLVMBuildGEP(b, v_resultvalues,
557 											 &v_resultnum, 1, "");
558 					v_risnullp = LLVMBuildGEP(b, v_resultnulls,
559 											  &v_resultnum, 1, "");
560 
561 					/* store nullness */
562 					LLVMBuildStore(b, v_isnull, v_risnullp);
563 
564 					/* check if value is NULL */
565 					LLVMBuildCondBr(b,
566 									LLVMBuildICmp(b, LLVMIntEQ, v_isnull,
567 												  l_sbool_const(0), ""),
568 									b_notnull, opblocks[i + 1]);
569 
570 					/* if value is not null, convert to RO datum */
571 					LLVMPositionBuilderAtEnd(b, b_notnull);
572 					v_params[0] = v_value;
573 					v_ret =
574 						LLVMBuildCall(b,
575 									  llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal),
576 									  v_params, lengthof(v_params), "");
577 
578 					/* store value */
579 					LLVMBuildStore(b, v_ret, v_rvaluep);
580 
581 					LLVMBuildBr(b, opblocks[i + 1]);
582 					break;
583 				}
584 
585 			case EEOP_CONST:
586 				{
587 					LLVMValueRef v_constvalue,
588 								v_constnull;
589 
590 					v_constvalue = l_sizet_const(op->d.constval.value);
591 					v_constnull = l_sbool_const(op->d.constval.isnull);
592 
593 					LLVMBuildStore(b, v_constvalue, v_resvaluep);
594 					LLVMBuildStore(b, v_constnull, v_resnullp);
595 
596 					LLVMBuildBr(b, opblocks[i + 1]);
597 					break;
598 				}
599 
600 			case EEOP_FUNCEXPR_STRICT:
601 				{
602 					FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
603 					LLVMBasicBlockRef b_nonull;
604 					int			argno;
605 					LLVMValueRef v_fcinfo;
606 					LLVMValueRef v_argnullp;
607 					LLVMBasicBlockRef *b_checkargnulls;
608 
609 					/*
610 					 * Block for the actual function call, if args are
611 					 * non-NULL.
612 					 */
613 					b_nonull = l_bb_before_v(opblocks[i + 1],
614 											 "b.%d.no-null-args", i);
615 
616 					/* should make sure they're optimized beforehand */
617 					if (op->d.func.nargs == 0)
618 						elog(ERROR, "argumentless strict functions are pointless");
619 
620 					v_fcinfo =
621 						l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
622 
623 					v_argnullp =
624 						LLVMBuildStructGEP(b,
625 										   v_fcinfo,
626 										   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
627 										   "v_argnullp");
628 
629 					/*
630 					 * set resnull to true, if the function is actually
631 					 * called, it'll be reset
632 					 */
633 					LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
634 
635 					/* create blocks for checking args, one for each */
636 					b_checkargnulls =
637 						palloc(sizeof(LLVMBasicBlockRef *) * op->d.func.nargs);
638 					for (argno = 0; argno < op->d.func.nargs; argno++)
639 						b_checkargnulls[argno] =
640 							l_bb_before_v(b_nonull, "b.%d.isnull.%d", i, argno);
641 
642 					/* jump to check of first argument */
643 					LLVMBuildBr(b, b_checkargnulls[0]);
644 
645 					/* check each arg for NULLness */
646 					for (argno = 0; argno < op->d.func.nargs; argno++)
647 					{
648 						LLVMValueRef v_argisnull;
649 						LLVMBasicBlockRef b_argnotnull;
650 
651 						LLVMPositionBuilderAtEnd(b, b_checkargnulls[argno]);
652 
653 						/* compute block to jump to if argument is not null */
654 						if (argno + 1 == op->d.func.nargs)
655 							b_argnotnull = b_nonull;
656 						else
657 							b_argnotnull = b_checkargnulls[argno + 1];
658 
659 						/* and finally load & check NULLness of arg */
660 						v_argisnull = l_load_struct_gep(b, v_argnullp,
661 														argno, "");
662 						LLVMBuildCondBr(b,
663 										LLVMBuildICmp(b, LLVMIntEQ,
664 													  v_argisnull,
665 													  l_sbool_const(1),
666 													  ""),
667 										opblocks[i + 1],
668 										b_argnotnull);
669 					}
670 
671 					LLVMPositionBuilderAtEnd(b, b_nonull);
672 				}
673 				/* FALLTHROUGH */
674 
675 			case EEOP_FUNCEXPR:
676 				{
677 					FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
678 					LLVMValueRef v_fcinfo_isnull;
679 					LLVMValueRef v_retval;
680 
681 					v_retval = BuildV1Call(context, b, mod, fcinfo,
682 										   &v_fcinfo_isnull);
683 					LLVMBuildStore(b, v_retval, v_resvaluep);
684 					LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
685 
686 					LLVMBuildBr(b, opblocks[i + 1]);
687 					break;
688 				}
689 
690 			case EEOP_FUNCEXPR_FUSAGE:
691 				build_EvalXFunc(b, mod, "ExecEvalFuncExprFusage",
692 								v_state, v_econtext, op);
693 				LLVMBuildBr(b, opblocks[i + 1]);
694 				break;
695 
696 
697 			case EEOP_FUNCEXPR_STRICT_FUSAGE:
698 				build_EvalXFunc(b, mod, "ExecEvalFuncExprStrictFusage",
699 								v_state, v_econtext, op);
700 				LLVMBuildBr(b, opblocks[i + 1]);
701 				break;
702 
703 			case EEOP_BOOL_AND_STEP_FIRST:
704 				{
705 					LLVMValueRef v_boolanynullp;
706 
707 					v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
708 												 l_ptr(TypeStorageBool));
709 					LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
710 
711 				}
712 				/* FALLTHROUGH */
713 
714 				/*
715 				 * Treat them the same for now, optimizer can remove
716 				 * redundancy. Could be worthwhile to optimize during emission
717 				 * though.
718 				 */
719 			case EEOP_BOOL_AND_STEP_LAST:
720 			case EEOP_BOOL_AND_STEP:
721 				{
722 					LLVMValueRef v_boolvalue;
723 					LLVMValueRef v_boolnull;
724 					LLVMValueRef v_boolanynullp,
725 								v_boolanynull;
726 					LLVMBasicBlockRef b_boolisnull;
727 					LLVMBasicBlockRef b_boolcheckfalse;
728 					LLVMBasicBlockRef b_boolisfalse;
729 					LLVMBasicBlockRef b_boolcont;
730 					LLVMBasicBlockRef b_boolisanynull;
731 
732 					b_boolisnull = l_bb_before_v(opblocks[i + 1],
733 												 "b.%d.boolisnull", i);
734 					b_boolcheckfalse = l_bb_before_v(opblocks[i + 1],
735 													 "b.%d.boolcheckfalse", i);
736 					b_boolisfalse = l_bb_before_v(opblocks[i + 1],
737 												  "b.%d.boolisfalse", i);
738 					b_boolisanynull = l_bb_before_v(opblocks[i + 1],
739 													"b.%d.boolisanynull", i);
740 					b_boolcont = l_bb_before_v(opblocks[i + 1],
741 											   "b.%d.boolcont", i);
742 
743 					v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
744 												 l_ptr(TypeStorageBool));
745 
746 					v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
747 					v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
748 
749 					/* set resnull to boolnull */
750 					LLVMBuildStore(b, v_boolnull, v_resnullp);
751 					/* set revalue to boolvalue */
752 					LLVMBuildStore(b, v_boolvalue, v_resvaluep);
753 
754 					/* check if current input is NULL */
755 					LLVMBuildCondBr(b,
756 									LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
757 												  l_sbool_const(1), ""),
758 									b_boolisnull,
759 									b_boolcheckfalse);
760 
761 					/* build block that sets anynull */
762 					LLVMPositionBuilderAtEnd(b, b_boolisnull);
763 					/* set boolanynull to true */
764 					LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
765 					/* and jump to next block */
766 					LLVMBuildBr(b, b_boolcont);
767 
768 					/* build block checking for false */
769 					LLVMPositionBuilderAtEnd(b, b_boolcheckfalse);
770 					LLVMBuildCondBr(b,
771 									LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
772 												  l_sizet_const(0), ""),
773 									b_boolisfalse,
774 									b_boolcont);
775 
776 					/*
777 					 * Build block handling FALSE. Value is false, so short
778 					 * circuit.
779 					 */
780 					LLVMPositionBuilderAtEnd(b, b_boolisfalse);
781 					/* result is already set to FALSE, need not change it */
782 					/* and jump to the end of the AND expression */
783 					LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]);
784 
785 					/* Build block that continues if bool is TRUE. */
786 					LLVMPositionBuilderAtEnd(b, b_boolcont);
787 
788 					v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, "");
789 
790 					/* set value to NULL if any previous values were NULL */
791 					LLVMBuildCondBr(b,
792 									LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
793 												  l_sbool_const(0), ""),
794 									opblocks[i + 1], b_boolisanynull);
795 
796 					LLVMPositionBuilderAtEnd(b, b_boolisanynull);
797 					/* set resnull to true */
798 					LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
799 					/* reset resvalue */
800 					LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
801 
802 					LLVMBuildBr(b, opblocks[i + 1]);
803 					break;
804 				}
805 			case EEOP_BOOL_OR_STEP_FIRST:
806 				{
807 					LLVMValueRef v_boolanynullp;
808 
809 					v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
810 												 l_ptr(TypeStorageBool));
811 					LLVMBuildStore(b, l_sbool_const(0), v_boolanynullp);
812 				}
813 				/* FALLTHROUGH */
814 
815 				/*
816 				 * Treat them the same for now, optimizer can remove
817 				 * redundancy. Could be worthwhile to optimize during emission
818 				 * though.
819 				 */
820 			case EEOP_BOOL_OR_STEP_LAST:
821 			case EEOP_BOOL_OR_STEP:
822 				{
823 					LLVMValueRef v_boolvalue;
824 					LLVMValueRef v_boolnull;
825 					LLVMValueRef v_boolanynullp,
826 								v_boolanynull;
827 
828 					LLVMBasicBlockRef b_boolisnull;
829 					LLVMBasicBlockRef b_boolchecktrue;
830 					LLVMBasicBlockRef b_boolistrue;
831 					LLVMBasicBlockRef b_boolcont;
832 					LLVMBasicBlockRef b_boolisanynull;
833 
834 					b_boolisnull = l_bb_before_v(opblocks[i + 1],
835 												 "b.%d.boolisnull", i);
836 					b_boolchecktrue = l_bb_before_v(opblocks[i + 1],
837 													"b.%d.boolchecktrue", i);
838 					b_boolistrue = l_bb_before_v(opblocks[i + 1],
839 												 "b.%d.boolistrue", i);
840 					b_boolisanynull = l_bb_before_v(opblocks[i + 1],
841 													"b.%d.boolisanynull", i);
842 					b_boolcont = l_bb_before_v(opblocks[i + 1],
843 											   "b.%d.boolcont", i);
844 
845 					v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
846 												 l_ptr(TypeStorageBool));
847 
848 					v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
849 					v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
850 
851 					/* set resnull to boolnull */
852 					LLVMBuildStore(b, v_boolnull, v_resnullp);
853 					/* set revalue to boolvalue */
854 					LLVMBuildStore(b, v_boolvalue, v_resvaluep);
855 
856 					LLVMBuildCondBr(b,
857 									LLVMBuildICmp(b, LLVMIntEQ, v_boolnull,
858 												  l_sbool_const(1), ""),
859 									b_boolisnull,
860 									b_boolchecktrue);
861 
862 					/* build block that sets anynull */
863 					LLVMPositionBuilderAtEnd(b, b_boolisnull);
864 					/* set boolanynull to true */
865 					LLVMBuildStore(b, l_sbool_const(1), v_boolanynullp);
866 					/* and jump to next block */
867 					LLVMBuildBr(b, b_boolcont);
868 
869 					/* build block checking for true */
870 					LLVMPositionBuilderAtEnd(b, b_boolchecktrue);
871 					LLVMBuildCondBr(b,
872 									LLVMBuildICmp(b, LLVMIntEQ, v_boolvalue,
873 												  l_sizet_const(1), ""),
874 									b_boolistrue,
875 									b_boolcont);
876 
877 					/*
878 					 * Build block handling True. Value is true, so short
879 					 * circuit.
880 					 */
881 					LLVMPositionBuilderAtEnd(b, b_boolistrue);
882 					/* result is already set to TRUE, need not change it */
883 					/* and jump to the end of the OR expression */
884 					LLVMBuildBr(b, opblocks[op->d.boolexpr.jumpdone]);
885 
886 					/* build block that continues if bool is FALSE */
887 					LLVMPositionBuilderAtEnd(b, b_boolcont);
888 
889 					v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, "");
890 
891 					/* set value to NULL if any previous values were NULL */
892 					LLVMBuildCondBr(b,
893 									LLVMBuildICmp(b, LLVMIntEQ, v_boolanynull,
894 												  l_sbool_const(0), ""),
895 									opblocks[i + 1], b_boolisanynull);
896 
897 					LLVMPositionBuilderAtEnd(b, b_boolisanynull);
898 					/* set resnull to true */
899 					LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
900 					/* reset resvalue */
901 					LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
902 
903 					LLVMBuildBr(b, opblocks[i + 1]);
904 					break;
905 				}
906 
907 			case EEOP_BOOL_NOT_STEP:
908 				{
909 					LLVMValueRef v_boolvalue;
910 					LLVMValueRef v_boolnull;
911 					LLVMValueRef v_negbool;
912 
913 					v_boolnull = LLVMBuildLoad(b, v_resnullp, "");
914 					v_boolvalue = LLVMBuildLoad(b, v_resvaluep, "");
915 
916 					v_negbool = LLVMBuildZExt(b,
917 											  LLVMBuildICmp(b, LLVMIntEQ,
918 															v_boolvalue,
919 															l_sizet_const(0),
920 															""),
921 											  TypeSizeT, "");
922 					/* set resnull to boolnull */
923 					LLVMBuildStore(b, v_boolnull, v_resnullp);
924 					/* set revalue to !boolvalue */
925 					LLVMBuildStore(b, v_negbool, v_resvaluep);
926 
927 					LLVMBuildBr(b, opblocks[i + 1]);
928 					break;
929 				}
930 
931 			case EEOP_QUAL:
932 				{
933 					LLVMValueRef v_resnull;
934 					LLVMValueRef v_resvalue;
935 					LLVMValueRef v_nullorfalse;
936 					LLVMBasicBlockRef b_qualfail;
937 
938 					b_qualfail = l_bb_before_v(opblocks[i + 1],
939 											   "op.%d.qualfail", i);
940 
941 					v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
942 					v_resnull = LLVMBuildLoad(b, v_resnullp, "");
943 
944 					v_nullorfalse =
945 						LLVMBuildOr(b,
946 									LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
947 												  l_sbool_const(1), ""),
948 									LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
949 												  l_sizet_const(0), ""),
950 									"");
951 
952 					LLVMBuildCondBr(b,
953 									v_nullorfalse,
954 									b_qualfail,
955 									opblocks[i + 1]);
956 
957 					/* build block handling NULL or false */
958 					LLVMPositionBuilderAtEnd(b, b_qualfail);
959 					/* set resnull to false */
960 					LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
961 					/* set resvalue to false */
962 					LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
963 					/* and jump out */
964 					LLVMBuildBr(b, opblocks[op->d.qualexpr.jumpdone]);
965 					break;
966 				}
967 
968 			case EEOP_JUMP:
969 				{
970 					LLVMBuildBr(b, opblocks[op->d.jump.jumpdone]);
971 					break;
972 				}
973 
974 			case EEOP_JUMP_IF_NULL:
975 				{
976 					LLVMValueRef v_resnull;
977 
978 					/* Transfer control if current result is null */
979 
980 					v_resnull = LLVMBuildLoad(b, v_resnullp, "");
981 
982 					LLVMBuildCondBr(b,
983 									LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
984 												  l_sbool_const(1), ""),
985 									opblocks[op->d.jump.jumpdone],
986 									opblocks[i + 1]);
987 					break;
988 				}
989 
990 			case EEOP_JUMP_IF_NOT_NULL:
991 				{
992 					LLVMValueRef v_resnull;
993 
994 					/* Transfer control if current result is non-null */
995 
996 					v_resnull = LLVMBuildLoad(b, v_resnullp, "");
997 
998 					LLVMBuildCondBr(b,
999 									LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
1000 												  l_sbool_const(0), ""),
1001 									opblocks[op->d.jump.jumpdone],
1002 									opblocks[i + 1]);
1003 					break;
1004 				}
1005 
1006 
1007 			case EEOP_JUMP_IF_NOT_TRUE:
1008 				{
1009 					LLVMValueRef v_resnull;
1010 					LLVMValueRef v_resvalue;
1011 					LLVMValueRef v_nullorfalse;
1012 
1013 					/* Transfer control if current result is null or false */
1014 
1015 					v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
1016 					v_resnull = LLVMBuildLoad(b, v_resnullp, "");
1017 
1018 					v_nullorfalse =
1019 						LLVMBuildOr(b,
1020 									LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
1021 												  l_sbool_const(1), ""),
1022 									LLVMBuildICmp(b, LLVMIntEQ, v_resvalue,
1023 												  l_sizet_const(0), ""),
1024 									"");
1025 
1026 					LLVMBuildCondBr(b,
1027 									v_nullorfalse,
1028 									opblocks[op->d.jump.jumpdone],
1029 									opblocks[i + 1]);
1030 					break;
1031 				}
1032 
1033 			case EEOP_NULLTEST_ISNULL:
1034 				{
1035 					LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
1036 					LLVMValueRef v_resvalue;
1037 
1038 					v_resvalue =
1039 						LLVMBuildSelect(b,
1040 										LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
1041 													  l_sbool_const(1), ""),
1042 										l_sizet_const(1),
1043 										l_sizet_const(0),
1044 										"");
1045 					LLVMBuildStore(b, v_resvalue, v_resvaluep);
1046 					LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
1047 
1048 					LLVMBuildBr(b, opblocks[i + 1]);
1049 					break;
1050 				}
1051 
1052 			case EEOP_NULLTEST_ISNOTNULL:
1053 				{
1054 					LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
1055 					LLVMValueRef v_resvalue;
1056 
1057 					v_resvalue =
1058 						LLVMBuildSelect(b,
1059 										LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
1060 													  l_sbool_const(1), ""),
1061 										l_sizet_const(0),
1062 										l_sizet_const(1),
1063 										"");
1064 					LLVMBuildStore(b, v_resvalue, v_resvaluep);
1065 					LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
1066 
1067 					LLVMBuildBr(b, opblocks[i + 1]);
1068 					break;
1069 				}
1070 
1071 			case EEOP_NULLTEST_ROWISNULL:
1072 				build_EvalXFunc(b, mod, "ExecEvalRowNull",
1073 								v_state, v_econtext, op);
1074 				LLVMBuildBr(b, opblocks[i + 1]);
1075 				break;
1076 
1077 			case EEOP_NULLTEST_ROWISNOTNULL:
1078 				build_EvalXFunc(b, mod, "ExecEvalRowNotNull",
1079 								v_state, v_econtext, op);
1080 				LLVMBuildBr(b, opblocks[i + 1]);
1081 				break;
1082 
1083 			case EEOP_BOOLTEST_IS_TRUE:
1084 			case EEOP_BOOLTEST_IS_NOT_FALSE:
1085 			case EEOP_BOOLTEST_IS_FALSE:
1086 			case EEOP_BOOLTEST_IS_NOT_TRUE:
1087 				{
1088 					LLVMBasicBlockRef b_isnull,
1089 								b_notnull;
1090 					LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, "");
1091 
1092 					b_isnull = l_bb_before_v(opblocks[i + 1],
1093 											 "op.%d.isnull", i);
1094 					b_notnull = l_bb_before_v(opblocks[i + 1],
1095 											  "op.%d.isnotnull", i);
1096 
1097 					/* check if value is NULL */
1098 					LLVMBuildCondBr(b,
1099 									LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
1100 												  l_sbool_const(1), ""),
1101 									b_isnull, b_notnull);
1102 
1103 					/* if value is NULL, return false */
1104 					LLVMPositionBuilderAtEnd(b, b_isnull);
1105 
1106 					/* result is not null */
1107 					LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
1108 
1109 					if (opcode == EEOP_BOOLTEST_IS_TRUE ||
1110 						opcode == EEOP_BOOLTEST_IS_FALSE)
1111 					{
1112 						LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
1113 					}
1114 					else
1115 					{
1116 						LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
1117 					}
1118 
1119 					LLVMBuildBr(b, opblocks[i + 1]);
1120 
1121 					LLVMPositionBuilderAtEnd(b, b_notnull);
1122 
1123 					if (opcode == EEOP_BOOLTEST_IS_TRUE ||
1124 						opcode == EEOP_BOOLTEST_IS_NOT_FALSE)
1125 					{
1126 						/*
1127 						 * if value is not null NULL, return value (already
1128 						 * set)
1129 						 */
1130 					}
1131 					else
1132 					{
1133 						LLVMValueRef v_value =
1134 						LLVMBuildLoad(b, v_resvaluep, "");
1135 
1136 						v_value = LLVMBuildZExt(b,
1137 												LLVMBuildICmp(b, LLVMIntEQ,
1138 															  v_value,
1139 															  l_sizet_const(0),
1140 															  ""),
1141 												TypeSizeT, "");
1142 						LLVMBuildStore(b, v_value, v_resvaluep);
1143 					}
1144 					LLVMBuildBr(b, opblocks[i + 1]);
1145 					break;
1146 				}
1147 
1148 			case EEOP_PARAM_EXEC:
1149 				build_EvalXFunc(b, mod, "ExecEvalParamExec",
1150 								v_state, v_econtext, op);
1151 				LLVMBuildBr(b, opblocks[i + 1]);
1152 				break;
1153 
1154 			case EEOP_PARAM_EXTERN:
1155 				build_EvalXFunc(b, mod, "ExecEvalParamExtern",
1156 								v_state, v_econtext, op);
1157 				LLVMBuildBr(b, opblocks[i + 1]);
1158 				break;
1159 
1160 			case EEOP_PARAM_CALLBACK:
1161 				{
1162 					LLVMTypeRef param_types[3];
1163 					LLVMValueRef v_params[3];
1164 					LLVMTypeRef v_functype;
1165 					LLVMValueRef v_func;
1166 
1167 					param_types[0] = l_ptr(StructExprState);
1168 					param_types[1] = l_ptr(TypeSizeT);
1169 					param_types[2] = l_ptr(StructExprContext);
1170 
1171 					v_functype = LLVMFunctionType(LLVMVoidType(),
1172 												  param_types,
1173 												  lengthof(param_types),
1174 												  false);
1175 					v_func = l_ptr_const(op->d.cparam.paramfunc,
1176 										 l_ptr(v_functype));
1177 
1178 					v_params[0] = v_state;
1179 					v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT));
1180 					v_params[2] = v_econtext;
1181 					LLVMBuildCall(b,
1182 								  v_func,
1183 								  v_params, lengthof(v_params), "");
1184 
1185 					LLVMBuildBr(b, opblocks[i + 1]);
1186 					break;
1187 				}
1188 
1189 			case EEOP_ARRAYREF_OLD:
1190 				build_EvalXFunc(b, mod, "ExecEvalArrayRefOld",
1191 								v_state, v_econtext, op);
1192 				LLVMBuildBr(b, opblocks[i + 1]);
1193 				break;
1194 
1195 			case EEOP_ARRAYREF_ASSIGN:
1196 				build_EvalXFunc(b, mod, "ExecEvalArrayRefAssign",
1197 								v_state, v_econtext, op);
1198 				LLVMBuildBr(b, opblocks[i + 1]);
1199 				break;
1200 
1201 			case EEOP_ARRAYREF_FETCH:
1202 				build_EvalXFunc(b, mod, "ExecEvalArrayRefFetch",
1203 								v_state, v_econtext, op);
1204 				LLVMBuildBr(b, opblocks[i + 1]);
1205 				break;
1206 
1207 			case EEOP_CASE_TESTVAL:
1208 				{
1209 					LLVMBasicBlockRef b_avail,
1210 								b_notavail;
1211 					LLVMValueRef v_casevaluep,
1212 								v_casevalue;
1213 					LLVMValueRef v_casenullp,
1214 								v_casenull;
1215 					LLVMValueRef v_casevaluenull;
1216 
1217 					b_avail = l_bb_before_v(opblocks[i + 1],
1218 											"op.%d.avail", i);
1219 					b_notavail = l_bb_before_v(opblocks[i + 1],
1220 											   "op.%d.notavail", i);
1221 
1222 					v_casevaluep = l_ptr_const(op->d.casetest.value,
1223 											   l_ptr(TypeSizeT));
1224 					v_casenullp = l_ptr_const(op->d.casetest.isnull,
1225 											  l_ptr(TypeStorageBool));
1226 
1227 					v_casevaluenull =
1228 						LLVMBuildICmp(b, LLVMIntEQ,
1229 									  LLVMBuildPtrToInt(b, v_casevaluep,
1230 														TypeSizeT, ""),
1231 									  l_sizet_const(0), "");
1232 					LLVMBuildCondBr(b, v_casevaluenull, b_notavail, b_avail);
1233 
1234 					/* if casetest != NULL */
1235 					LLVMPositionBuilderAtEnd(b, b_avail);
1236 					v_casevalue = LLVMBuildLoad(b, v_casevaluep, "");
1237 					v_casenull = LLVMBuildLoad(b, v_casenullp, "");
1238 					LLVMBuildStore(b, v_casevalue, v_resvaluep);
1239 					LLVMBuildStore(b, v_casenull, v_resnullp);
1240 					LLVMBuildBr(b, opblocks[i + 1]);
1241 
1242 					/* if casetest == NULL */
1243 					LLVMPositionBuilderAtEnd(b, b_notavail);
1244 					v_casevalue =
1245 						l_load_struct_gep(b, v_econtext,
1246 										  FIELDNO_EXPRCONTEXT_CASEDATUM, "");
1247 					v_casenull =
1248 						l_load_struct_gep(b, v_econtext,
1249 										  FIELDNO_EXPRCONTEXT_CASENULL, "");
1250 					LLVMBuildStore(b, v_casevalue, v_resvaluep);
1251 					LLVMBuildStore(b, v_casenull, v_resnullp);
1252 
1253 					LLVMBuildBr(b, opblocks[i + 1]);
1254 					break;
1255 				}
1256 
1257 			case EEOP_MAKE_READONLY:
1258 				{
1259 					LLVMBasicBlockRef b_notnull;
1260 					LLVMValueRef v_params[1];
1261 					LLVMValueRef v_ret;
1262 					LLVMValueRef v_nullp;
1263 					LLVMValueRef v_valuep;
1264 					LLVMValueRef v_null;
1265 					LLVMValueRef v_value;
1266 
1267 					b_notnull = l_bb_before_v(opblocks[i + 1],
1268 											  "op.%d.readonly.notnull", i);
1269 
1270 					v_nullp = l_ptr_const(op->d.make_readonly.isnull,
1271 										  l_ptr(TypeStorageBool));
1272 
1273 					v_null = LLVMBuildLoad(b, v_nullp, "");
1274 
1275 					/* store null isnull value in result */
1276 					LLVMBuildStore(b, v_null, v_resnullp);
1277 
1278 					/* check if value is NULL */
1279 					LLVMBuildCondBr(b,
1280 									LLVMBuildICmp(b, LLVMIntEQ, v_null,
1281 												  l_sbool_const(1), ""),
1282 									opblocks[i + 1], b_notnull);
1283 
1284 					/* if value is not null, convert to RO datum */
1285 					LLVMPositionBuilderAtEnd(b, b_notnull);
1286 
1287 					v_valuep = l_ptr_const(op->d.make_readonly.value,
1288 										   l_ptr(TypeSizeT));
1289 
1290 					v_value = LLVMBuildLoad(b, v_valuep, "");
1291 
1292 					v_params[0] = v_value;
1293 					v_ret =
1294 						LLVMBuildCall(b,
1295 									  llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal),
1296 									  v_params, lengthof(v_params), "");
1297 					LLVMBuildStore(b, v_ret, v_resvaluep);
1298 
1299 					LLVMBuildBr(b, opblocks[i + 1]);
1300 					break;
1301 				}
1302 
1303 			case EEOP_IOCOERCE:
1304 				{
1305 					FunctionCallInfo fcinfo_out,
1306 								fcinfo_in;
1307 					LLVMValueRef v_fcinfo_out,
1308 								v_fcinfo_in;
1309 					LLVMValueRef v_fn_addr_out,
1310 								v_fn_addr_in;
1311 					LLVMValueRef v_fcinfo_in_isnullp;
1312 					LLVMValueRef v_in_argp,
1313 								v_out_argp;
1314 					LLVMValueRef v_in_argnullp,
1315 								v_out_argnullp;
1316 					LLVMValueRef v_retval;
1317 					LLVMValueRef v_resvalue;
1318 					LLVMValueRef v_resnull;
1319 
1320 					LLVMValueRef v_output_skip;
1321 					LLVMValueRef v_output;
1322 
1323 					LLVMBasicBlockRef b_skipoutput;
1324 					LLVMBasicBlockRef b_calloutput;
1325 					LLVMBasicBlockRef b_input;
1326 					LLVMBasicBlockRef b_inputcall;
1327 
1328 					fcinfo_out = op->d.iocoerce.fcinfo_data_out;
1329 					fcinfo_in = op->d.iocoerce.fcinfo_data_in;
1330 
1331 					b_skipoutput = l_bb_before_v(opblocks[i + 1],
1332 												 "op.%d.skipoutputnull", i);
1333 					b_calloutput = l_bb_before_v(opblocks[i + 1],
1334 												 "op.%d.calloutput", i);
1335 					b_input = l_bb_before_v(opblocks[i + 1],
1336 											"op.%d.input", i);
1337 					b_inputcall = l_bb_before_v(opblocks[i + 1],
1338 												"op.%d.inputcall", i);
1339 
1340 					v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData));
1341 					v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData));
1342 					v_fn_addr_out = l_ptr_const(fcinfo_out->flinfo->fn_addr, TypePGFunction);
1343 					v_fn_addr_in = l_ptr_const(fcinfo_in->flinfo->fn_addr, TypePGFunction);
1344 
1345 					v_fcinfo_in_isnullp =
1346 						LLVMBuildStructGEP(b, v_fcinfo_in,
1347 										   FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
1348 										   "v_fcinfo_in_isnull");
1349 					v_out_argnullp =
1350 						LLVMBuildStructGEP(b, v_fcinfo_out,
1351 										   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
1352 										   "v_fcinfo_out_argnullp");
1353 					v_in_argnullp =
1354 						LLVMBuildStructGEP(b, v_fcinfo_in,
1355 										   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
1356 										   "v_fcinfo_in_argnullp");
1357 					v_out_argp =
1358 						LLVMBuildStructGEP(b, v_fcinfo_out,
1359 										   FIELDNO_FUNCTIONCALLINFODATA_ARG,
1360 										   "v_fcinfo_out_argp");
1361 					v_in_argp =
1362 						LLVMBuildStructGEP(b, v_fcinfo_in,
1363 										   FIELDNO_FUNCTIONCALLINFODATA_ARG,
1364 										   "v_fcinfo_in_argp");
1365 
1366 					/* output functions are not called on nulls */
1367 					v_resnull = LLVMBuildLoad(b, v_resnullp, "");
1368 					LLVMBuildCondBr(b,
1369 									LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
1370 												  l_sbool_const(1), ""),
1371 									b_skipoutput,
1372 									b_calloutput);
1373 
1374 					LLVMPositionBuilderAtEnd(b, b_skipoutput);
1375 					v_output_skip = l_sizet_const(0);
1376 					LLVMBuildBr(b, b_input);
1377 
1378 					LLVMPositionBuilderAtEnd(b, b_calloutput);
1379 					v_resvalue = LLVMBuildLoad(b, v_resvaluep, "");
1380 
1381 					/* set arg[0] */
1382 					LLVMBuildStore(b,
1383 								   v_resvalue,
1384 								   LLVMBuildStructGEP(b, v_out_argp, 0, ""));
1385 					LLVMBuildStore(b,
1386 								   l_sbool_const(0),
1387 								   LLVMBuildStructGEP(b, v_out_argnullp,
1388 													  0, ""));
1389 					/* and call output function (can never return NULL) */
1390 					v_output = LLVMBuildCall(b, v_fn_addr_out, &v_fcinfo_out,
1391 											 1, "funccall_coerce_out");
1392 					LLVMBuildBr(b, b_input);
1393 
1394 					/* build block handling input function call */
1395 					LLVMPositionBuilderAtEnd(b, b_input);
1396 
1397 					/* phi between resnull and output function call branches */
1398 					{
1399 						LLVMValueRef incoming_values[2];
1400 						LLVMBasicBlockRef incoming_blocks[2];
1401 
1402 						incoming_values[0] = v_output_skip;
1403 						incoming_blocks[0] = b_skipoutput;
1404 
1405 						incoming_values[1] = v_output;
1406 						incoming_blocks[1] = b_calloutput;
1407 
1408 						v_output = LLVMBuildPhi(b, TypeSizeT, "output");
1409 						LLVMAddIncoming(v_output,
1410 										incoming_values, incoming_blocks,
1411 										lengthof(incoming_blocks));
1412 					}
1413 
1414 					/*
1415 					 * If input function is strict, skip if input string is
1416 					 * NULL.
1417 					 */
1418 					if (op->d.iocoerce.finfo_in->fn_strict)
1419 					{
1420 						LLVMBuildCondBr(b,
1421 										LLVMBuildICmp(b, LLVMIntEQ, v_output,
1422 													  l_sizet_const(0), ""),
1423 										opblocks[i + 1],
1424 										b_inputcall);
1425 					}
1426 					else
1427 					{
1428 						LLVMBuildBr(b, b_inputcall);
1429 					}
1430 
1431 					LLVMPositionBuilderAtEnd(b, b_inputcall);
1432 					/* set arguments */
1433 					/* arg0: output */
1434 					LLVMBuildStore(b, v_output,
1435 								   LLVMBuildStructGEP(b, v_in_argp, 0, ""));
1436 					LLVMBuildStore(b, v_resnull,
1437 								   LLVMBuildStructGEP(b, v_in_argnullp, 0, ""));
1438 
1439 					/* arg1: ioparam: preset in execExpr.c */
1440 					/* arg2: typmod: preset in execExpr.c  */
1441 
1442 					/* reset fcinfo_in->isnull */
1443 					LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
1444 					/* and call function */
1445 					v_retval = LLVMBuildCall(b, v_fn_addr_in, &v_fcinfo_in, 1,
1446 											 "funccall_iocoerce_in");
1447 
1448 					LLVMBuildStore(b, v_retval, v_resvaluep);
1449 
1450 					LLVMBuildBr(b, opblocks[i + 1]);
1451 					break;
1452 				}
1453 
1454 			case EEOP_DISTINCT:
1455 			case EEOP_NOT_DISTINCT:
1456 				{
1457 					FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1458 
1459 					LLVMValueRef v_fcinfo;
1460 					LLVMValueRef v_fcinfo_isnull;
1461 
1462 					LLVMValueRef v_argnullp;
1463 					LLVMValueRef v_argnull0,
1464 								v_argisnull0;
1465 					LLVMValueRef v_argnull1,
1466 								v_argisnull1;
1467 
1468 					LLVMValueRef v_anyargisnull;
1469 					LLVMValueRef v_bothargisnull;
1470 
1471 					LLVMValueRef v_result;
1472 
1473 					LLVMBasicBlockRef b_noargnull;
1474 					LLVMBasicBlockRef b_checkbothargnull;
1475 					LLVMBasicBlockRef b_bothargnull;
1476 					LLVMBasicBlockRef b_anyargnull;
1477 
1478 					b_noargnull = l_bb_before_v(opblocks[i + 1], "op.%d.noargnull", i);
1479 					b_checkbothargnull = l_bb_before_v(opblocks[i + 1], "op.%d.checkbothargnull", i);
1480 					b_bothargnull = l_bb_before_v(opblocks[i + 1], "op.%d.bothargnull", i);
1481 					b_anyargnull = l_bb_before_v(opblocks[i + 1], "op.%d.anyargnull", i);
1482 
1483 					v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
1484 
1485 					v_argnullp =
1486 						LLVMBuildStructGEP(b,
1487 										   v_fcinfo,
1488 										   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
1489 										   "v_argnullp");
1490 
1491 					/* load argnull[0|1] for both arguments */
1492 					v_argnull0 = l_load_struct_gep(b, v_argnullp, 0, "");
1493 					v_argisnull0 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
1494 												 l_sbool_const(1), "");
1495 
1496 					v_argnull1 = l_load_struct_gep(b, v_argnullp, 1, "");
1497 					v_argisnull1 = LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
1498 												 l_sbool_const(1), "");
1499 
1500 					v_anyargisnull = LLVMBuildOr(b, v_argisnull0, v_argisnull1, "");
1501 					v_bothargisnull = LLVMBuildAnd(b, v_argisnull0, v_argisnull1, "");
1502 
1503 					/*
1504 					 * Check function arguments for NULLness: If either is
1505 					 * NULL, we check if both args are NULL. Otherwise call
1506 					 * comparator.
1507 					 */
1508 					LLVMBuildCondBr(b, v_anyargisnull, b_checkbothargnull,
1509 									b_noargnull);
1510 
1511 					/*
1512 					 * build block checking if any arg is null
1513 					 */
1514 					LLVMPositionBuilderAtEnd(b, b_checkbothargnull);
1515 					LLVMBuildCondBr(b, v_bothargisnull, b_bothargnull,
1516 									b_anyargnull);
1517 
1518 
1519 					/* Both NULL? Then is not distinct... */
1520 					LLVMPositionBuilderAtEnd(b, b_bothargnull);
1521 					LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
1522 					if (opcode == EEOP_NOT_DISTINCT)
1523 						LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
1524 					else
1525 						LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
1526 
1527 					LLVMBuildBr(b, opblocks[i + 1]);
1528 
1529 					/* Only one is NULL? Then is distinct... */
1530 					LLVMPositionBuilderAtEnd(b, b_anyargnull);
1531 					LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
1532 					if (opcode == EEOP_NOT_DISTINCT)
1533 						LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
1534 					else
1535 						LLVMBuildStore(b, l_sizet_const(1), v_resvaluep);
1536 					LLVMBuildBr(b, opblocks[i + 1]);
1537 
1538 					/* neither argument is null: compare */
1539 					LLVMPositionBuilderAtEnd(b, b_noargnull);
1540 
1541 					v_result = BuildV1Call(context, b, mod, fcinfo,
1542 										   &v_fcinfo_isnull);
1543 
1544 					if (opcode == EEOP_DISTINCT)
1545 					{
1546 						/* Must invert result of "=" */
1547 						v_result =
1548 							LLVMBuildZExt(b,
1549 										  LLVMBuildICmp(b, LLVMIntEQ,
1550 														v_result,
1551 														l_sizet_const(0), ""),
1552 										  TypeSizeT, "");
1553 					}
1554 
1555 					LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
1556 					LLVMBuildStore(b, v_result, v_resvaluep);
1557 
1558 					LLVMBuildBr(b, opblocks[i + 1]);
1559 					break;
1560 				}
1561 
1562 			case EEOP_NULLIF:
1563 				{
1564 					FunctionCallInfo fcinfo = op->d.func.fcinfo_data;
1565 
1566 					LLVMValueRef v_fcinfo;
1567 					LLVMValueRef v_fcinfo_isnull;
1568 					LLVMValueRef v_argnullp;
1569 					LLVMValueRef v_argnull0;
1570 					LLVMValueRef v_argnull1;
1571 					LLVMValueRef v_anyargisnull;
1572 					LLVMValueRef v_argp;
1573 					LLVMValueRef v_arg0;
1574 					LLVMBasicBlockRef b_hasnull;
1575 					LLVMBasicBlockRef b_nonull;
1576 					LLVMBasicBlockRef b_argsequal;
1577 					LLVMValueRef v_retval;
1578 					LLVMValueRef v_argsequal;
1579 
1580 					b_hasnull = l_bb_before_v(opblocks[i + 1],
1581 											  "b.%d.null-args", i);
1582 					b_nonull = l_bb_before_v(opblocks[i + 1],
1583 											 "b.%d.no-null-args", i);
1584 					b_argsequal = l_bb_before_v(opblocks[i + 1],
1585 												"b.%d.argsequal", i);
1586 
1587 					v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
1588 
1589 					v_argnullp =
1590 						LLVMBuildStructGEP(b,
1591 										   v_fcinfo,
1592 										   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
1593 										   "v_argnullp");
1594 
1595 					v_argp =
1596 						LLVMBuildStructGEP(b,
1597 										   v_fcinfo,
1598 										   FIELDNO_FUNCTIONCALLINFODATA_ARG,
1599 										   "v_argp");
1600 
1601 					/* if either argument is NULL they can't be equal */
1602 					v_argnull0 = l_load_struct_gep(b, v_argnullp, 0, "");
1603 					v_argnull1 = l_load_struct_gep(b, v_argnullp, 1, "");
1604 
1605 					v_anyargisnull =
1606 						LLVMBuildOr(b,
1607 									LLVMBuildICmp(b, LLVMIntEQ, v_argnull0,
1608 												  l_sbool_const(1), ""),
1609 									LLVMBuildICmp(b, LLVMIntEQ, v_argnull1,
1610 												  l_sbool_const(1), ""),
1611 									"");
1612 
1613 					LLVMBuildCondBr(b, v_anyargisnull, b_hasnull, b_nonull);
1614 
1615 					/* one (or both) of the arguments are null, return arg[0] */
1616 					LLVMPositionBuilderAtEnd(b, b_hasnull);
1617 					v_arg0 = l_load_struct_gep(b, v_argp, 0, "");
1618 					LLVMBuildStore(b, v_argnull0, v_resnullp);
1619 					LLVMBuildStore(b, v_arg0, v_resvaluep);
1620 					LLVMBuildBr(b, opblocks[i + 1]);
1621 
1622 					/* build block to invoke function and check result */
1623 					LLVMPositionBuilderAtEnd(b, b_nonull);
1624 
1625 					v_retval = BuildV1Call(context, b, mod, fcinfo, &v_fcinfo_isnull);
1626 
1627 					/*
1628 					 * If result not null, and arguments are equal return null
1629 					 * (same result as if there'd been NULLs, hence reuse
1630 					 * b_hasnull).
1631 					 */
1632 					v_argsequal = LLVMBuildAnd(b,
1633 											   LLVMBuildICmp(b, LLVMIntEQ,
1634 															 v_fcinfo_isnull,
1635 															 l_sbool_const(0),
1636 															 ""),
1637 											   LLVMBuildICmp(b, LLVMIntEQ,
1638 															 v_retval,
1639 															 l_sizet_const(1),
1640 															 ""),
1641 											   "");
1642 					LLVMBuildCondBr(b, v_argsequal, b_argsequal, b_hasnull);
1643 
1644 					/* build block setting result to NULL, if args are equal */
1645 					LLVMPositionBuilderAtEnd(b, b_argsequal);
1646 					LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
1647 					LLVMBuildStore(b, l_sizet_const(0), v_resvaluep);
1648 					LLVMBuildStore(b, v_retval, v_resvaluep);
1649 
1650 					LLVMBuildBr(b, opblocks[i + 1]);
1651 					break;
1652 				}
1653 
1654 			case EEOP_SQLVALUEFUNCTION:
1655 				build_EvalXFunc(b, mod, "ExecEvalSQLValueFunction",
1656 								v_state, v_econtext, op);
1657 				LLVMBuildBr(b, opblocks[i + 1]);
1658 				break;
1659 
1660 			case EEOP_CURRENTOFEXPR:
1661 				build_EvalXFunc(b, mod, "ExecEvalCurrentOfExpr",
1662 								v_state, v_econtext, op);
1663 				LLVMBuildBr(b, opblocks[i + 1]);
1664 				break;
1665 
1666 			case EEOP_NEXTVALUEEXPR:
1667 				build_EvalXFunc(b, mod, "ExecEvalNextValueExpr",
1668 								v_state, v_econtext, op);
1669 				LLVMBuildBr(b, opblocks[i + 1]);
1670 				break;
1671 
1672 			case EEOP_ARRAYEXPR:
1673 				build_EvalXFunc(b, mod, "ExecEvalArrayExpr",
1674 								v_state, v_econtext, op);
1675 				LLVMBuildBr(b, opblocks[i + 1]);
1676 				break;
1677 
1678 			case EEOP_ARRAYCOERCE:
1679 				build_EvalXFunc(b, mod, "ExecEvalArrayCoerce",
1680 								v_state, v_econtext, op);
1681 				LLVMBuildBr(b, opblocks[i + 1]);
1682 				break;
1683 
1684 			case EEOP_ROW:
1685 				build_EvalXFunc(b, mod, "ExecEvalRow",
1686 								v_state, v_econtext, op);
1687 				LLVMBuildBr(b, opblocks[i + 1]);
1688 				break;
1689 
1690 			case EEOP_ROWCOMPARE_STEP:
1691 				{
1692 					FunctionCallInfo fcinfo = op->d.rowcompare_step.fcinfo_data;
1693 					LLVMValueRef v_fcinfo_isnull;
1694 					LLVMBasicBlockRef b_null;
1695 					LLVMBasicBlockRef b_compare;
1696 					LLVMBasicBlockRef b_compare_result;
1697 
1698 					LLVMValueRef v_retval;
1699 
1700 					b_null = l_bb_before_v(opblocks[i + 1],
1701 										   "op.%d.row-null", i);
1702 					b_compare = l_bb_before_v(opblocks[i + 1],
1703 											  "op.%d.row-compare", i);
1704 					b_compare_result =
1705 						l_bb_before_v(opblocks[i + 1],
1706 									  "op.%d.row-compare-result",
1707 									  i);
1708 
1709 					/*
1710 					 * If function is strict, and either arg is null, we're
1711 					 * done.
1712 					 */
1713 					if (op->d.rowcompare_step.finfo->fn_strict)
1714 					{
1715 						LLVMValueRef v_fcinfo;
1716 						LLVMValueRef v_argnullp;
1717 						LLVMValueRef v_argnull0;
1718 						LLVMValueRef v_argnull1;
1719 						LLVMValueRef v_anyargisnull;
1720 
1721 						v_fcinfo = l_ptr_const(fcinfo,
1722 											   l_ptr(StructFunctionCallInfoData));
1723 
1724 						v_argnullp =
1725 							LLVMBuildStructGEP(b, v_fcinfo,
1726 											   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
1727 											   "v_argnullp");
1728 
1729 						v_argnull0 = l_load_struct_gep(b, v_argnullp, 0, "");
1730 						v_argnull1 = l_load_struct_gep(b, v_argnullp, 1, "");
1731 
1732 						v_anyargisnull =
1733 							LLVMBuildOr(b,
1734 										LLVMBuildICmp(b,
1735 													  LLVMIntEQ,
1736 													  v_argnull0,
1737 													  l_sbool_const(1),
1738 													  ""),
1739 										LLVMBuildICmp(b, LLVMIntEQ,
1740 													  v_argnull1,
1741 													  l_sbool_const(1), ""),
1742 										"");
1743 
1744 						LLVMBuildCondBr(b, v_anyargisnull, b_null, b_compare);
1745 					}
1746 					else
1747 					{
1748 						LLVMBuildBr(b, b_compare);
1749 					}
1750 
1751 					/* build block invoking comparison function */
1752 					LLVMPositionBuilderAtEnd(b, b_compare);
1753 
1754 					/* call function */
1755 					v_retval = BuildV1Call(context, b, mod, fcinfo,
1756 										   &v_fcinfo_isnull);
1757 					LLVMBuildStore(b, v_retval, v_resvaluep);
1758 
1759 					/* if result of function is NULL, force NULL result */
1760 					LLVMBuildCondBr(b,
1761 									LLVMBuildICmp(b,
1762 												  LLVMIntEQ,
1763 												  v_fcinfo_isnull,
1764 												  l_sbool_const(0),
1765 												  ""),
1766 									b_compare_result,
1767 									b_null);
1768 
1769 					/* build block analyzing the !NULL comparator result */
1770 					LLVMPositionBuilderAtEnd(b, b_compare_result);
1771 
1772 					/* if results equal, compare next, otherwise done */
1773 					LLVMBuildCondBr(b,
1774 									LLVMBuildICmp(b,
1775 												  LLVMIntEQ,
1776 												  v_retval,
1777 												  l_sizet_const(0), ""),
1778 									opblocks[i + 1],
1779 									opblocks[op->d.rowcompare_step.jumpdone]);
1780 
1781 					/*
1782 					 * Build block handling NULL input or NULL comparator
1783 					 * result.
1784 					 */
1785 					LLVMPositionBuilderAtEnd(b, b_null);
1786 					LLVMBuildStore(b, l_sbool_const(1), v_resnullp);
1787 					LLVMBuildBr(b, opblocks[op->d.rowcompare_step.jumpnull]);
1788 
1789 					break;
1790 				}
1791 
1792 			case EEOP_ROWCOMPARE_FINAL:
1793 				{
1794 					RowCompareType rctype = op->d.rowcompare_final.rctype;
1795 
1796 					LLVMValueRef v_cmpresult;
1797 					LLVMValueRef v_result;
1798 					LLVMIntPredicate predicate;
1799 
1800 					/*
1801 					 * Btree comparators return 32 bit results, need to be
1802 					 * careful about sign (used as a 64 bit value it's
1803 					 * otherwise wrong).
1804 					 */
1805 					v_cmpresult =
1806 						LLVMBuildTrunc(b,
1807 									   LLVMBuildLoad(b, v_resvaluep, ""),
1808 									   LLVMInt32Type(), "");
1809 
1810 					switch (rctype)
1811 					{
1812 						case ROWCOMPARE_LT:
1813 							predicate = LLVMIntSLT;
1814 							break;
1815 						case ROWCOMPARE_LE:
1816 							predicate = LLVMIntSLE;
1817 							break;
1818 						case ROWCOMPARE_GT:
1819 							predicate = LLVMIntSGT;
1820 							break;
1821 						case ROWCOMPARE_GE:
1822 							predicate = LLVMIntSGE;
1823 							break;
1824 						default:
1825 							/* EQ and NE cases aren't allowed here */
1826 							Assert(false);
1827 							predicate = 0;	/* prevent compiler warning */
1828 							break;
1829 					}
1830 
1831 					v_result = LLVMBuildICmp(b,
1832 											 predicate,
1833 											 v_cmpresult,
1834 											 l_int32_const(0),
1835 											 "");
1836 					v_result = LLVMBuildZExt(b, v_result, TypeSizeT, "");
1837 
1838 					LLVMBuildStore(b, l_sbool_const(0), v_resnullp);
1839 					LLVMBuildStore(b, v_result, v_resvaluep);
1840 
1841 					LLVMBuildBr(b, opblocks[i + 1]);
1842 					break;
1843 				}
1844 
1845 			case EEOP_MINMAX:
1846 				build_EvalXFunc(b, mod, "ExecEvalMinMax",
1847 								v_state, v_econtext, op);
1848 				LLVMBuildBr(b, opblocks[i + 1]);
1849 				break;
1850 
1851 			case EEOP_FIELDSELECT:
1852 				build_EvalXFunc(b, mod, "ExecEvalFieldSelect",
1853 								v_state, v_econtext, op);
1854 				LLVMBuildBr(b, opblocks[i + 1]);
1855 				break;
1856 
1857 			case EEOP_FIELDSTORE_DEFORM:
1858 				build_EvalXFunc(b, mod, "ExecEvalFieldStoreDeForm",
1859 								v_state, v_econtext, op);
1860 				LLVMBuildBr(b, opblocks[i + 1]);
1861 				break;
1862 
1863 			case EEOP_FIELDSTORE_FORM:
1864 				build_EvalXFunc(b, mod, "ExecEvalFieldStoreForm",
1865 								v_state, v_econtext, op);
1866 				LLVMBuildBr(b, opblocks[i + 1]);
1867 				break;
1868 
1869 			case EEOP_ARRAYREF_SUBSCRIPT:
1870 				{
1871 					LLVMValueRef v_fn;
1872 					int			jumpdone = op->d.arrayref_subscript.jumpdone;
1873 					LLVMValueRef v_params[2];
1874 					LLVMValueRef v_ret;
1875 
1876 					v_fn = llvm_get_decl(mod, FuncExecEvalArrayRefSubscript);
1877 
1878 					v_params[0] = v_state;
1879 					v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
1880 					v_ret = LLVMBuildCall(b, v_fn,
1881 										  v_params, lengthof(v_params), "");
1882 					v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
1883 
1884 					LLVMBuildCondBr(b,
1885 									LLVMBuildICmp(b, LLVMIntEQ, v_ret,
1886 												  l_sbool_const(1), ""),
1887 									opblocks[i + 1],
1888 									opblocks[jumpdone]);
1889 					break;
1890 				}
1891 
1892 			case EEOP_DOMAIN_TESTVAL:
1893 				{
1894 					LLVMBasicBlockRef b_avail,
1895 								b_notavail;
1896 					LLVMValueRef v_casevaluep,
1897 								v_casevalue;
1898 					LLVMValueRef v_casenullp,
1899 								v_casenull;
1900 					LLVMValueRef v_casevaluenull;
1901 
1902 					b_avail = l_bb_before_v(opblocks[i + 1],
1903 											"op.%d.avail", i);
1904 					b_notavail = l_bb_before_v(opblocks[i + 1],
1905 											   "op.%d.notavail", i);
1906 
1907 					v_casevaluep = l_ptr_const(op->d.casetest.value,
1908 											   l_ptr(TypeSizeT));
1909 					v_casenullp = l_ptr_const(op->d.casetest.isnull,
1910 											  l_ptr(TypeStorageBool));
1911 
1912 					v_casevaluenull =
1913 						LLVMBuildICmp(b, LLVMIntEQ,
1914 									  LLVMBuildPtrToInt(b, v_casevaluep,
1915 														TypeSizeT, ""),
1916 									  l_sizet_const(0), "");
1917 					LLVMBuildCondBr(b,
1918 									v_casevaluenull,
1919 									b_notavail, b_avail);
1920 
1921 					/* if casetest != NULL */
1922 					LLVMPositionBuilderAtEnd(b, b_avail);
1923 					v_casevalue = LLVMBuildLoad(b, v_casevaluep, "");
1924 					v_casenull = LLVMBuildLoad(b, v_casenullp, "");
1925 					LLVMBuildStore(b, v_casevalue, v_resvaluep);
1926 					LLVMBuildStore(b, v_casenull, v_resnullp);
1927 					LLVMBuildBr(b, opblocks[i + 1]);
1928 
1929 					/* if casetest == NULL */
1930 					LLVMPositionBuilderAtEnd(b, b_notavail);
1931 					v_casevalue =
1932 						l_load_struct_gep(b, v_econtext,
1933 										  FIELDNO_EXPRCONTEXT_DOMAINDATUM,
1934 										  "");
1935 					v_casenull =
1936 						l_load_struct_gep(b, v_econtext,
1937 										  FIELDNO_EXPRCONTEXT_DOMAINNULL,
1938 										  "");
1939 					LLVMBuildStore(b, v_casevalue, v_resvaluep);
1940 					LLVMBuildStore(b, v_casenull, v_resnullp);
1941 
1942 					LLVMBuildBr(b, opblocks[i + 1]);
1943 					break;
1944 				}
1945 
1946 			case EEOP_DOMAIN_NOTNULL:
1947 				build_EvalXFunc(b, mod, "ExecEvalConstraintNotNull",
1948 								v_state, v_econtext, op);
1949 				LLVMBuildBr(b, opblocks[i + 1]);
1950 				break;
1951 
1952 			case EEOP_DOMAIN_CHECK:
1953 				build_EvalXFunc(b, mod, "ExecEvalConstraintCheck",
1954 								v_state, v_econtext, op);
1955 				LLVMBuildBr(b, opblocks[i + 1]);
1956 				break;
1957 
1958 			case EEOP_CONVERT_ROWTYPE:
1959 				build_EvalXFunc(b, mod, "ExecEvalConvertRowtype",
1960 								v_state, v_econtext, op);
1961 				LLVMBuildBr(b, opblocks[i + 1]);
1962 				break;
1963 
1964 			case EEOP_SCALARARRAYOP:
1965 				build_EvalXFunc(b, mod, "ExecEvalScalarArrayOp",
1966 								v_state, v_econtext, op);
1967 				LLVMBuildBr(b, opblocks[i + 1]);
1968 				break;
1969 
1970 			case EEOP_XMLEXPR:
1971 				build_EvalXFunc(b, mod, "ExecEvalXmlExpr",
1972 								v_state, v_econtext, op);
1973 				LLVMBuildBr(b, opblocks[i + 1]);
1974 				break;
1975 
1976 			case EEOP_AGGREF:
1977 				{
1978 					AggrefExprState *aggref = op->d.aggref.astate;
1979 					LLVMValueRef v_aggnop;
1980 					LLVMValueRef v_aggno;
1981 					LLVMValueRef value,
1982 								isnull;
1983 
1984 					/*
1985 					 * At this point aggref->aggno is not yet set (it's set up
1986 					 * in ExecInitAgg() after initializing the expression). So
1987 					 * load it from memory each time round.
1988 					 */
1989 					v_aggnop = l_ptr_const(&aggref->aggno,
1990 										   l_ptr(LLVMInt32Type()));
1991 					v_aggno = LLVMBuildLoad(b, v_aggnop, "v_aggno");
1992 
1993 					/* load agg value / null */
1994 					value = l_load_gep1(b, v_aggvalues, v_aggno, "aggvalue");
1995 					isnull = l_load_gep1(b, v_aggnulls, v_aggno, "aggnull");
1996 
1997 					/* and store result */
1998 					LLVMBuildStore(b, value, v_resvaluep);
1999 					LLVMBuildStore(b, isnull, v_resnullp);
2000 
2001 					LLVMBuildBr(b, opblocks[i + 1]);
2002 					break;
2003 				}
2004 
2005 			case EEOP_GROUPING_FUNC:
2006 				build_EvalXFunc(b, mod, "ExecEvalGroupingFunc",
2007 								v_state, v_econtext, op);
2008 				LLVMBuildBr(b, opblocks[i + 1]);
2009 				break;
2010 
2011 			case EEOP_WINDOW_FUNC:
2012 				{
2013 					WindowFuncExprState *wfunc = op->d.window_func.wfstate;
2014 					LLVMValueRef v_wfuncnop;
2015 					LLVMValueRef v_wfuncno;
2016 					LLVMValueRef value,
2017 								isnull;
2018 
2019 					/*
2020 					 * At this point aggref->wfuncno is not yet set (it's set
2021 					 * up in ExecInitWindowAgg() after initializing the
2022 					 * expression). So load it from memory each time round.
2023 					 */
2024 					v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
2025 											 l_ptr(LLVMInt32Type()));
2026 					v_wfuncno = LLVMBuildLoad(b, v_wfuncnop, "v_wfuncno");
2027 
2028 					/* load window func value / null */
2029 					value = l_load_gep1(b, v_aggvalues, v_wfuncno,
2030 										"windowvalue");
2031 					isnull = l_load_gep1(b, v_aggnulls, v_wfuncno,
2032 										 "windownull");
2033 
2034 					LLVMBuildStore(b, value, v_resvaluep);
2035 					LLVMBuildStore(b, isnull, v_resnullp);
2036 
2037 					LLVMBuildBr(b, opblocks[i + 1]);
2038 					break;
2039 				}
2040 
2041 			case EEOP_SUBPLAN:
2042 				build_EvalXFunc(b, mod, "ExecEvalSubPlan",
2043 								v_state, v_econtext, op);
2044 				LLVMBuildBr(b, opblocks[i + 1]);
2045 				break;
2046 
2047 			case EEOP_ALTERNATIVE_SUBPLAN:
2048 				build_EvalXFunc(b, mod, "ExecEvalAlternativeSubPlan",
2049 								v_state, v_econtext, op);
2050 				LLVMBuildBr(b, opblocks[i + 1]);
2051 				break;
2052 
2053 			case EEOP_AGG_STRICT_DESERIALIZE:
2054 				{
2055 					FunctionCallInfo fcinfo = op->d.agg_deserialize.fcinfo_data;
2056 					LLVMValueRef v_fcinfo;
2057 					LLVMValueRef v_argnullp;
2058 					LLVMValueRef v_argnull0;
2059 					LLVMBasicBlockRef b_deserialize;
2060 
2061 					b_deserialize = l_bb_before_v(opblocks[i + 1],
2062 												  "op.%d.deserialize", i);
2063 
2064 					v_fcinfo = l_ptr_const(fcinfo,
2065 										   l_ptr(StructFunctionCallInfoData));
2066 
2067 					v_argnullp =
2068 						LLVMBuildStructGEP(b,
2069 										   v_fcinfo,
2070 										   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
2071 										   "v_argnullp");
2072 					v_argnull0 =
2073 						l_load_struct_gep(b, v_argnullp, 0, "v_argnull0");
2074 
2075 					LLVMBuildCondBr(b,
2076 									LLVMBuildICmp(b,
2077 												  LLVMIntEQ,
2078 												  v_argnull0,
2079 												  l_sbool_const(1),
2080 												  ""),
2081 									opblocks[op->d.agg_deserialize.jumpnull],
2082 									b_deserialize);
2083 					LLVMPositionBuilderAtEnd(b, b_deserialize);
2084 				}
2085 				/* FALLTHROUGH */
2086 
2087 			case EEOP_AGG_DESERIALIZE:
2088 				{
2089 					AggState   *aggstate;
2090 					FunctionCallInfo fcinfo;
2091 
2092 					LLVMValueRef v_retval;
2093 					LLVMValueRef v_fcinfo_isnull;
2094 					LLVMValueRef v_tmpcontext;
2095 					LLVMValueRef v_oldcontext;
2096 
2097 					aggstate = op->d.agg_deserialize.aggstate;
2098 					fcinfo = op->d.agg_deserialize.fcinfo_data;
2099 
2100 					v_tmpcontext =
2101 						l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2102 									l_ptr(StructMemoryContextData));
2103 					v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
2104 					v_retval = BuildV1Call(context, b, mod, fcinfo,
2105 										   &v_fcinfo_isnull);
2106 					l_mcxt_switch(mod, b, v_oldcontext);
2107 
2108 					LLVMBuildStore(b, v_retval, v_resvaluep);
2109 					LLVMBuildStore(b, v_fcinfo_isnull, v_resnullp);
2110 
2111 					LLVMBuildBr(b, opblocks[i + 1]);
2112 					break;
2113 				}
2114 
2115 			case EEOP_AGG_STRICT_INPUT_CHECK:
2116 				{
2117 					int			nargs = op->d.agg_strict_input_check.nargs;
2118 					bool	   *nulls = op->d.agg_strict_input_check.nulls;
2119 					int			jumpnull;
2120 					int			argno;
2121 
2122 					LLVMValueRef v_nullp;
2123 					LLVMBasicBlockRef *b_checknulls;
2124 
2125 					Assert(nargs > 0);
2126 
2127 					jumpnull = op->d.agg_strict_input_check.jumpnull;
2128 					v_nullp = l_ptr_const(nulls, l_ptr(TypeStorageBool));
2129 
2130 					/* create blocks for checking args */
2131 					b_checknulls = palloc(sizeof(LLVMBasicBlockRef *) * nargs);
2132 					for (argno = 0; argno < nargs; argno++)
2133 					{
2134 						b_checknulls[argno] =
2135 							l_bb_before_v(opblocks[i + 1],
2136 										  "op.%d.check-null.%d",
2137 										  i, argno);
2138 					}
2139 
2140 					LLVMBuildBr(b, b_checknulls[0]);
2141 
2142 					/* strict function, check for NULL args */
2143 					for (argno = 0; argno < nargs; argno++)
2144 					{
2145 						LLVMValueRef v_argno = l_int32_const(argno);
2146 						LLVMValueRef v_argisnull;
2147 						LLVMBasicBlockRef b_argnotnull;
2148 
2149 						LLVMPositionBuilderAtEnd(b, b_checknulls[argno]);
2150 
2151 						if (argno + 1 == nargs)
2152 							b_argnotnull = opblocks[i + 1];
2153 						else
2154 							b_argnotnull = b_checknulls[argno + 1];
2155 
2156 						v_argisnull = l_load_gep1(b, v_nullp, v_argno, "");
2157 
2158 						LLVMBuildCondBr(b,
2159 										LLVMBuildICmp(b,
2160 													  LLVMIntEQ,
2161 													  v_argisnull,
2162 													  l_sbool_const(1), ""),
2163 										opblocks[jumpnull],
2164 										b_argnotnull);
2165 					}
2166 
2167 					break;
2168 				}
2169 
2170 			case EEOP_AGG_INIT_TRANS:
2171 				{
2172 					AggState   *aggstate;
2173 					AggStatePerTrans pertrans;
2174 
2175 					LLVMValueRef v_aggstatep;
2176 					LLVMValueRef v_pertransp;
2177 
2178 					LLVMValueRef v_allpergroupsp;
2179 
2180 					LLVMValueRef v_pergroupp;
2181 
2182 					LLVMValueRef v_setoff,
2183 								v_transno;
2184 
2185 					LLVMValueRef v_notransvalue;
2186 
2187 					LLVMBasicBlockRef b_init;
2188 
2189 					aggstate = op->d.agg_init_trans.aggstate;
2190 					pertrans = op->d.agg_init_trans.pertrans;
2191 
2192 					v_aggstatep = l_ptr_const(aggstate,
2193 											  l_ptr(StructAggState));
2194 					v_pertransp = l_ptr_const(pertrans,
2195 											  l_ptr(StructAggStatePerTransData));
2196 
2197 					/*
2198 					 * pergroup = &aggstate->all_pergroups
2199 					 * [op->d.agg_init_trans_check.setoff]
2200 					 * [op->d.agg_init_trans_check.transno];
2201 					 */
2202 					v_allpergroupsp =
2203 						l_load_struct_gep(b, v_aggstatep,
2204 										  FIELDNO_AGGSTATE_ALL_PERGROUPS,
2205 										  "aggstate.all_pergroups");
2206 					v_setoff = l_int32_const(op->d.agg_init_trans.setoff);
2207 					v_transno = l_int32_const(op->d.agg_init_trans.transno);
2208 					v_pergroupp =
2209 						LLVMBuildGEP(b,
2210 									 l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
2211 									 &v_transno, 1, "");
2212 
2213 					v_notransvalue =
2214 						l_load_struct_gep(b, v_pergroupp,
2215 										  FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE,
2216 										  "notransvalue");
2217 
2218 					b_init = l_bb_before_v(opblocks[i + 1],
2219 										   "op.%d.inittrans", i);
2220 
2221 					LLVMBuildCondBr(b,
2222 									LLVMBuildICmp(b, LLVMIntEQ, v_notransvalue,
2223 												  l_sbool_const(1), ""),
2224 									b_init,
2225 									opblocks[i + 1]);
2226 
2227 					LLVMPositionBuilderAtEnd(b, b_init);
2228 
2229 					{
2230 						LLVMValueRef params[3];
2231 						LLVMValueRef v_curaggcontext;
2232 						LLVMValueRef v_current_set;
2233 						LLVMValueRef v_aggcontext;
2234 
2235 						v_aggcontext = l_ptr_const(op->d.agg_init_trans.aggcontext,
2236 												   l_ptr(StructExprContext));
2237 
2238 						v_current_set =
2239 							LLVMBuildStructGEP(b,
2240 											   v_aggstatep,
2241 											   FIELDNO_AGGSTATE_CURRENT_SET,
2242 											   "aggstate.current_set");
2243 						v_curaggcontext =
2244 							LLVMBuildStructGEP(b,
2245 											   v_aggstatep,
2246 											   FIELDNO_AGGSTATE_CURAGGCONTEXT,
2247 											   "aggstate.curaggcontext");
2248 
2249 						LLVMBuildStore(b, l_int32_const(op->d.agg_init_trans.setno),
2250 									   v_current_set);
2251 						LLVMBuildStore(b, v_aggcontext,
2252 									   v_curaggcontext);
2253 
2254 						params[0] = v_aggstatep;
2255 						params[1] = v_pertransp;
2256 						params[2] = v_pergroupp;
2257 
2258 						LLVMBuildCall(b,
2259 									  llvm_get_decl(mod, FuncExecAggInitGroup),
2260 									  params, lengthof(params),
2261 									  "");
2262 					}
2263 					LLVMBuildBr(b, opblocks[op->d.agg_init_trans.jumpnull]);
2264 
2265 					break;
2266 				}
2267 
2268 			case EEOP_AGG_STRICT_TRANS_CHECK:
2269 				{
2270 					AggState   *aggstate;
2271 					LLVMValueRef v_setoff,
2272 								v_transno;
2273 
2274 					LLVMValueRef v_aggstatep;
2275 					LLVMValueRef v_allpergroupsp;
2276 
2277 					LLVMValueRef v_transnull;
2278 					LLVMValueRef v_pergroupp;
2279 
2280 					int			jumpnull = op->d.agg_strict_trans_check.jumpnull;
2281 
2282 					aggstate = op->d.agg_strict_trans_check.aggstate;
2283 					v_aggstatep = l_ptr_const(aggstate, l_ptr(StructAggState));
2284 
2285 					/*
2286 					 * pergroup = &aggstate->all_pergroups
2287 					 * [op->d.agg_strict_trans_check.setoff]
2288 					 * [op->d.agg_init_trans_check.transno];
2289 					 */
2290 					v_allpergroupsp =
2291 						l_load_struct_gep(b, v_aggstatep,
2292 										  FIELDNO_AGGSTATE_ALL_PERGROUPS,
2293 										  "aggstate.all_pergroups");
2294 					v_setoff =
2295 						l_int32_const(op->d.agg_strict_trans_check.setoff);
2296 					v_transno =
2297 						l_int32_const(op->d.agg_strict_trans_check.transno);
2298 					v_pergroupp =
2299 						LLVMBuildGEP(b,
2300 									 l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
2301 									 &v_transno, 1, "");
2302 
2303 					v_transnull =
2304 						l_load_struct_gep(b, v_pergroupp,
2305 										  FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
2306 										  "transnull");
2307 
2308 					LLVMBuildCondBr(b,
2309 									LLVMBuildICmp(b, LLVMIntEQ, v_transnull,
2310 												  l_sbool_const(1), ""),
2311 									opblocks[jumpnull],
2312 									opblocks[i + 1]);
2313 
2314 					break;
2315 				}
2316 
2317 			case EEOP_AGG_PLAIN_TRANS_BYVAL:
2318 			case EEOP_AGG_PLAIN_TRANS:
2319 				{
2320 					AggState   *aggstate;
2321 					AggStatePerTrans pertrans;
2322 					FunctionCallInfo fcinfo;
2323 
2324 					LLVMValueRef v_aggstatep;
2325 					LLVMValueRef v_fcinfo;
2326 					LLVMValueRef v_fcinfo_isnull;
2327 					LLVMValueRef v_argp,
2328 								v_argnullp;
2329 
2330 					LLVMValueRef v_transvaluep;
2331 					LLVMValueRef v_transnullp;
2332 
2333 					LLVMValueRef v_setoff;
2334 					LLVMValueRef v_transno;
2335 
2336 					LLVMValueRef v_aggcontext;
2337 
2338 					LLVMValueRef v_allpergroupsp;
2339 					LLVMValueRef v_current_setp;
2340 					LLVMValueRef v_current_pertransp;
2341 					LLVMValueRef v_curaggcontext;
2342 
2343 					LLVMValueRef v_pertransp;
2344 
2345 					LLVMValueRef v_pergroupp;
2346 
2347 					LLVMValueRef v_retval;
2348 
2349 					LLVMValueRef v_tmpcontext;
2350 					LLVMValueRef v_oldcontext;
2351 
2352 					aggstate = op->d.agg_trans.aggstate;
2353 					pertrans = op->d.agg_trans.pertrans;
2354 
2355 					fcinfo = &pertrans->transfn_fcinfo;
2356 
2357 					v_aggstatep = l_ptr_const(aggstate,
2358 											  l_ptr(StructAggState));
2359 					v_pertransp = l_ptr_const(pertrans,
2360 											  l_ptr(StructAggStatePerTransData));
2361 
2362 					/*
2363 					 * pergroup = &aggstate->all_pergroups
2364 					 * [op->d.agg_strict_trans_check.setoff]
2365 					 * [op->d.agg_init_trans_check.transno];
2366 					 */
2367 					v_allpergroupsp =
2368 						l_load_struct_gep(b, v_aggstatep,
2369 										  FIELDNO_AGGSTATE_ALL_PERGROUPS,
2370 										  "aggstate.all_pergroups");
2371 					v_setoff = l_int32_const(op->d.agg_trans.setoff);
2372 					v_transno = l_int32_const(op->d.agg_trans.transno);
2373 					v_pergroupp =
2374 						LLVMBuildGEP(b,
2375 									 l_load_gep1(b, v_allpergroupsp, v_setoff, ""),
2376 									 &v_transno, 1, "");
2377 
2378 					v_fcinfo = l_ptr_const(fcinfo,
2379 										   l_ptr(StructFunctionCallInfoData));
2380 
2381 					v_argnullp =
2382 						LLVMBuildStructGEP(b,
2383 										   v_fcinfo,
2384 										   FIELDNO_FUNCTIONCALLINFODATA_ARGNULL,
2385 										   "v_argnullp");
2386 					v_argp =
2387 						LLVMBuildStructGEP(b,
2388 										   v_fcinfo,
2389 										   FIELDNO_FUNCTIONCALLINFODATA_ARG,
2390 										   "v_argp");
2391 
2392 					v_aggcontext = l_ptr_const(op->d.agg_trans.aggcontext,
2393 											   l_ptr(StructExprContext));
2394 
2395 					v_current_setp =
2396 						LLVMBuildStructGEP(b,
2397 										   v_aggstatep,
2398 										   FIELDNO_AGGSTATE_CURRENT_SET,
2399 										   "aggstate.current_set");
2400 					v_curaggcontext =
2401 						LLVMBuildStructGEP(b,
2402 										   v_aggstatep,
2403 										   FIELDNO_AGGSTATE_CURAGGCONTEXT,
2404 										   "aggstate.curaggcontext");
2405 					v_current_pertransp =
2406 						LLVMBuildStructGEP(b,
2407 										   v_aggstatep,
2408 										   FIELDNO_AGGSTATE_CURPERTRANS,
2409 										   "aggstate.curpertrans");
2410 
2411 					/* set aggstate globals */
2412 					LLVMBuildStore(b, v_aggcontext, v_curaggcontext);
2413 					LLVMBuildStore(b, l_int32_const(op->d.agg_trans.setno),
2414 								   v_current_setp);
2415 					LLVMBuildStore(b, v_pertransp, v_current_pertransp);
2416 
2417 					/* invoke transition function in per-tuple context */
2418 					v_tmpcontext =
2419 						l_ptr_const(aggstate->tmpcontext->ecxt_per_tuple_memory,
2420 									l_ptr(StructMemoryContextData));
2421 					v_oldcontext = l_mcxt_switch(mod, b, v_tmpcontext);
2422 
2423 					/* store transvalue in fcinfo->arg/argnull[0] */
2424 					v_transvaluep =
2425 						LLVMBuildStructGEP(b, v_pergroupp,
2426 										   FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE,
2427 										   "transvalue");
2428 					v_transnullp =
2429 						LLVMBuildStructGEP(b, v_pergroupp,
2430 										   FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
2431 										   "transnullp");
2432 					LLVMBuildStore(b,
2433 								   LLVMBuildLoad(b, v_transvaluep,
2434 												 "transvalue"),
2435 								   LLVMBuildStructGEP(b, v_argp, 0, ""));
2436 					LLVMBuildStore(b,
2437 								   LLVMBuildLoad(b, v_transnullp, "transnull"),
2438 								   LLVMBuildStructGEP(b, v_argnullp, 0, ""));
2439 
2440 					/* and invoke transition function */
2441 					v_retval = BuildV1Call(context, b, mod, fcinfo,
2442 										   &v_fcinfo_isnull);
2443 
2444 					/*
2445 					 * For pass-by-ref datatype, must copy the new value into
2446 					 * aggcontext and free the prior transValue.  But if
2447 					 * transfn returned a pointer to its first input, we don't
2448 					 * need to do anything.  Also, if transfn returned a
2449 					 * pointer to a R/W expanded object that is already a
2450 					 * child of the aggcontext, assume we can adopt that value
2451 					 * without copying it.
2452 					 */
2453 					if (opcode == EEOP_AGG_PLAIN_TRANS)
2454 					{
2455 						LLVMBasicBlockRef b_call;
2456 						LLVMBasicBlockRef b_nocall;
2457 						LLVMValueRef v_fn;
2458 						LLVMValueRef v_transvalue;
2459 						LLVMValueRef v_transnull;
2460 						LLVMValueRef v_newval;
2461 						LLVMValueRef params[6];
2462 
2463 						b_call = l_bb_before_v(opblocks[i + 1],
2464 											   "op.%d.transcall", i);
2465 						b_nocall = l_bb_before_v(opblocks[i + 1],
2466 												 "op.%d.transnocall", i);
2467 
2468 						v_transvalue = LLVMBuildLoad(b, v_transvaluep, "");
2469 						v_transnull = LLVMBuildLoad(b, v_transnullp, "");
2470 
2471 						/*
2472 						 * DatumGetPointer(newVal) !=
2473 						 * DatumGetPointer(pergroup->transValue))
2474 						 */
2475 						LLVMBuildCondBr(b,
2476 										LLVMBuildICmp(b, LLVMIntEQ,
2477 													  v_transvalue,
2478 													  v_retval, ""),
2479 										b_nocall, b_call);
2480 
2481 						/* returned datum not passed datum, reparent */
2482 						LLVMPositionBuilderAtEnd(b, b_call);
2483 
2484 						params[0] = v_aggstatep;
2485 						params[1] = v_pertransp;
2486 						params[2] = v_retval;
2487 						params[3] = LLVMBuildTrunc(b, v_fcinfo_isnull,
2488 												   TypeParamBool, "");
2489 						params[4] = v_transvalue;
2490 						params[5] = LLVMBuildTrunc(b, v_transnull,
2491 												   TypeParamBool, "");
2492 
2493 						v_fn = llvm_get_decl(mod, FuncExecAggTransReparent);
2494 						v_newval =
2495 							LLVMBuildCall(b, v_fn,
2496 										  params, lengthof(params),
2497 										  "");
2498 
2499 						/* store trans value */
2500 						LLVMBuildStore(b, v_newval, v_transvaluep);
2501 						LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
2502 
2503 						l_mcxt_switch(mod, b, v_oldcontext);
2504 						LLVMBuildBr(b, opblocks[i + 1]);
2505 
2506 						/* returned datum passed datum, no need to reparent */
2507 						LLVMPositionBuilderAtEnd(b, b_nocall);
2508 					}
2509 
2510 					/* store trans value */
2511 					LLVMBuildStore(b, v_retval, v_transvaluep);
2512 					LLVMBuildStore(b, v_fcinfo_isnull, v_transnullp);
2513 
2514 					l_mcxt_switch(mod, b, v_oldcontext);
2515 
2516 					LLVMBuildBr(b, opblocks[i + 1]);
2517 					break;
2518 				}
2519 
2520 			case EEOP_AGG_ORDERED_TRANS_DATUM:
2521 				build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransDatum",
2522 								v_state, v_econtext, op);
2523 				LLVMBuildBr(b, opblocks[i + 1]);
2524 				break;
2525 
2526 			case EEOP_AGG_ORDERED_TRANS_TUPLE:
2527 				build_EvalXFunc(b, mod, "ExecEvalAggOrderedTransTuple",
2528 								v_state, v_econtext, op);
2529 				LLVMBuildBr(b, opblocks[i + 1]);
2530 				break;
2531 
2532 			case EEOP_LAST:
2533 				Assert(false);
2534 				break;
2535 		}
2536 	}
2537 
2538 	LLVMDisposeBuilder(b);
2539 
2540 	/*
2541 	 * Don't immediately emit function, instead do so the first time the
2542 	 * expression is actually evaluated. That allows to emit a lot of
2543 	 * functions together, avoiding a lot of repeated llvm and memory
2544 	 * remapping overhead.
2545 	 */
2546 	{
2547 
2548 		CompiledExprState *cstate = palloc0(sizeof(CompiledExprState));
2549 
2550 		cstate->context = context;
2551 		cstate->funcname = funcname;
2552 
2553 		state->evalfunc = ExecRunCompiledExpr;
2554 		state->evalfunc_private = cstate;
2555 	}
2556 
2557 	llvm_leave_fatal_on_oom();
2558 
2559 	INSTR_TIME_SET_CURRENT(endtime);
2560 	INSTR_TIME_ACCUM_DIFF(context->base.instr.generation_counter,
2561 						  endtime, starttime);
2562 
2563 	return true;
2564 }
2565 
2566 /*
2567  * Run compiled expression.
2568  *
2569  * This will only be called the first time a JITed expression is called. We
2570  * first make sure the expression is still up2date, and then get a pointer to
2571  * the emitted function. The latter can be the first thing that triggers
2572  * optimizing and emitting all the generated functions.
2573  */
2574 static Datum
ExecRunCompiledExpr(ExprState * state,ExprContext * econtext,bool * isNull)2575 ExecRunCompiledExpr(ExprState *state, ExprContext *econtext, bool *isNull)
2576 {
2577 	CompiledExprState *cstate = state->evalfunc_private;
2578 	ExprStateEvalFunc func;
2579 
2580 	CheckExprStillValid(state, econtext);
2581 
2582 	llvm_enter_fatal_on_oom();
2583 	func = (ExprStateEvalFunc) llvm_get_function(cstate->context,
2584 												 cstate->funcname);
2585 	llvm_leave_fatal_on_oom();
2586 	Assert(func);
2587 
2588 	/* remove indirection via this function for future calls */
2589 	state->evalfunc = func;
2590 
2591 	return func(state, econtext, isNull);
2592 }
2593 
2594 static LLVMValueRef
BuildV1Call(LLVMJitContext * context,LLVMBuilderRef b,LLVMModuleRef mod,FunctionCallInfo fcinfo,LLVMValueRef * v_fcinfo_isnull)2595 BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
2596 			LLVMModuleRef mod, FunctionCallInfo fcinfo,
2597 			LLVMValueRef *v_fcinfo_isnull)
2598 {
2599 	LLVMValueRef v_fn;
2600 	LLVMValueRef v_fcinfo_isnullp;
2601 	LLVMValueRef v_retval;
2602 	LLVMValueRef v_fcinfo;
2603 
2604 	v_fn = llvm_function_reference(context, b, mod, fcinfo);
2605 
2606 	v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
2607 	v_fcinfo_isnullp = LLVMBuildStructGEP(b, v_fcinfo,
2608 										  FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
2609 										  "v_fcinfo_isnull");
2610 	LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp);
2611 
2612 	v_retval = LLVMBuildCall(b, v_fn, &v_fcinfo, 1, "funccall");
2613 
2614 	if (v_fcinfo_isnull)
2615 		*v_fcinfo_isnull = LLVMBuildLoad(b, v_fcinfo_isnullp, "");
2616 
2617 	/*
2618 	 * Add lifetime-end annotation, signalling that writes to memory don't
2619 	 * have to be retained (important for inlining potential).
2620 	 */
2621 	{
2622 		LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
2623 		LLVMValueRef params[2];
2624 
2625 		params[0] = l_int64_const(sizeof(fcinfo->arg));
2626 		params[1] = l_ptr_const(fcinfo->arg, l_ptr(LLVMInt8Type()));
2627 		LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
2628 
2629 		params[0] = l_int64_const(sizeof(fcinfo->argnull));
2630 		params[1] = l_ptr_const(fcinfo->argnull, l_ptr(LLVMInt8Type()));
2631 		LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
2632 
2633 		params[0] = l_int64_const(sizeof(fcinfo->isnull));
2634 		params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8Type()));
2635 		LLVMBuildCall(b, v_lifetime, params, lengthof(params), "");
2636 	}
2637 
2638 	return v_retval;
2639 }
2640 
2641 /*
2642  * Implement an expression step by calling the function funcname.
2643  */
2644 static void
build_EvalXFunc(LLVMBuilderRef b,LLVMModuleRef mod,const char * funcname,LLVMValueRef v_state,LLVMValueRef v_econtext,ExprEvalStep * op)2645 build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
2646 				LLVMValueRef v_state, LLVMValueRef v_econtext,
2647 				ExprEvalStep *op)
2648 {
2649 	LLVMTypeRef sig;
2650 	LLVMValueRef v_fn;
2651 	LLVMTypeRef param_types[3];
2652 	LLVMValueRef params[3];
2653 
2654 	v_fn = LLVMGetNamedFunction(mod, funcname);
2655 	if (!v_fn)
2656 	{
2657 		param_types[0] = l_ptr(StructExprState);
2658 		param_types[1] = l_ptr(StructExprEvalStep);
2659 		param_types[2] = l_ptr(StructExprContext);
2660 
2661 		sig = LLVMFunctionType(LLVMVoidType(),
2662 							   param_types, lengthof(param_types),
2663 							   false);
2664 		v_fn = LLVMAddFunction(mod, funcname, sig);
2665 	}
2666 
2667 	params[0] = v_state;
2668 	params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
2669 	params[2] = v_econtext;
2670 
2671 	LLVMBuildCall(b,
2672 				  v_fn,
2673 				  params, lengthof(params), "");
2674 }
2675 
2676 static LLVMValueRef
create_LifetimeEnd(LLVMModuleRef mod)2677 create_LifetimeEnd(LLVMModuleRef mod)
2678 {
2679 	LLVMTypeRef sig;
2680 	LLVMValueRef fn;
2681 	LLVMTypeRef param_types[2];
2682 
2683 	/* LLVM 5+ has a variadic pointer argument */
2684 #if LLVM_VERSION_MAJOR < 5
2685 	const char *nm = "llvm.lifetime.end";
2686 #else
2687 	const char *nm = "llvm.lifetime.end.p0i8";
2688 #endif
2689 
2690 	fn = LLVMGetNamedFunction(mod, nm);
2691 	if (fn)
2692 		return fn;
2693 
2694 	param_types[0] = LLVMInt64Type();
2695 	param_types[1] = l_ptr(LLVMInt8Type());
2696 
2697 	sig = LLVMFunctionType(LLVMVoidType(),
2698 						   param_types, lengthof(param_types),
2699 						   false);
2700 	fn = LLVMAddFunction(mod, nm, sig);
2701 
2702 	LLVMSetFunctionCallConv(fn, LLVMCCallConv);
2703 
2704 	Assert(LLVMGetIntrinsicID(fn));
2705 
2706 	return fn;
2707 }
2708