jit: Support opaque pointers in LLVM 16.

Remove use of LLVMGetElementType() and provide the type of all pointers
to LLVMBuildXXX() functions when emitting IR, as required by modern LLVM
versions[1].

 * For LLVM <= 14, we'll still use the old LLVMBuildXXX() functions.
 * For LLVM == 15, we'll continue to do the same, explicitly opting
   out of opaque pointer mode.
 * For LLVM >= 16, we'll use the new LLVMBuildXXX2() functions that take
   the extra type argument.

The difference is hidden behind some new IR emitting wrapper functions
l_load(), l_gep(), l_call() etc.  The change is mostly mechanical,
except that at each site the correct type had to be provided.

In some places we needed to do some extra work to get functions types,
including some new wrappers for C++ APIs that are not yet exposed by in
LLVM's C API, and some new "example" functions in llvmjit_types.c
because it's no longer possible to start from the function pointer type
and ask for the function type.

Back-patch to 12, because it's a little tricker in 11 and we agreed not
to put the latest LLVM support into the upcoming final release of 11.

[1] https://llvm.org/docs/OpaquePointers.html

Reviewed-by: Dmitry Dolgov <9erthalion6@gmail.com>
Reviewed-by: Ronan Dunklau <ronan.dunklau@aiven.io>
Reviewed-by: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CA%2BhUKGKNX_%3Df%2B1C4r06WETKTq0G4Z_7q4L4Fxn5WWpMycDj9Fw%40mail.gmail.com
This commit is contained in:
Thomas Munro 2023-10-18 22:09:05 +13:00
parent 0e32652a79
commit 15ddc9725e
7 changed files with 563 additions and 381 deletions

View File

@ -89,18 +89,12 @@ LLVMTypeRef StructExprState;
LLVMTypeRef StructAggState; LLVMTypeRef StructAggState;
LLVMTypeRef StructAggStatePerGroupData; LLVMTypeRef StructAggStatePerGroupData;
LLVMTypeRef StructAggStatePerTransData; LLVMTypeRef StructAggStatePerTransData;
LLVMTypeRef StructPlanState;
LLVMValueRef AttributeTemplate; LLVMValueRef AttributeTemplate;
LLVMValueRef FuncStrlen; LLVMValueRef ExecEvalSubroutineTemplate;
LLVMValueRef FuncVarsizeAny;
LLVMValueRef FuncSlotGetsomeattrsInt;
LLVMValueRef FuncSlotGetmissingattrs;
LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
LLVMValueRef FuncExecEvalSubscriptingRef;
LLVMValueRef FuncExecEvalSysVar;
LLVMValueRef FuncExecAggTransReparent;
LLVMValueRef FuncExecAggInitGroup;
LLVMModuleRef llvm_types_module = NULL;
static bool llvm_session_initialized = false; static bool llvm_session_initialized = false;
static size_t llvm_generation = 0; static size_t llvm_generation = 0;
@ -382,26 +376,71 @@ llvm_get_function(LLVMJitContext *context, const char *funcname)
} }
/* /*
* Return declaration for passed function, adding it to the module if * Return type of a variable in llvmjit_types.c. This is useful to keep types
* necessary. * in sync between plain C and JIT related code.
*/
LLVMTypeRef
llvm_pg_var_type(const char *varname)
{
LLVMValueRef v_srcvar;
LLVMTypeRef typ;
/* this'll return a *pointer* to the global */
v_srcvar = LLVMGetNamedGlobal(llvm_types_module, varname);
if (!v_srcvar)
elog(ERROR, "variable %s not in llvmjit_types.c", varname);
typ = LLVMGlobalGetValueType(v_srcvar);
return typ;
}
/*
* Return function type of a variable in llvmjit_types.c. This is useful to
* keep function types in sync between C and JITed code.
*/
LLVMTypeRef
llvm_pg_var_func_type(const char *varname)
{
LLVMValueRef v_srcvar;
LLVMTypeRef typ;
v_srcvar = LLVMGetNamedFunction(llvm_types_module, varname);
if (!v_srcvar)
elog(ERROR, "function %s not in llvmjit_types.c", varname);
typ = LLVMGetFunctionType(v_srcvar);
return typ;
}
/*
* Return declaration for a function referenced in llvmjit_types.c, adding it
* to the module if necessary.
* *
* This is used to make functions imported by llvm_create_types() known to the * This is used to make functions discovered via llvm_create_types() known to
* module that's currently being worked on. * the module that's currently being worked on.
*/ */
LLVMValueRef LLVMValueRef
llvm_get_decl(LLVMModuleRef mod, LLVMValueRef v_src) llvm_pg_func(LLVMModuleRef mod, const char *funcname)
{ {
LLVMValueRef v_srcfn;
LLVMValueRef v_fn; LLVMValueRef v_fn;
/* don't repeatedly add function */ /* don't repeatedly add function */
v_fn = LLVMGetNamedFunction(mod, LLVMGetValueName(v_src)); v_fn = LLVMGetNamedFunction(mod, funcname);
if (v_fn) if (v_fn)
return v_fn; return v_fn;
v_srcfn = LLVMGetNamedFunction(llvm_types_module, funcname);
if (!v_srcfn)
elog(ERROR, "function %s not in llvmjit_types.c", funcname);
v_fn = LLVMAddFunction(mod, v_fn = LLVMAddFunction(mod,
LLVMGetValueName(v_src), funcname,
LLVMGetElementType(LLVMTypeOf(v_src))); LLVMGetFunctionType(v_srcfn));
llvm_copy_attributes(v_src, v_fn); llvm_copy_attributes(v_srcfn, v_fn);
return v_fn; return v_fn;
} }
@ -496,7 +535,7 @@ llvm_function_reference(LLVMJitContext *context,
fcinfo->flinfo->fn_oid); fcinfo->flinfo->fn_oid);
v_fn = LLVMGetNamedGlobal(mod, funcname); v_fn = LLVMGetNamedGlobal(mod, funcname);
if (v_fn != 0) if (v_fn != 0)
return LLVMBuildLoad(builder, v_fn, ""); return l_load(builder, TypePGFunction, v_fn, "");
v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction); v_fn_addr = l_ptr_const(fcinfo->flinfo->fn_addr, TypePGFunction);
@ -506,7 +545,7 @@ llvm_function_reference(LLVMJitContext *context,
LLVMSetLinkage(v_fn, LLVMPrivateLinkage); LLVMSetLinkage(v_fn, LLVMPrivateLinkage);
LLVMSetUnnamedAddr(v_fn, true); LLVMSetUnnamedAddr(v_fn, true);
return LLVMBuildLoad(builder, v_fn, ""); return l_load(builder, TypePGFunction, v_fn, "");
} }
/* check if function already has been added */ /* check if function already has been added */
@ -514,7 +553,7 @@ llvm_function_reference(LLVMJitContext *context,
if (v_fn != 0) if (v_fn != 0)
return v_fn; return v_fn;
v_fn = LLVMAddFunction(mod, funcname, LLVMGetElementType(TypePGFunction)); v_fn = LLVMAddFunction(mod, funcname, LLVMGetFunctionType(AttributeTemplate));
return v_fn; return v_fn;
} }
@ -766,12 +805,15 @@ llvm_session_initialize(void)
LLVMInitializeNativeAsmParser(); LLVMInitializeNativeAsmParser();
/* /*
* When targeting an LLVM version with opaque pointers enabled by * When targeting LLVM 15, turn off opaque pointers for the context we
* default, turn them off for the context we build our code in. We don't * build our code in. We don't need to do so for other contexts (e.g.
* need to do so for other contexts (e.g. llvm_ts_context). Once the IR is * llvm_ts_context). Once the IR is generated, it carries the necessary
* generated, it carries the necessary information. * information.
*
* For 16 and above, opaque pointers must be used, and we have special
* code for that.
*/ */
#if LLVM_VERSION_MAJOR > 14 #if LLVM_VERSION_MAJOR == 15
LLVMContextSetOpaquePointers(LLVMGetGlobalContext(), false); LLVMContextSetOpaquePointers(LLVMGetGlobalContext(), false);
#endif #endif
@ -921,26 +963,6 @@ llvm_shutdown(int code, Datum arg)
#endif /* LLVM_VERSION_MAJOR > 11 */ #endif /* LLVM_VERSION_MAJOR > 11 */
} }
/* helper for llvm_create_types, returning a global var's type */
static LLVMTypeRef
load_type(LLVMModuleRef mod, const char *name)
{
LLVMValueRef value;
LLVMTypeRef typ;
/* this'll return a *pointer* to the global */
value = LLVMGetNamedGlobal(mod, name);
if (!value)
elog(ERROR, "type %s is unknown", name);
/* therefore look at the contained type and return that */
typ = LLVMTypeOf(value);
Assert(typ != NULL);
typ = LLVMGetElementType(typ);
Assert(typ != NULL);
return typ;
}
/* helper for llvm_create_types, returning a function's return type */ /* helper for llvm_create_types, returning a function's return type */
static LLVMTypeRef static LLVMTypeRef
load_return_type(LLVMModuleRef mod, const char *name) load_return_type(LLVMModuleRef mod, const char *name)
@ -953,15 +975,7 @@ load_return_type(LLVMModuleRef mod, const char *name)
if (!value) if (!value)
elog(ERROR, "function %s is unknown", name); elog(ERROR, "function %s is unknown", name);
/* get type of function pointer */ typ = LLVMGetFunctionReturnType(value); /* in llvmjit_wrap.cpp */
typ = LLVMTypeOf(value);
Assert(typ != NULL);
/* dereference pointer */
typ = LLVMGetElementType(typ);
Assert(typ != NULL);
/* and look at return type */
typ = LLVMGetReturnType(typ);
Assert(typ != NULL);
return typ; return typ;
} }
@ -978,7 +992,6 @@ llvm_create_types(void)
char path[MAXPGPATH]; char path[MAXPGPATH];
LLVMMemoryBufferRef buf; LLVMMemoryBufferRef buf;
char *msg; char *msg;
LLVMModuleRef mod = NULL;
snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc"); snprintf(path, MAXPGPATH, "%s/%s", pkglib_path, "llvmjit_types.bc");
@ -990,7 +1003,7 @@ llvm_create_types(void)
} }
/* eagerly load contents, going to need it all */ /* eagerly load contents, going to need it all */
if (LLVMParseBitcode2(buf, &mod)) if (LLVMParseBitcode2(buf, &llvm_types_module))
{ {
elog(ERROR, "LLVMParseBitcode2 of %s failed", path); elog(ERROR, "LLVMParseBitcode2 of %s failed", path);
} }
@ -1000,45 +1013,33 @@ llvm_create_types(void)
* Load triple & layout from clang emitted file so we're guaranteed to be * Load triple & layout from clang emitted file so we're guaranteed to be
* compatible. * compatible.
*/ */
llvm_triple = pstrdup(LLVMGetTarget(mod)); llvm_triple = pstrdup(LLVMGetTarget(llvm_types_module));
llvm_layout = pstrdup(LLVMGetDataLayoutStr(mod)); llvm_layout = pstrdup(LLVMGetDataLayoutStr(llvm_types_module));
TypeSizeT = load_type(mod, "TypeSizeT"); TypeSizeT = llvm_pg_var_type("TypeSizeT");
TypeParamBool = load_return_type(mod, "FunctionReturningBool"); TypeParamBool = load_return_type(llvm_types_module, "FunctionReturningBool");
TypeStorageBool = load_type(mod, "TypeStorageBool"); TypeStorageBool = llvm_pg_var_type("TypeStorageBool");
TypePGFunction = load_type(mod, "TypePGFunction"); TypePGFunction = llvm_pg_var_type("TypePGFunction");
StructNullableDatum = load_type(mod, "StructNullableDatum"); StructNullableDatum = llvm_pg_var_type("StructNullableDatum");
StructExprContext = load_type(mod, "StructExprContext"); StructExprContext = llvm_pg_var_type("StructExprContext");
StructExprEvalStep = load_type(mod, "StructExprEvalStep"); StructExprEvalStep = llvm_pg_var_type("StructExprEvalStep");
StructExprState = load_type(mod, "StructExprState"); StructExprState = llvm_pg_var_type("StructExprState");
StructFunctionCallInfoData = load_type(mod, "StructFunctionCallInfoData"); StructFunctionCallInfoData = llvm_pg_var_type("StructFunctionCallInfoData");
StructMemoryContextData = load_type(mod, "StructMemoryContextData"); StructMemoryContextData = llvm_pg_var_type("StructMemoryContextData");
StructTupleTableSlot = load_type(mod, "StructTupleTableSlot"); StructTupleTableSlot = llvm_pg_var_type("StructTupleTableSlot");
StructHeapTupleTableSlot = load_type(mod, "StructHeapTupleTableSlot"); StructHeapTupleTableSlot = llvm_pg_var_type("StructHeapTupleTableSlot");
StructMinimalTupleTableSlot = load_type(mod, "StructMinimalTupleTableSlot"); StructMinimalTupleTableSlot = llvm_pg_var_type("StructMinimalTupleTableSlot");
StructHeapTupleData = load_type(mod, "StructHeapTupleData"); StructHeapTupleData = llvm_pg_var_type("StructHeapTupleData");
StructTupleDescData = load_type(mod, "StructTupleDescData"); StructHeapTupleHeaderData = llvm_pg_var_type("StructHeapTupleHeaderData");
StructAggState = load_type(mod, "StructAggState"); StructTupleDescData = llvm_pg_var_type("StructTupleDescData");
StructAggStatePerGroupData = load_type(mod, "StructAggStatePerGroupData"); StructAggState = llvm_pg_var_type("StructAggState");
StructAggStatePerTransData = load_type(mod, "StructAggStatePerTransData"); StructAggStatePerGroupData = llvm_pg_var_type("StructAggStatePerGroupData");
StructAggStatePerTransData = llvm_pg_var_type("StructAggStatePerTransData");
StructPlanState = llvm_pg_var_type("StructPlanState");
StructMinimalTupleData = llvm_pg_var_type("StructMinimalTupleData");
AttributeTemplate = LLVMGetNamedFunction(mod, "AttributeTemplate"); AttributeTemplate = LLVMGetNamedFunction(llvm_types_module, "AttributeTemplate");
FuncStrlen = LLVMGetNamedFunction(mod, "strlen"); ExecEvalSubroutineTemplate = LLVMGetNamedFunction(llvm_types_module, "ExecEvalSubroutineTemplate");
FuncVarsizeAny = LLVMGetNamedFunction(mod, "varsize_any");
FuncSlotGetsomeattrsInt = LLVMGetNamedFunction(mod, "slot_getsomeattrs_int");
FuncSlotGetmissingattrs = LLVMGetNamedFunction(mod, "slot_getmissingattrs");
FuncMakeExpandedObjectReadOnlyInternal = LLVMGetNamedFunction(mod, "MakeExpandedObjectReadOnlyInternal");
FuncExecEvalSubscriptingRef = LLVMGetNamedFunction(mod, "ExecEvalSubscriptingRef");
FuncExecEvalSysVar = LLVMGetNamedFunction(mod, "ExecEvalSysVar");
FuncExecAggTransReparent = LLVMGetNamedFunction(mod, "ExecAggTransReparent");
FuncExecAggInitGroup = LLVMGetNamedFunction(mod, "ExecAggInitGroup");
/*
* Leave the module alive, otherwise references to function would be
* dangling.
*/
return;
} }
/* /*

View File

@ -187,13 +187,13 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_slot = LLVMGetParam(v_deform_fn, 0); v_slot = LLVMGetParam(v_deform_fn, 0);
v_tts_values = v_tts_values =
l_load_struct_gep(b, v_slot, FIELDNO_TUPLETABLESLOT_VALUES, l_load_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_VALUES,
"tts_values"); "tts_values");
v_tts_nulls = v_tts_nulls =
l_load_struct_gep(b, v_slot, FIELDNO_TUPLETABLESLOT_ISNULL, l_load_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_ISNULL,
"tts_ISNULL"); "tts_ISNULL");
v_flagsp = LLVMBuildStructGEP(b, v_slot, FIELDNO_TUPLETABLESLOT_FLAGS, ""); v_flagsp = l_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_FLAGS, "");
v_nvalidp = LLVMBuildStructGEP(b, v_slot, FIELDNO_TUPLETABLESLOT_NVALID, ""); v_nvalidp = l_struct_gep(b, StructTupleTableSlot, v_slot, FIELDNO_TUPLETABLESLOT_NVALID, "");
if (ops == &TTSOpsHeapTuple || ops == &TTSOpsBufferHeapTuple) if (ops == &TTSOpsHeapTuple || ops == &TTSOpsBufferHeapTuple)
{ {
@ -204,9 +204,9 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_slot, v_slot,
l_ptr(StructHeapTupleTableSlot), l_ptr(StructHeapTupleTableSlot),
"heapslot"); "heapslot");
v_slotoffp = LLVMBuildStructGEP(b, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_OFF, ""); v_slotoffp = l_struct_gep(b, StructHeapTupleTableSlot, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_OFF, "");
v_tupleheaderp = v_tupleheaderp =
l_load_struct_gep(b, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_TUPLE, l_load_struct_gep(b, StructHeapTupleTableSlot, v_heapslot, FIELDNO_HEAPTUPLETABLESLOT_TUPLE,
"tupleheader"); "tupleheader");
} }
@ -219,9 +219,15 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_slot, v_slot,
l_ptr(StructMinimalTupleTableSlot), l_ptr(StructMinimalTupleTableSlot),
"minimalslot"); "minimalslot");
v_slotoffp = LLVMBuildStructGEP(b, v_minimalslot, FIELDNO_MINIMALTUPLETABLESLOT_OFF, ""); v_slotoffp = l_struct_gep(b,
StructMinimalTupleTableSlot,
v_minimalslot,
FIELDNO_MINIMALTUPLETABLESLOT_OFF, "");
v_tupleheaderp = v_tupleheaderp =
l_load_struct_gep(b, v_minimalslot, FIELDNO_MINIMALTUPLETABLESLOT_TUPLE, l_load_struct_gep(b,
StructMinimalTupleTableSlot,
v_minimalslot,
FIELDNO_MINIMALTUPLETABLESLOT_TUPLE,
"tupleheader"); "tupleheader");
} }
else else
@ -231,21 +237,29 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
} }
v_tuplep = v_tuplep =
l_load_struct_gep(b, v_tupleheaderp, FIELDNO_HEAPTUPLEDATA_DATA, l_load_struct_gep(b,
StructHeapTupleData,
v_tupleheaderp,
FIELDNO_HEAPTUPLEDATA_DATA,
"tuple"); "tuple");
v_bits = v_bits =
LLVMBuildBitCast(b, LLVMBuildBitCast(b,
LLVMBuildStructGEP(b, v_tuplep, l_struct_gep(b,
FIELDNO_HEAPTUPLEHEADERDATA_BITS, StructHeapTupleHeaderData,
""), v_tuplep,
FIELDNO_HEAPTUPLEHEADERDATA_BITS,
""),
l_ptr(LLVMInt8Type()), l_ptr(LLVMInt8Type()),
"t_bits"); "t_bits");
v_infomask1 = v_infomask1 =
l_load_struct_gep(b, v_tuplep, l_load_struct_gep(b,
StructHeapTupleHeaderData,
v_tuplep,
FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK, FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK,
"infomask1"); "infomask1");
v_infomask2 = v_infomask2 =
l_load_struct_gep(b, l_load_struct_gep(b,
StructHeapTupleHeaderData,
v_tuplep, FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2, v_tuplep, FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2,
"infomask2"); "infomask2");
@ -270,19 +284,21 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
*/ */
v_hoff = v_hoff =
LLVMBuildZExt(b, LLVMBuildZExt(b,
l_load_struct_gep(b, v_tuplep, l_load_struct_gep(b,
StructHeapTupleHeaderData,
v_tuplep,
FIELDNO_HEAPTUPLEHEADERDATA_HOFF, FIELDNO_HEAPTUPLEHEADERDATA_HOFF,
""), ""),
LLVMInt32Type(), "t_hoff"); LLVMInt32Type(), "t_hoff");
v_tupdata_base = v_tupdata_base = l_gep(b,
LLVMBuildGEP(b, LLVMInt8Type(),
LLVMBuildBitCast(b, LLVMBuildBitCast(b,
v_tuplep, v_tuplep,
l_ptr(LLVMInt8Type()), l_ptr(LLVMInt8Type()),
""), ""),
&v_hoff, 1, &v_hoff, 1,
"v_tupdata_base"); "v_tupdata_base");
/* /*
* Load tuple start offset from slot. Will be reset below in case there's * Load tuple start offset from slot. Will be reset below in case there's
@ -291,7 +307,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
{ {
LLVMValueRef v_off_start; LLVMValueRef v_off_start;
v_off_start = LLVMBuildLoad(b, v_slotoffp, "v_slot_off"); v_off_start = l_load(b, LLVMInt32Type(), v_slotoffp, "v_slot_off");
v_off_start = LLVMBuildZExt(b, v_off_start, TypeSizeT, ""); v_off_start = LLVMBuildZExt(b, v_off_start, TypeSizeT, "");
LLVMBuildStore(b, v_off_start, v_offp); LLVMBuildStore(b, v_off_start, v_offp);
} }
@ -331,6 +347,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
else else
{ {
LLVMValueRef v_params[3]; LLVMValueRef v_params[3];
LLVMValueRef f;
/* branch if not all columns available */ /* branch if not all columns available */
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
@ -347,14 +364,16 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_params[0] = v_slot; v_params[0] = v_slot;
v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), ""); v_params[1] = LLVMBuildZExt(b, v_maxatt, LLVMInt32Type(), "");
v_params[2] = l_int32_const(natts); v_params[2] = l_int32_const(natts);
LLVMBuildCall(b, llvm_get_decl(mod, FuncSlotGetmissingattrs), f = llvm_pg_func(mod, "slot_getmissingattrs");
v_params, lengthof(v_params), ""); l_call(b,
LLVMGetFunctionType(f), f,
v_params, lengthof(v_params), "");
LLVMBuildBr(b, b_find_start); LLVMBuildBr(b, b_find_start);
} }
LLVMPositionBuilderAtEnd(b, b_find_start); LLVMPositionBuilderAtEnd(b, b_find_start);
v_nvalid = LLVMBuildLoad(b, v_nvalidp, ""); v_nvalid = l_load(b, LLVMInt16Type(), v_nvalidp, "");
/* /*
* Build switch to go from nvalid to the right startblock. Callers * Build switch to go from nvalid to the right startblock. Callers
@ -456,7 +475,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
v_nullbyteno = l_int32_const(attnum >> 3); v_nullbyteno = l_int32_const(attnum >> 3);
v_nullbytemask = l_int8_const(1 << ((attnum) & 0x07)); v_nullbytemask = l_int8_const(1 << ((attnum) & 0x07));
v_nullbyte = l_load_gep1(b, v_bits, v_nullbyteno, "attnullbyte"); v_nullbyte = l_load_gep1(b, LLVMInt8Type(), v_bits, v_nullbyteno, "attnullbyte");
v_nullbit = LLVMBuildICmp(b, v_nullbit = LLVMBuildICmp(b,
LLVMIntEQ, LLVMIntEQ,
@ -473,11 +492,11 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* store null-byte */ /* store null-byte */
LLVMBuildStore(b, LLVMBuildStore(b,
l_int8_const(1), l_int8_const(1),
LLVMBuildGEP(b, v_tts_nulls, &l_attno, 1, "")); l_gep(b, LLVMInt8Type(), v_tts_nulls, &l_attno, 1, ""));
/* store zero datum */ /* store zero datum */
LLVMBuildStore(b, LLVMBuildStore(b,
l_sizet_const(0), l_sizet_const(0),
LLVMBuildGEP(b, v_tts_values, &l_attno, 1, "")); l_gep(b, TypeSizeT, v_tts_values, &l_attno, 1, ""));
LLVMBuildBr(b, b_next); LLVMBuildBr(b, b_next);
attguaranteedalign = false; attguaranteedalign = false;
@ -536,10 +555,10 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* don't know if short varlena or not */ /* don't know if short varlena or not */
attguaranteedalign = false; attguaranteedalign = false;
v_off = LLVMBuildLoad(b, v_offp, ""); v_off = l_load(b, TypeSizeT, v_offp, "");
v_possible_padbyte = v_possible_padbyte =
l_load_gep1(b, v_tupdata_base, v_off, "padbyte"); l_load_gep1(b, LLVMInt8Type(), v_tupdata_base, v_off, "padbyte");
v_ispad = v_ispad =
LLVMBuildICmp(b, LLVMIntEQ, LLVMBuildICmp(b, LLVMIntEQ,
v_possible_padbyte, l_int8_const(0), v_possible_padbyte, l_int8_const(0),
@ -558,7 +577,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* translation of alignment code (cf TYPEALIGN()) */ /* translation of alignment code (cf TYPEALIGN()) */
{ {
LLVMValueRef v_off_aligned; LLVMValueRef v_off_aligned;
LLVMValueRef v_off = LLVMBuildLoad(b, v_offp, ""); LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
/* ((ALIGNVAL) - 1) */ /* ((ALIGNVAL) - 1) */
LLVMValueRef v_alignval = l_sizet_const(alignto - 1); LLVMValueRef v_alignval = l_sizet_const(alignto - 1);
@ -647,18 +666,18 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
/* compute address to load data from */ /* compute address to load data from */
{ {
LLVMValueRef v_off = LLVMBuildLoad(b, v_offp, ""); LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
v_attdatap = v_attdatap =
LLVMBuildGEP(b, v_tupdata_base, &v_off, 1, ""); l_gep(b, LLVMInt8Type(), v_tupdata_base, &v_off, 1, "");
} }
/* compute address to store value at */ /* compute address to store value at */
v_resultp = LLVMBuildGEP(b, v_tts_values, &l_attno, 1, ""); v_resultp = l_gep(b, TypeSizeT, v_tts_values, &l_attno, 1, "");
/* store null-byte (false) */ /* store null-byte (false) */
LLVMBuildStore(b, l_int8_const(0), LLVMBuildStore(b, l_int8_const(0),
LLVMBuildGEP(b, v_tts_nulls, &l_attno, 1, "")); l_gep(b, TypeStorageBool, v_tts_nulls, &l_attno, 1, ""));
/* /*
* Store datum. For byval: datums copy the value, extend to Datum's * Store datum. For byval: datums copy the value, extend to Datum's
@ -667,12 +686,12 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
if (att->attbyval) if (att->attbyval)
{ {
LLVMValueRef v_tmp_loaddata; LLVMValueRef v_tmp_loaddata;
LLVMTypeRef vartypep = LLVMTypeRef vartype = LLVMIntType(att->attlen * 8);
LLVMPointerType(LLVMIntType(att->attlen * 8), 0); LLVMTypeRef vartypep = LLVMPointerType(vartype, 0);
v_tmp_loaddata = v_tmp_loaddata =
LLVMBuildPointerCast(b, v_attdatap, vartypep, ""); LLVMBuildPointerCast(b, v_attdatap, vartypep, "");
v_tmp_loaddata = LLVMBuildLoad(b, v_tmp_loaddata, "attr_byval"); v_tmp_loaddata = l_load(b, vartype, v_tmp_loaddata, "attr_byval");
v_tmp_loaddata = LLVMBuildZExt(b, v_tmp_loaddata, TypeSizeT, ""); v_tmp_loaddata = LLVMBuildZExt(b, v_tmp_loaddata, TypeSizeT, "");
LLVMBuildStore(b, v_tmp_loaddata, v_resultp); LLVMBuildStore(b, v_tmp_loaddata, v_resultp);
@ -697,18 +716,20 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
} }
else if (att->attlen == -1) else if (att->attlen == -1)
{ {
v_incby = LLVMBuildCall(b, v_incby = l_call(b,
llvm_get_decl(mod, FuncVarsizeAny), llvm_pg_var_func_type("varsize_any"),
&v_attdatap, 1, llvm_pg_func(mod, "varsize_any"),
"varsize_any"); &v_attdatap, 1,
"varsize_any");
l_callsite_ro(v_incby); l_callsite_ro(v_incby);
l_callsite_alwaysinline(v_incby); l_callsite_alwaysinline(v_incby);
} }
else if (att->attlen == -2) else if (att->attlen == -2)
{ {
v_incby = LLVMBuildCall(b, v_incby = l_call(b,
llvm_get_decl(mod, FuncStrlen), llvm_pg_var_func_type("strlen"),
&v_attdatap, 1, "strlen"); llvm_pg_func(mod, "strlen"),
&v_attdatap, 1, "strlen");
l_callsite_ro(v_incby); l_callsite_ro(v_incby);
@ -728,7 +749,7 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
} }
else else
{ {
LLVMValueRef v_off = LLVMBuildLoad(b, v_offp, ""); LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
v_off = LLVMBuildAdd(b, v_off, v_incby, "increment_offset"); v_off = LLVMBuildAdd(b, v_off, v_incby, "increment_offset");
LLVMBuildStore(b, v_off, v_offp); LLVMBuildStore(b, v_off, v_offp);
@ -754,13 +775,13 @@ slot_compile_deform(LLVMJitContext *context, TupleDesc desc,
LLVMPositionBuilderAtEnd(b, b_out); LLVMPositionBuilderAtEnd(b, b_out);
{ {
LLVMValueRef v_off = LLVMBuildLoad(b, v_offp, ""); LLVMValueRef v_off = l_load(b, TypeSizeT, v_offp, "");
LLVMValueRef v_flags; LLVMValueRef v_flags;
LLVMBuildStore(b, l_int16_const(natts), v_nvalidp); LLVMBuildStore(b, l_int16_const(natts), v_nvalidp);
v_off = LLVMBuildTrunc(b, v_off, LLVMInt32Type(), ""); v_off = LLVMBuildTrunc(b, v_off, LLVMInt32Type(), "");
LLVMBuildStore(b, v_off, v_slotoffp); LLVMBuildStore(b, v_off, v_slotoffp);
v_flags = LLVMBuildLoad(b, v_flagsp, "tts_flags"); v_flags = l_load(b, LLVMInt16Type(), v_flagsp, "tts_flags");
v_flags = LLVMBuildOr(b, v_flags, l_int16_const(TTS_FLAG_SLOW), ""); v_flags = LLVMBuildOr(b, v_flags, l_int16_const(TTS_FLAG_SLOW), "");
LLVMBuildStore(b, v_flags, v_flagsp); LLVMBuildStore(b, v_flags, v_flagsp);
LLVMBuildRetVoid(b); LLVMBuildRetVoid(b);

View File

@ -80,7 +80,6 @@ llvm_compile_expr(ExprState *state)
LLVMBuilderRef b; LLVMBuilderRef b;
LLVMModuleRef mod; LLVMModuleRef mod;
LLVMTypeRef eval_sig;
LLVMValueRef eval_fn; LLVMValueRef eval_fn;
LLVMBasicBlockRef entry; LLVMBasicBlockRef entry;
LLVMBasicBlockRef *opblocks; LLVMBasicBlockRef *opblocks;
@ -145,19 +144,9 @@ llvm_compile_expr(ExprState *state)
funcname = llvm_expand_funcname(context, "evalexpr"); funcname = llvm_expand_funcname(context, "evalexpr");
/* Create the signature and function */ /* create function */
{ eval_fn = LLVMAddFunction(mod, funcname,
LLVMTypeRef param_types[3]; llvm_pg_var_func_type("ExecInterpExprStillValid"));
param_types[0] = l_ptr(StructExprState); /* state */
param_types[1] = l_ptr(StructExprContext); /* econtext */
param_types[2] = l_ptr(TypeStorageBool); /* isnull */
eval_sig = LLVMFunctionType(TypeSizeT,
param_types, lengthof(param_types),
false);
}
eval_fn = LLVMAddFunction(mod, funcname, eval_sig);
LLVMSetLinkage(eval_fn, LLVMExternalLinkage); LLVMSetLinkage(eval_fn, LLVMExternalLinkage);
LLVMSetVisibility(eval_fn, LLVMDefaultVisibility); LLVMSetVisibility(eval_fn, LLVMDefaultVisibility);
llvm_copy_attributes(AttributeTemplate, eval_fn); llvm_copy_attributes(AttributeTemplate, eval_fn);
@ -171,58 +160,90 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, entry); LLVMPositionBuilderAtEnd(b, entry);
v_tmpvaluep = LLVMBuildStructGEP(b, v_state, v_tmpvaluep = l_struct_gep(b,
FIELDNO_EXPRSTATE_RESVALUE, StructExprState,
"v.state.resvalue"); v_state,
v_tmpisnullp = LLVMBuildStructGEP(b, v_state, FIELDNO_EXPRSTATE_RESVALUE,
FIELDNO_EXPRSTATE_RESNULL, "v.state.resvalue");
"v.state.resnull"); v_tmpisnullp = l_struct_gep(b,
StructExprState,
v_state,
FIELDNO_EXPRSTATE_RESNULL,
"v.state.resnull");
/* build global slots */ /* build global slots */
v_scanslot = l_load_struct_gep(b, v_econtext, v_scanslot = l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_SCANTUPLE, FIELDNO_EXPRCONTEXT_SCANTUPLE,
"v_scanslot"); "v_scanslot");
v_innerslot = l_load_struct_gep(b, v_econtext, v_innerslot = l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_INNERTUPLE, FIELDNO_EXPRCONTEXT_INNERTUPLE,
"v_innerslot"); "v_innerslot");
v_outerslot = l_load_struct_gep(b, v_econtext, v_outerslot = l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_OUTERTUPLE, FIELDNO_EXPRCONTEXT_OUTERTUPLE,
"v_outerslot"); "v_outerslot");
v_resultslot = l_load_struct_gep(b, v_state, v_resultslot = l_load_struct_gep(b,
StructExprState,
v_state,
FIELDNO_EXPRSTATE_RESULTSLOT, FIELDNO_EXPRSTATE_RESULTSLOT,
"v_resultslot"); "v_resultslot");
/* build global values/isnull pointers */ /* build global values/isnull pointers */
v_scanvalues = l_load_struct_gep(b, v_scanslot, v_scanvalues = l_load_struct_gep(b,
StructTupleTableSlot,
v_scanslot,
FIELDNO_TUPLETABLESLOT_VALUES, FIELDNO_TUPLETABLESLOT_VALUES,
"v_scanvalues"); "v_scanvalues");
v_scannulls = l_load_struct_gep(b, v_scanslot, v_scannulls = l_load_struct_gep(b,
StructTupleTableSlot,
v_scanslot,
FIELDNO_TUPLETABLESLOT_ISNULL, FIELDNO_TUPLETABLESLOT_ISNULL,
"v_scannulls"); "v_scannulls");
v_innervalues = l_load_struct_gep(b, v_innerslot, v_innervalues = l_load_struct_gep(b,
StructTupleTableSlot,
v_innerslot,
FIELDNO_TUPLETABLESLOT_VALUES, FIELDNO_TUPLETABLESLOT_VALUES,
"v_innervalues"); "v_innervalues");
v_innernulls = l_load_struct_gep(b, v_innerslot, v_innernulls = l_load_struct_gep(b,
StructTupleTableSlot,
v_innerslot,
FIELDNO_TUPLETABLESLOT_ISNULL, FIELDNO_TUPLETABLESLOT_ISNULL,
"v_innernulls"); "v_innernulls");
v_outervalues = l_load_struct_gep(b, v_outerslot, v_outervalues = l_load_struct_gep(b,
StructTupleTableSlot,
v_outerslot,
FIELDNO_TUPLETABLESLOT_VALUES, FIELDNO_TUPLETABLESLOT_VALUES,
"v_outervalues"); "v_outervalues");
v_outernulls = l_load_struct_gep(b, v_outerslot, v_outernulls = l_load_struct_gep(b,
StructTupleTableSlot,
v_outerslot,
FIELDNO_TUPLETABLESLOT_ISNULL, FIELDNO_TUPLETABLESLOT_ISNULL,
"v_outernulls"); "v_outernulls");
v_resultvalues = l_load_struct_gep(b, v_resultslot, v_resultvalues = l_load_struct_gep(b,
StructTupleTableSlot,
v_resultslot,
FIELDNO_TUPLETABLESLOT_VALUES, FIELDNO_TUPLETABLESLOT_VALUES,
"v_resultvalues"); "v_resultvalues");
v_resultnulls = l_load_struct_gep(b, v_resultslot, v_resultnulls = l_load_struct_gep(b,
StructTupleTableSlot,
v_resultslot,
FIELDNO_TUPLETABLESLOT_ISNULL, FIELDNO_TUPLETABLESLOT_ISNULL,
"v_resultnulls"); "v_resultnulls");
/* aggvalues/aggnulls */ /* aggvalues/aggnulls */
v_aggvalues = l_load_struct_gep(b, v_econtext, v_aggvalues = l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_AGGVALUES, FIELDNO_EXPRCONTEXT_AGGVALUES,
"v.econtext.aggvalues"); "v.econtext.aggvalues");
v_aggnulls = l_load_struct_gep(b, v_econtext, v_aggnulls = l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_AGGNULLS, FIELDNO_EXPRCONTEXT_AGGNULLS,
"v.econtext.aggnulls"); "v.econtext.aggnulls");
@ -256,8 +277,8 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_tmpisnull, LLVMValueRef v_tmpisnull,
v_tmpvalue; v_tmpvalue;
v_tmpvalue = LLVMBuildLoad(b, v_tmpvaluep, ""); v_tmpvalue = l_load(b, TypeSizeT, v_tmpvaluep, "");
v_tmpisnull = LLVMBuildLoad(b, v_tmpisnullp, ""); v_tmpisnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
LLVMBuildStore(b, v_tmpisnull, v_isnullp); LLVMBuildStore(b, v_tmpisnull, v_isnullp);
@ -300,7 +321,9 @@ llvm_compile_expr(ExprState *state)
* be a virtual slot. * be a virtual slot.
*/ */
v_nvalid = v_nvalid =
l_load_struct_gep(b, v_slot, l_load_struct_gep(b,
StructTupleTableSlot,
v_slot,
FIELDNO_TUPLETABLESLOT_NVALID, FIELDNO_TUPLETABLESLOT_NVALID,
""); "");
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
@ -331,8 +354,10 @@ llvm_compile_expr(ExprState *state)
params[0] = v_slot; params[0] = v_slot;
LLVMBuildCall(b, l_jit_deform, l_call(b,
params, lengthof(params), ""); LLVMGetFunctionType(l_jit_deform),
l_jit_deform,
params, lengthof(params), "");
} }
else else
{ {
@ -341,9 +366,10 @@ llvm_compile_expr(ExprState *state)
params[0] = v_slot; params[0] = v_slot;
params[1] = l_int32_const(op->d.fetch.last_var); params[1] = l_int32_const(op->d.fetch.last_var);
LLVMBuildCall(b, l_call(b,
llvm_get_decl(mod, FuncSlotGetsomeattrsInt), llvm_pg_var_func_type("slot_getsomeattrs_int"),
params, lengthof(params), ""); llvm_pg_func(mod, "slot_getsomeattrs_int"),
params, lengthof(params), "");
} }
LLVMBuildBr(b, opblocks[i + 1]); LLVMBuildBr(b, opblocks[i + 1]);
@ -377,8 +403,8 @@ llvm_compile_expr(ExprState *state)
} }
v_attnum = l_int32_const(op->d.var.attnum); v_attnum = l_int32_const(op->d.var.attnum);
value = l_load_gep1(b, v_values, v_attnum, ""); value = l_load_gep1(b, TypeSizeT, v_values, v_attnum, "");
isnull = l_load_gep1(b, v_nulls, v_attnum, ""); isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
LLVMBuildStore(b, value, v_resvaluep); LLVMBuildStore(b, value, v_resvaluep);
LLVMBuildStore(b, isnull, v_resnullp); LLVMBuildStore(b, isnull, v_resnullp);
@ -405,9 +431,10 @@ llvm_compile_expr(ExprState *state)
v_params[2] = v_econtext; v_params[2] = v_econtext;
v_params[3] = v_slot; v_params[3] = v_slot;
LLVMBuildCall(b, l_call(b,
llvm_get_decl(mod, FuncExecEvalSysVar), llvm_pg_var_func_type("ExecEvalSysVar"),
v_params, lengthof(v_params), ""); llvm_pg_func(mod, "ExecEvalSysVar"),
v_params, lengthof(v_params), "");
LLVMBuildBr(b, opblocks[i + 1]); LLVMBuildBr(b, opblocks[i + 1]);
break; break;
@ -450,15 +477,19 @@ llvm_compile_expr(ExprState *state)
/* load data */ /* load data */
v_attnum = l_int32_const(op->d.assign_var.attnum); v_attnum = l_int32_const(op->d.assign_var.attnum);
v_value = l_load_gep1(b, v_values, v_attnum, ""); v_value = l_load_gep1(b, TypeSizeT, v_values, v_attnum, "");
v_isnull = l_load_gep1(b, v_nulls, v_attnum, ""); v_isnull = l_load_gep1(b, TypeStorageBool, v_nulls, v_attnum, "");
/* compute addresses of targets */ /* compute addresses of targets */
v_resultnum = l_int32_const(op->d.assign_var.resultnum); v_resultnum = l_int32_const(op->d.assign_var.resultnum);
v_rvaluep = LLVMBuildGEP(b, v_resultvalues, v_rvaluep = l_gep(b,
&v_resultnum, 1, ""); TypeSizeT,
v_risnullp = LLVMBuildGEP(b, v_resultnulls, v_resultvalues,
&v_resultnum, 1, ""); &v_resultnum, 1, "");
v_risnullp = l_gep(b,
TypeStorageBool,
v_resultnulls,
&v_resultnum, 1, "");
/* and store */ /* and store */
LLVMBuildStore(b, v_value, v_rvaluep); LLVMBuildStore(b, v_value, v_rvaluep);
@ -478,15 +509,15 @@ llvm_compile_expr(ExprState *state)
size_t resultnum = op->d.assign_tmp.resultnum; size_t resultnum = op->d.assign_tmp.resultnum;
/* load data */ /* load data */
v_value = LLVMBuildLoad(b, v_tmpvaluep, ""); v_value = l_load(b, TypeSizeT, v_tmpvaluep, "");
v_isnull = LLVMBuildLoad(b, v_tmpisnullp, ""); v_isnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
/* compute addresses of targets */ /* compute addresses of targets */
v_resultnum = l_int32_const(resultnum); v_resultnum = l_int32_const(resultnum);
v_rvaluep = v_rvaluep =
LLVMBuildGEP(b, v_resultvalues, &v_resultnum, 1, ""); l_gep(b, TypeSizeT, v_resultvalues, &v_resultnum, 1, "");
v_risnullp = v_risnullp =
LLVMBuildGEP(b, v_resultnulls, &v_resultnum, 1, ""); l_gep(b, TypeStorageBool, v_resultnulls, &v_resultnum, 1, "");
/* and store */ /* and store */
LLVMBuildStore(b, v_value, v_rvaluep); LLVMBuildStore(b, v_value, v_rvaluep);
@ -512,15 +543,15 @@ llvm_compile_expr(ExprState *state)
"op.%d.assign_tmp.notnull", i); "op.%d.assign_tmp.notnull", i);
/* load data */ /* load data */
v_value = LLVMBuildLoad(b, v_tmpvaluep, ""); v_value = l_load(b, TypeSizeT, v_tmpvaluep, "");
v_isnull = LLVMBuildLoad(b, v_tmpisnullp, ""); v_isnull = l_load(b, TypeStorageBool, v_tmpisnullp, "");
/* compute addresses of targets */ /* compute addresses of targets */
v_resultnum = l_int32_const(resultnum); v_resultnum = l_int32_const(resultnum);
v_rvaluep = LLVMBuildGEP(b, v_resultvalues, v_rvaluep =
&v_resultnum, 1, ""); l_gep(b, TypeSizeT, v_resultvalues, &v_resultnum, 1, "");
v_risnullp = LLVMBuildGEP(b, v_resultnulls, v_risnullp =
&v_resultnum, 1, ""); l_gep(b, TypeStorageBool, v_resultnulls, &v_resultnum, 1, "");
/* store nullness */ /* store nullness */
LLVMBuildStore(b, v_isnull, v_risnullp); LLVMBuildStore(b, v_isnull, v_risnullp);
@ -535,9 +566,10 @@ llvm_compile_expr(ExprState *state)
LLVMPositionBuilderAtEnd(b, b_notnull); LLVMPositionBuilderAtEnd(b, b_notnull);
v_params[0] = v_value; v_params[0] = v_value;
v_ret = v_ret =
LLVMBuildCall(b, l_call(b,
llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal), llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), ""); llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), "");
/* store value */ /* store value */
LLVMBuildStore(b, v_ret, v_rvaluep); LLVMBuildStore(b, v_ret, v_rvaluep);
@ -699,8 +731,8 @@ llvm_compile_expr(ExprState *state)
v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull, v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
l_ptr(TypeStorageBool)); l_ptr(TypeStorageBool));
v_boolnull = LLVMBuildLoad(b, v_resnullp, ""); v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
v_boolvalue = LLVMBuildLoad(b, v_resvaluep, ""); v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
/* set resnull to boolnull */ /* set resnull to boolnull */
LLVMBuildStore(b, v_boolnull, v_resnullp); LLVMBuildStore(b, v_boolnull, v_resnullp);
@ -741,7 +773,7 @@ llvm_compile_expr(ExprState *state)
/* Build block that continues if bool is TRUE. */ /* Build block that continues if bool is TRUE. */
LLVMPositionBuilderAtEnd(b, b_boolcont); LLVMPositionBuilderAtEnd(b, b_boolcont);
v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, ""); v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
/* set value to NULL if any previous values were NULL */ /* set value to NULL if any previous values were NULL */
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
@ -801,8 +833,8 @@ llvm_compile_expr(ExprState *state)
v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull, v_boolanynullp = l_ptr_const(op->d.boolexpr.anynull,
l_ptr(TypeStorageBool)); l_ptr(TypeStorageBool));
v_boolnull = LLVMBuildLoad(b, v_resnullp, ""); v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
v_boolvalue = LLVMBuildLoad(b, v_resvaluep, ""); v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
/* set resnull to boolnull */ /* set resnull to boolnull */
LLVMBuildStore(b, v_boolnull, v_resnullp); LLVMBuildStore(b, v_boolnull, v_resnullp);
@ -842,7 +874,7 @@ llvm_compile_expr(ExprState *state)
/* build block that continues if bool is FALSE */ /* build block that continues if bool is FALSE */
LLVMPositionBuilderAtEnd(b, b_boolcont); LLVMPositionBuilderAtEnd(b, b_boolcont);
v_boolanynull = LLVMBuildLoad(b, v_boolanynullp, ""); v_boolanynull = l_load(b, TypeStorageBool, v_boolanynullp, "");
/* set value to NULL if any previous values were NULL */ /* set value to NULL if any previous values were NULL */
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
@ -866,8 +898,8 @@ llvm_compile_expr(ExprState *state)
LLVMValueRef v_boolnull; LLVMValueRef v_boolnull;
LLVMValueRef v_negbool; LLVMValueRef v_negbool;
v_boolnull = LLVMBuildLoad(b, v_resnullp, ""); v_boolnull = l_load(b, TypeStorageBool, v_resnullp, "");
v_boolvalue = LLVMBuildLoad(b, v_resvaluep, ""); v_boolvalue = l_load(b, TypeSizeT, v_resvaluep, "");
v_negbool = LLVMBuildZExt(b, v_negbool = LLVMBuildZExt(b,
LLVMBuildICmp(b, LLVMIntEQ, LLVMBuildICmp(b, LLVMIntEQ,
@ -894,8 +926,8 @@ llvm_compile_expr(ExprState *state)
b_qualfail = l_bb_before_v(opblocks[i + 1], b_qualfail = l_bb_before_v(opblocks[i + 1],
"op.%d.qualfail", i); "op.%d.qualfail", i);
v_resvalue = LLVMBuildLoad(b, v_resvaluep, ""); v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
v_resnull = LLVMBuildLoad(b, v_resnullp, ""); v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
v_nullorfalse = v_nullorfalse =
LLVMBuildOr(b, LLVMBuildOr(b,
@ -933,7 +965,7 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is null */ /* Transfer control if current result is null */
v_resnull = LLVMBuildLoad(b, v_resnullp, ""); v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull, LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
@ -949,7 +981,7 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is non-null */ /* Transfer control if current result is non-null */
v_resnull = LLVMBuildLoad(b, v_resnullp, ""); v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull, LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
@ -968,8 +1000,8 @@ llvm_compile_expr(ExprState *state)
/* Transfer control if current result is null or false */ /* Transfer control if current result is null or false */
v_resvalue = LLVMBuildLoad(b, v_resvaluep, ""); v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
v_resnull = LLVMBuildLoad(b, v_resnullp, ""); v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
v_nullorfalse = v_nullorfalse =
LLVMBuildOr(b, LLVMBuildOr(b,
@ -988,7 +1020,7 @@ llvm_compile_expr(ExprState *state)
case EEOP_NULLTEST_ISNULL: case EEOP_NULLTEST_ISNULL:
{ {
LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, ""); LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMValueRef v_resvalue; LLVMValueRef v_resvalue;
v_resvalue = v_resvalue =
@ -1007,7 +1039,7 @@ llvm_compile_expr(ExprState *state)
case EEOP_NULLTEST_ISNOTNULL: case EEOP_NULLTEST_ISNOTNULL:
{ {
LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, ""); LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMValueRef v_resvalue; LLVMValueRef v_resvalue;
v_resvalue = v_resvalue =
@ -1043,7 +1075,7 @@ llvm_compile_expr(ExprState *state)
{ {
LLVMBasicBlockRef b_isnull, LLVMBasicBlockRef b_isnull,
b_notnull; b_notnull;
LLVMValueRef v_resnull = LLVMBuildLoad(b, v_resnullp, ""); LLVMValueRef v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
b_isnull = l_bb_before_v(opblocks[i + 1], b_isnull = l_bb_before_v(opblocks[i + 1],
"op.%d.isnull", i); "op.%d.isnull", i);
@ -1087,7 +1119,7 @@ llvm_compile_expr(ExprState *state)
else else
{ {
LLVMValueRef v_value = LLVMValueRef v_value =
LLVMBuildLoad(b, v_resvaluep, ""); l_load(b, TypeSizeT, v_resvaluep, "");
v_value = LLVMBuildZExt(b, v_value = LLVMBuildZExt(b,
LLVMBuildICmp(b, LLVMIntEQ, LLVMBuildICmp(b, LLVMIntEQ,
@ -1115,28 +1147,19 @@ llvm_compile_expr(ExprState *state)
case EEOP_PARAM_CALLBACK: case EEOP_PARAM_CALLBACK:
{ {
LLVMTypeRef param_types[3];
LLVMValueRef v_params[3]; LLVMValueRef v_params[3];
LLVMTypeRef v_functype;
LLVMValueRef v_func; LLVMValueRef v_func;
param_types[0] = l_ptr(StructExprState);
param_types[1] = l_ptr(TypeSizeT);
param_types[2] = l_ptr(StructExprContext);
v_functype = LLVMFunctionType(LLVMVoidType(),
param_types,
lengthof(param_types),
false);
v_func = l_ptr_const(op->d.cparam.paramfunc, v_func = l_ptr_const(op->d.cparam.paramfunc,
l_ptr(v_functype)); llvm_pg_var_type("TypeExecEvalSubroutine"));
v_params[0] = v_state; v_params[0] = v_state;
v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT)); v_params[1] = l_ptr_const(op, l_ptr(TypeSizeT));
v_params[2] = v_econtext; v_params[2] = v_econtext;
LLVMBuildCall(b, l_call(b,
v_func, LLVMGetFunctionType(ExecEvalSubroutineTemplate),
v_params, lengthof(v_params), ""); v_func,
v_params, lengthof(v_params), "");
LLVMBuildBr(b, opblocks[i + 1]); LLVMBuildBr(b, opblocks[i + 1]);
break; break;
@ -1189,8 +1212,8 @@ llvm_compile_expr(ExprState *state)
/* if casetest != NULL */ /* if casetest != NULL */
LLVMPositionBuilderAtEnd(b, b_avail); LLVMPositionBuilderAtEnd(b, b_avail);
v_casevalue = LLVMBuildLoad(b, v_casevaluep, ""); v_casevalue = l_load(b, TypeSizeT, v_casevaluep, "");
v_casenull = LLVMBuildLoad(b, v_casenullp, ""); v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep); LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp); LLVMBuildStore(b, v_casenull, v_resnullp);
LLVMBuildBr(b, opblocks[i + 1]); LLVMBuildBr(b, opblocks[i + 1]);
@ -1198,10 +1221,14 @@ llvm_compile_expr(ExprState *state)
/* if casetest == NULL */ /* if casetest == NULL */
LLVMPositionBuilderAtEnd(b, b_notavail); LLVMPositionBuilderAtEnd(b, b_notavail);
v_casevalue = v_casevalue =
l_load_struct_gep(b, v_econtext, l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_CASEDATUM, ""); FIELDNO_EXPRCONTEXT_CASEDATUM, "");
v_casenull = v_casenull =
l_load_struct_gep(b, v_econtext, l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_CASENULL, ""); FIELDNO_EXPRCONTEXT_CASENULL, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep); LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp); LLVMBuildStore(b, v_casenull, v_resnullp);
@ -1226,7 +1253,7 @@ llvm_compile_expr(ExprState *state)
v_nullp = l_ptr_const(op->d.make_readonly.isnull, v_nullp = l_ptr_const(op->d.make_readonly.isnull,
l_ptr(TypeStorageBool)); l_ptr(TypeStorageBool));
v_null = LLVMBuildLoad(b, v_nullp, ""); v_null = l_load(b, TypeStorageBool, v_nullp, "");
/* store null isnull value in result */ /* store null isnull value in result */
LLVMBuildStore(b, v_null, v_resnullp); LLVMBuildStore(b, v_null, v_resnullp);
@ -1243,13 +1270,14 @@ llvm_compile_expr(ExprState *state)
v_valuep = l_ptr_const(op->d.make_readonly.value, v_valuep = l_ptr_const(op->d.make_readonly.value,
l_ptr(TypeSizeT)); l_ptr(TypeSizeT));
v_value = LLVMBuildLoad(b, v_valuep, ""); v_value = l_load(b, TypeSizeT, v_valuep, "");
v_params[0] = v_value; v_params[0] = v_value;
v_ret = v_ret =
LLVMBuildCall(b, l_call(b,
llvm_get_decl(mod, FuncMakeExpandedObjectReadOnlyInternal), llvm_pg_var_func_type("MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), ""); llvm_pg_func(mod, "MakeExpandedObjectReadOnlyInternal"),
v_params, lengthof(v_params), "");
LLVMBuildStore(b, v_ret, v_resvaluep); LLVMBuildStore(b, v_ret, v_resvaluep);
LLVMBuildBr(b, opblocks[i + 1]); LLVMBuildBr(b, opblocks[i + 1]);
@ -1260,10 +1288,10 @@ llvm_compile_expr(ExprState *state)
{ {
FunctionCallInfo fcinfo_out, FunctionCallInfo fcinfo_out,
fcinfo_in; fcinfo_in;
LLVMValueRef v_fn_out,
v_fn_in;
LLVMValueRef v_fcinfo_out, LLVMValueRef v_fcinfo_out,
v_fcinfo_in; v_fcinfo_in;
LLVMValueRef v_fn_addr_out,
v_fn_addr_in;
LLVMValueRef v_fcinfo_in_isnullp; LLVMValueRef v_fcinfo_in_isnullp;
LLVMValueRef v_retval; LLVMValueRef v_retval;
LLVMValueRef v_resvalue; LLVMValueRef v_resvalue;
@ -1289,18 +1317,20 @@ llvm_compile_expr(ExprState *state)
b_inputcall = l_bb_before_v(opblocks[i + 1], b_inputcall = l_bb_before_v(opblocks[i + 1],
"op.%d.inputcall", i); "op.%d.inputcall", i);
v_fn_out = llvm_function_reference(context, b, mod, fcinfo_out);
v_fn_in = llvm_function_reference(context, b, mod, fcinfo_in);
v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData)); v_fcinfo_out = l_ptr_const(fcinfo_out, l_ptr(StructFunctionCallInfoData));
v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData)); v_fcinfo_in = l_ptr_const(fcinfo_in, l_ptr(StructFunctionCallInfoData));
v_fn_addr_out = l_ptr_const(fcinfo_out->flinfo->fn_addr, TypePGFunction);
v_fn_addr_in = l_ptr_const(fcinfo_in->flinfo->fn_addr, TypePGFunction);
v_fcinfo_in_isnullp = v_fcinfo_in_isnullp =
LLVMBuildStructGEP(b, v_fcinfo_in, l_struct_gep(b,
FIELDNO_FUNCTIONCALLINFODATA_ISNULL, StructFunctionCallInfoData,
"v_fcinfo_in_isnull"); v_fcinfo_in,
FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
"v_fcinfo_in_isnull");
/* output functions are not called on nulls */ /* output functions are not called on nulls */
v_resnull = LLVMBuildLoad(b, v_resnullp, ""); v_resnull = l_load(b, TypeStorageBool, v_resnullp, "");
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
LLVMBuildICmp(b, LLVMIntEQ, v_resnull, LLVMBuildICmp(b, LLVMIntEQ, v_resnull,
l_sbool_const(1), ""), l_sbool_const(1), ""),
@ -1312,7 +1342,7 @@ llvm_compile_expr(ExprState *state)
LLVMBuildBr(b, b_input); LLVMBuildBr(b, b_input);
LLVMPositionBuilderAtEnd(b, b_calloutput); LLVMPositionBuilderAtEnd(b, b_calloutput);
v_resvalue = LLVMBuildLoad(b, v_resvaluep, ""); v_resvalue = l_load(b, TypeSizeT, v_resvaluep, "");
/* set arg[0] */ /* set arg[0] */
LLVMBuildStore(b, LLVMBuildStore(b,
@ -1322,8 +1352,10 @@ llvm_compile_expr(ExprState *state)
l_sbool_const(0), l_sbool_const(0),
l_funcnullp(b, v_fcinfo_out, 0)); l_funcnullp(b, v_fcinfo_out, 0));
/* and call output function (can never return NULL) */ /* and call output function (can never return NULL) */
v_output = LLVMBuildCall(b, v_fn_addr_out, &v_fcinfo_out, v_output = l_call(b,
1, "funccall_coerce_out"); LLVMGetFunctionType(v_fn_out),
v_fn_out, &v_fcinfo_out,
1, "funccall_coerce_out");
LLVMBuildBr(b, b_input); LLVMBuildBr(b, b_input);
/* build block handling input function call */ /* build block handling input function call */
@ -1377,8 +1409,10 @@ llvm_compile_expr(ExprState *state)
/* reset fcinfo_in->isnull */ /* reset fcinfo_in->isnull */
LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp); LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_in_isnullp);
/* and call function */ /* and call function */
v_retval = LLVMBuildCall(b, v_fn_addr_in, &v_fcinfo_in, 1, v_retval = l_call(b,
"funccall_iocoerce_in"); LLVMGetFunctionType(v_fn_in),
v_fn_in, &v_fcinfo_in, 1,
"funccall_iocoerce_in");
LLVMBuildStore(b, v_retval, v_resvaluep); LLVMBuildStore(b, v_retval, v_resvaluep);
@ -1711,7 +1745,7 @@ llvm_compile_expr(ExprState *state)
*/ */
v_cmpresult = v_cmpresult =
LLVMBuildTrunc(b, LLVMBuildTrunc(b,
LLVMBuildLoad(b, v_resvaluep, ""), l_load(b, TypeSizeT, v_resvaluep, ""),
LLVMInt32Type(), ""); LLVMInt32Type(), "");
switch (rctype) switch (rctype)
@ -1775,17 +1809,16 @@ llvm_compile_expr(ExprState *state)
case EEOP_SBSREF_SUBSCRIPT: case EEOP_SBSREF_SUBSCRIPT:
{ {
LLVMValueRef v_fn;
int jumpdone = op->d.sbsref_subscript.jumpdone; int jumpdone = op->d.sbsref_subscript.jumpdone;
LLVMValueRef v_params[2]; LLVMValueRef v_params[2];
LLVMValueRef v_ret; LLVMValueRef v_ret;
v_fn = llvm_get_decl(mod, FuncExecEvalSubscriptingRef);
v_params[0] = v_state; v_params[0] = v_state;
v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); v_params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
v_ret = LLVMBuildCall(b, v_fn, v_ret = l_call(b,
v_params, lengthof(v_params), ""); llvm_pg_var_func_type("ExecEvalSubscriptingRef"),
llvm_pg_func(mod, "ExecEvalSubscriptingRef"),
v_params, lengthof(v_params), "");
v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, ""); v_ret = LLVMBuildZExt(b, v_ret, TypeStorageBool, "");
LLVMBuildCondBr(b, LLVMBuildCondBr(b,
@ -1827,8 +1860,8 @@ llvm_compile_expr(ExprState *state)
/* if casetest != NULL */ /* if casetest != NULL */
LLVMPositionBuilderAtEnd(b, b_avail); LLVMPositionBuilderAtEnd(b, b_avail);
v_casevalue = LLVMBuildLoad(b, v_casevaluep, ""); v_casevalue = l_load(b, TypeSizeT, v_casevaluep, "");
v_casenull = LLVMBuildLoad(b, v_casenullp, ""); v_casenull = l_load(b, TypeStorageBool, v_casenullp, "");
LLVMBuildStore(b, v_casevalue, v_resvaluep); LLVMBuildStore(b, v_casevalue, v_resvaluep);
LLVMBuildStore(b, v_casenull, v_resnullp); LLVMBuildStore(b, v_casenull, v_resnullp);
LLVMBuildBr(b, opblocks[i + 1]); LLVMBuildBr(b, opblocks[i + 1]);
@ -1836,11 +1869,15 @@ llvm_compile_expr(ExprState *state)
/* if casetest == NULL */ /* if casetest == NULL */
LLVMPositionBuilderAtEnd(b, b_notavail); LLVMPositionBuilderAtEnd(b, b_notavail);
v_casevalue = v_casevalue =
l_load_struct_gep(b, v_econtext, l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_DOMAINDATUM, FIELDNO_EXPRCONTEXT_DOMAINDATUM,
""); "");
v_casenull = v_casenull =
l_load_struct_gep(b, v_econtext, l_load_struct_gep(b,
StructExprContext,
v_econtext,
FIELDNO_EXPRCONTEXT_DOMAINNULL, FIELDNO_EXPRCONTEXT_DOMAINNULL,
""); "");
LLVMBuildStore(b, v_casevalue, v_resvaluep); LLVMBuildStore(b, v_casevalue, v_resvaluep);
@ -1895,11 +1932,11 @@ llvm_compile_expr(ExprState *state)
*/ */
v_aggnop = l_ptr_const(&aggref->aggno, v_aggnop = l_ptr_const(&aggref->aggno,
l_ptr(LLVMInt32Type())); l_ptr(LLVMInt32Type()));
v_aggno = LLVMBuildLoad(b, v_aggnop, "v_aggno"); v_aggno = l_load(b, LLVMInt32Type(), v_aggnop, "v_aggno");
/* load agg value / null */ /* load agg value / null */
value = l_load_gep1(b, v_aggvalues, v_aggno, "aggvalue"); value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_aggno, "aggvalue");
isnull = l_load_gep1(b, v_aggnulls, v_aggno, "aggnull"); isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_aggno, "aggnull");
/* and store result */ /* and store result */
LLVMBuildStore(b, value, v_resvaluep); LLVMBuildStore(b, value, v_resvaluep);
@ -1930,12 +1967,12 @@ llvm_compile_expr(ExprState *state)
*/ */
v_wfuncnop = l_ptr_const(&wfunc->wfuncno, v_wfuncnop = l_ptr_const(&wfunc->wfuncno,
l_ptr(LLVMInt32Type())); l_ptr(LLVMInt32Type()));
v_wfuncno = LLVMBuildLoad(b, v_wfuncnop, "v_wfuncno"); v_wfuncno = l_load(b, LLVMInt32Type(), v_wfuncnop, "v_wfuncno");
/* load window func value / null */ /* load window func value / null */
value = l_load_gep1(b, v_aggvalues, v_wfuncno, value = l_load_gep1(b, TypeSizeT, v_aggvalues, v_wfuncno,
"windowvalue"); "windowvalue");
isnull = l_load_gep1(b, v_aggnulls, v_wfuncno, isnull = l_load_gep1(b, TypeStorageBool, v_aggnulls, v_wfuncno,
"windownull"); "windownull");
LLVMBuildStore(b, value, v_resvaluep); LLVMBuildStore(b, value, v_resvaluep);
@ -2057,14 +2094,14 @@ llvm_compile_expr(ExprState *state)
b_argnotnull = b_checknulls[argno + 1]; b_argnotnull = b_checknulls[argno + 1];
if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS) if (opcode == EEOP_AGG_STRICT_INPUT_CHECK_NULLS)
v_argisnull = l_load_gep1(b, v_nullsp, v_argno, ""); v_argisnull = l_load_gep1(b, TypeStorageBool, v_nullsp, v_argno, "");
else else
{ {
LLVMValueRef v_argn; LLVMValueRef v_argn;
v_argn = LLVMBuildGEP(b, v_argsp, &v_argno, 1, ""); v_argn = l_gep(b, StructNullableDatum, v_argsp, &v_argno, 1, "");
v_argisnull = v_argisnull =
l_load_struct_gep(b, v_argn, l_load_struct_gep(b, StructNullableDatum, v_argn,
FIELDNO_NULLABLE_DATUM_ISNULL, FIELDNO_NULLABLE_DATUM_ISNULL,
""); "");
} }
@ -2114,18 +2151,24 @@ llvm_compile_expr(ExprState *state)
* [op->d.agg_init_trans_check.transno]; * [op->d.agg_init_trans_check.transno];
*/ */
v_allpergroupsp = v_allpergroupsp =
l_load_struct_gep(b, v_aggstatep, l_load_struct_gep(b,
StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS, FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups"); "aggstate.all_pergroups");
v_setoff = l_int32_const(op->d.agg_init_trans.setoff); v_setoff = l_int32_const(op->d.agg_init_trans.setoff);
v_transno = l_int32_const(op->d.agg_init_trans.transno); v_transno = l_int32_const(op->d.agg_init_trans.transno);
v_pergroupp = v_pergroupp =
LLVMBuildGEP(b, l_gep(b,
l_load_gep1(b, v_allpergroupsp, v_setoff, ""), StructAggStatePerGroupData,
&v_transno, 1, ""); l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
v_allpergroupsp, v_setoff, ""),
&v_transno, 1, "");
v_notransvalue = v_notransvalue =
l_load_struct_gep(b, v_pergroupp, l_load_struct_gep(b,
StructAggStatePerGroupData,
v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE, FIELDNO_AGGSTATEPERGROUPDATA_NOTRANSVALUE,
"notransvalue"); "notransvalue");
@ -2150,15 +2193,17 @@ llvm_compile_expr(ExprState *state)
l_ptr(StructExprContext)); l_ptr(StructExprContext));
v_current_set = v_current_set =
LLVMBuildStructGEP(b, l_struct_gep(b,
v_aggstatep, StructAggState,
FIELDNO_AGGSTATE_CURRENT_SET, v_aggstatep,
"aggstate.current_set"); FIELDNO_AGGSTATE_CURRENT_SET,
"aggstate.current_set");
v_curaggcontext = v_curaggcontext =
LLVMBuildStructGEP(b, l_struct_gep(b,
v_aggstatep, StructAggState,
FIELDNO_AGGSTATE_CURAGGCONTEXT, v_aggstatep,
"aggstate.curaggcontext"); FIELDNO_AGGSTATE_CURAGGCONTEXT,
"aggstate.curaggcontext");
LLVMBuildStore(b, l_int32_const(op->d.agg_init_trans.setno), LLVMBuildStore(b, l_int32_const(op->d.agg_init_trans.setno),
v_current_set); v_current_set);
@ -2169,10 +2214,11 @@ llvm_compile_expr(ExprState *state)
params[1] = v_pertransp; params[1] = v_pertransp;
params[2] = v_pergroupp; params[2] = v_pergroupp;
LLVMBuildCall(b, l_call(b,
llvm_get_decl(mod, FuncExecAggInitGroup), llvm_pg_var_func_type("ExecAggInitGroup"),
params, lengthof(params), llvm_pg_func(mod, "ExecAggInitGroup"),
""); params, lengthof(params),
"");
} }
LLVMBuildBr(b, opblocks[op->d.agg_init_trans.jumpnull]); LLVMBuildBr(b, opblocks[op->d.agg_init_trans.jumpnull]);
@ -2202,7 +2248,9 @@ llvm_compile_expr(ExprState *state)
* [op->d.agg_init_trans_check.transno]; * [op->d.agg_init_trans_check.transno];
*/ */
v_allpergroupsp = v_allpergroupsp =
l_load_struct_gep(b, v_aggstatep, l_load_struct_gep(b,
StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS, FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups"); "aggstate.all_pergroups");
v_setoff = v_setoff =
@ -2210,12 +2258,16 @@ llvm_compile_expr(ExprState *state)
v_transno = v_transno =
l_int32_const(op->d.agg_strict_trans_check.transno); l_int32_const(op->d.agg_strict_trans_check.transno);
v_pergroupp = v_pergroupp =
LLVMBuildGEP(b, l_gep(b,
l_load_gep1(b, v_allpergroupsp, v_setoff, ""), StructAggStatePerGroupData,
&v_transno, 1, ""); l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
v_allpergroupsp, v_setoff, ""),
&v_transno, 1, "");
v_transnull = v_transnull =
l_load_struct_gep(b, v_pergroupp, l_load_struct_gep(b,
StructAggStatePerGroupData,
v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL, FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
"transnull"); "transnull");
@ -2277,15 +2329,19 @@ llvm_compile_expr(ExprState *state)
* [op->d.agg_init_trans_check.transno]; * [op->d.agg_init_trans_check.transno];
*/ */
v_allpergroupsp = v_allpergroupsp =
l_load_struct_gep(b, v_aggstatep, l_load_struct_gep(b,
StructAggState,
v_aggstatep,
FIELDNO_AGGSTATE_ALL_PERGROUPS, FIELDNO_AGGSTATE_ALL_PERGROUPS,
"aggstate.all_pergroups"); "aggstate.all_pergroups");
v_setoff = l_int32_const(op->d.agg_trans.setoff); v_setoff = l_int32_const(op->d.agg_trans.setoff);
v_transno = l_int32_const(op->d.agg_trans.transno); v_transno = l_int32_const(op->d.agg_trans.transno);
v_pergroupp = v_pergroupp =
LLVMBuildGEP(b, l_gep(b,
l_load_gep1(b, v_allpergroupsp, v_setoff, ""), StructAggStatePerGroupData,
&v_transno, 1, ""); l_load_gep1(b, l_ptr(StructAggStatePerGroupData),
v_allpergroupsp, v_setoff, ""),
&v_transno, 1, "");
v_fcinfo = l_ptr_const(fcinfo, v_fcinfo = l_ptr_const(fcinfo,
l_ptr(StructFunctionCallInfoData)); l_ptr(StructFunctionCallInfoData));
@ -2293,20 +2349,23 @@ llvm_compile_expr(ExprState *state)
l_ptr(StructExprContext)); l_ptr(StructExprContext));
v_current_setp = v_current_setp =
LLVMBuildStructGEP(b, l_struct_gep(b,
v_aggstatep, StructAggState,
FIELDNO_AGGSTATE_CURRENT_SET, v_aggstatep,
"aggstate.current_set"); FIELDNO_AGGSTATE_CURRENT_SET,
"aggstate.current_set");
v_curaggcontext = v_curaggcontext =
LLVMBuildStructGEP(b, l_struct_gep(b,
v_aggstatep, StructAggState,
FIELDNO_AGGSTATE_CURAGGCONTEXT, v_aggstatep,
"aggstate.curaggcontext"); FIELDNO_AGGSTATE_CURAGGCONTEXT,
"aggstate.curaggcontext");
v_current_pertransp = v_current_pertransp =
LLVMBuildStructGEP(b, l_struct_gep(b,
v_aggstatep, StructAggState,
FIELDNO_AGGSTATE_CURPERTRANS, v_aggstatep,
"aggstate.curpertrans"); FIELDNO_AGGSTATE_CURPERTRANS,
"aggstate.curpertrans");
/* set aggstate globals */ /* set aggstate globals */
LLVMBuildStore(b, v_aggcontext, v_curaggcontext); LLVMBuildStore(b, v_aggcontext, v_curaggcontext);
@ -2322,19 +2381,25 @@ llvm_compile_expr(ExprState *state)
/* store transvalue in fcinfo->args[0] */ /* store transvalue in fcinfo->args[0] */
v_transvaluep = v_transvaluep =
LLVMBuildStructGEP(b, v_pergroupp, l_struct_gep(b,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE, StructAggStatePerGroupData,
"transvalue"); v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUE,
"transvalue");
v_transnullp = v_transnullp =
LLVMBuildStructGEP(b, v_pergroupp, l_struct_gep(b,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL, StructAggStatePerGroupData,
"transnullp"); v_pergroupp,
FIELDNO_AGGSTATEPERGROUPDATA_TRANSVALUEISNULL,
"transnullp");
LLVMBuildStore(b, LLVMBuildStore(b,
LLVMBuildLoad(b, v_transvaluep, l_load(b,
"transvalue"), TypeSizeT,
v_transvaluep,
"transvalue"),
l_funcvaluep(b, v_fcinfo, 0)); l_funcvaluep(b, v_fcinfo, 0));
LLVMBuildStore(b, LLVMBuildStore(b,
LLVMBuildLoad(b, v_transnullp, "transnull"), l_load(b, TypeStorageBool, v_transnullp, "transnull"),
l_funcnullp(b, v_fcinfo, 0)); l_funcnullp(b, v_fcinfo, 0));
/* and invoke transition function */ /* and invoke transition function */
@ -2365,8 +2430,8 @@ llvm_compile_expr(ExprState *state)
b_nocall = l_bb_before_v(opblocks[i + 1], b_nocall = l_bb_before_v(opblocks[i + 1],
"op.%d.transnocall", i); "op.%d.transnocall", i);
v_transvalue = LLVMBuildLoad(b, v_transvaluep, ""); v_transvalue = l_load(b, TypeSizeT, v_transvaluep, "");
v_transnull = LLVMBuildLoad(b, v_transnullp, ""); v_transnull = l_load(b, TypeStorageBool, v_transnullp, "");
/* /*
* DatumGetPointer(newVal) != * DatumGetPointer(newVal) !=
@ -2390,11 +2455,13 @@ llvm_compile_expr(ExprState *state)
params[5] = LLVMBuildTrunc(b, v_transnull, params[5] = LLVMBuildTrunc(b, v_transnull,
TypeParamBool, ""); TypeParamBool, "");
v_fn = llvm_get_decl(mod, FuncExecAggTransReparent); v_fn = llvm_pg_func(mod, "ExecAggTransReparent");
v_newval = v_newval =
LLVMBuildCall(b, v_fn, l_call(b,
params, lengthof(params), LLVMGetFunctionType(v_fn),
""); v_fn,
params, lengthof(params),
"");
/* store trans value */ /* store trans value */
LLVMBuildStore(b, v_newval, v_transvaluep); LLVMBuildStore(b, v_newval, v_transvaluep);
@ -2504,15 +2571,17 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
v_fn = llvm_function_reference(context, b, mod, fcinfo); v_fn = llvm_function_reference(context, b, mod, fcinfo);
v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData)); v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
v_fcinfo_isnullp = LLVMBuildStructGEP(b, v_fcinfo, v_fcinfo_isnullp = l_struct_gep(b,
FIELDNO_FUNCTIONCALLINFODATA_ISNULL, StructFunctionCallInfoData,
"v_fcinfo_isnull"); v_fcinfo,
FIELDNO_FUNCTIONCALLINFODATA_ISNULL,
"v_fcinfo_isnull");
LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp); LLVMBuildStore(b, l_sbool_const(0), v_fcinfo_isnullp);
v_retval = LLVMBuildCall(b, v_fn, &v_fcinfo, 1, "funccall"); v_retval = l_call(b, LLVMGetFunctionType(AttributeTemplate), v_fn, &v_fcinfo, 1, "funccall");
if (v_fcinfo_isnull) if (v_fcinfo_isnull)
*v_fcinfo_isnull = LLVMBuildLoad(b, v_fcinfo_isnullp, ""); *v_fcinfo_isnull = l_load(b, TypeStorageBool, v_fcinfo_isnullp, "");
/* /*
* Add lifetime-end annotation, signalling that writes to memory don't * Add lifetime-end annotation, signalling that writes to memory don't
@ -2524,11 +2593,11 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
params[0] = l_int64_const(sizeof(NullableDatum) * fcinfo->nargs); params[0] = l_int64_const(sizeof(NullableDatum) * fcinfo->nargs);
params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8Type())); params[1] = l_ptr_const(fcinfo->args, l_ptr(LLVMInt8Type()));
LLVMBuildCall(b, v_lifetime, params, lengthof(params), ""); l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
params[0] = l_int64_const(sizeof(fcinfo->isnull)); params[0] = l_int64_const(sizeof(fcinfo->isnull));
params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8Type())); params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8Type()));
LLVMBuildCall(b, v_lifetime, params, lengthof(params), ""); l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
} }
return v_retval; return v_retval;
@ -2564,9 +2633,7 @@ build_EvalXFunc(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep)); params[1] = l_ptr_const(op, l_ptr(StructExprEvalStep));
params[2] = v_econtext; params[2] = v_econtext;
LLVMBuildCall(b, l_call(b, LLVMGetFunctionType(v_fn), v_fn, params, lengthof(params), "");
v_fn,
params, lengthof(params), "");
} }
static LLVMValueRef static LLVMValueRef

View File

@ -49,6 +49,8 @@ PGFunction TypePGFunction;
size_t TypeSizeT; size_t TypeSizeT;
bool TypeStorageBool; bool TypeStorageBool;
ExecEvalSubroutine TypeExecEvalSubroutine;
NullableDatum StructNullableDatum; NullableDatum StructNullableDatum;
AggState StructAggState; AggState StructAggState;
AggStatePerGroupData StructAggStatePerGroupData; AggStatePerGroupData StructAggStatePerGroupData;
@ -58,11 +60,14 @@ ExprEvalStep StructExprEvalStep;
ExprState StructExprState; ExprState StructExprState;
FunctionCallInfoBaseData StructFunctionCallInfoData; FunctionCallInfoBaseData StructFunctionCallInfoData;
HeapTupleData StructHeapTupleData; HeapTupleData StructHeapTupleData;
HeapTupleHeaderData StructHeapTupleHeaderData;
MemoryContextData StructMemoryContextData; MemoryContextData StructMemoryContextData;
TupleTableSlot StructTupleTableSlot; TupleTableSlot StructTupleTableSlot;
HeapTupleTableSlot StructHeapTupleTableSlot; HeapTupleTableSlot StructHeapTupleTableSlot;
MinimalTupleTableSlot StructMinimalTupleTableSlot; MinimalTupleTableSlot StructMinimalTupleTableSlot;
TupleDescData StructTupleDescData; TupleDescData StructTupleDescData;
PlanState StructPlanState;
MinimalTupleData StructMinimalTupleData;
/* /*
@ -74,9 +79,28 @@ extern Datum AttributeTemplate(PG_FUNCTION_ARGS);
Datum Datum
AttributeTemplate(PG_FUNCTION_ARGS) AttributeTemplate(PG_FUNCTION_ARGS)
{ {
AssertVariableIsOfType(&AttributeTemplate, PGFunction);
PG_RETURN_NULL(); PG_RETURN_NULL();
} }
/*
* And some more "templates" to give us examples of function types
* corresponding to function pointer types.
*/
extern void ExecEvalSubroutineTemplate(ExprState *state,
struct ExprEvalStep *op,
ExprContext *econtext);
void
ExecEvalSubroutineTemplate(ExprState *state,
struct ExprEvalStep *op,
ExprContext *econtext)
{
AssertVariableIsOfType(&ExecEvalSubroutineTemplate,
ExecEvalSubroutine);
}
/* /*
* Clang represents stdbool.h style booleans that are returned by functions * Clang represents stdbool.h style booleans that are returned by functions
* differently (as i1) than stored ones (as i8). Therefore we do not just need * differently (as i1) than stored ones (as i8). Therefore we do not just need
@ -106,5 +130,6 @@ void *referenced_functions[] =
ExecEvalSubscriptingRef, ExecEvalSubscriptingRef,
ExecEvalSysVar, ExecEvalSysVar,
ExecAggTransReparent, ExecAggTransReparent,
ExecAggInitGroup ExecAggInitGroup,
ExecInterpExprStillValid
}; };

View File

@ -76,3 +76,15 @@ LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx)
*/ */
return LLVMGetAttributeCountAtIndex(F, Idx); return LLVMGetAttributeCountAtIndex(F, Idx);
} }
LLVMTypeRef
LLVMGetFunctionReturnType(LLVMValueRef r)
{
return llvm::wrap(llvm::unwrap<llvm::Function>(r)->getReturnType());
}
LLVMTypeRef
LLVMGetFunctionType(LLVMValueRef r)
{
return llvm::wrap(llvm::unwrap<llvm::Function>(r)->getFunctionType());
}

View File

@ -57,6 +57,8 @@ typedef struct LLVMJitContext
List *handles; List *handles;
} LLVMJitContext; } LLVMJitContext;
/* llvm module containing information about types */
extern PGDLLIMPORT LLVMModuleRef llvm_types_module;
/* type and struct definitions */ /* type and struct definitions */
extern LLVMTypeRef TypeParamBool; extern LLVMTypeRef TypeParamBool;
@ -67,6 +69,8 @@ extern LLVMTypeRef TypeStorageBool;
extern LLVMTypeRef StructNullableDatum; extern LLVMTypeRef StructNullableDatum;
extern LLVMTypeRef StructTupleDescData; extern LLVMTypeRef StructTupleDescData;
extern LLVMTypeRef StructHeapTupleData; extern LLVMTypeRef StructHeapTupleData;
extern LLVMTypeRef StructHeapTupleHeaderData;
extern LLVMTypeRef StructMinimalTupleData;
extern LLVMTypeRef StructTupleTableSlot; extern LLVMTypeRef StructTupleTableSlot;
extern LLVMTypeRef StructHeapTupleTableSlot; extern LLVMTypeRef StructHeapTupleTableSlot;
extern LLVMTypeRef StructMinimalTupleTableSlot; extern LLVMTypeRef StructMinimalTupleTableSlot;
@ -80,15 +84,7 @@ extern LLVMTypeRef StructAggStatePerTransData;
extern LLVMTypeRef StructAggStatePerGroupData; extern LLVMTypeRef StructAggStatePerGroupData;
extern LLVMValueRef AttributeTemplate; extern LLVMValueRef AttributeTemplate;
extern LLVMValueRef FuncStrlen; extern LLVMValueRef ExecEvalSubroutineTemplate;
extern LLVMValueRef FuncVarsizeAny;
extern LLVMValueRef FuncSlotGetmissingattrs;
extern LLVMValueRef FuncSlotGetsomeattrsInt;
extern LLVMValueRef FuncMakeExpandedObjectReadOnlyInternal;
extern LLVMValueRef FuncExecEvalSubscriptingRef;
extern LLVMValueRef FuncExecEvalSysVar;
extern LLVMValueRef FuncExecAggTransReparent;
extern LLVMValueRef FuncExecAggInitGroup;
extern void llvm_enter_fatal_on_oom(void); extern void llvm_enter_fatal_on_oom(void);
@ -102,7 +98,9 @@ extern LLVMModuleRef llvm_mutable_module(LLVMJitContext *context);
extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename); extern char *llvm_expand_funcname(LLVMJitContext *context, const char *basename);
extern void *llvm_get_function(LLVMJitContext *context, const char *funcname); extern void *llvm_get_function(LLVMJitContext *context, const char *funcname);
extern void llvm_split_symbol_name(const char *name, char **modname, char **funcname); extern void llvm_split_symbol_name(const char *name, char **modname, char **funcname);
extern LLVMValueRef llvm_get_decl(LLVMModuleRef mod, LLVMValueRef f); extern LLVMTypeRef llvm_pg_var_type(const char *varname);
extern LLVMTypeRef llvm_pg_var_func_type(const char *varname);
extern LLVMValueRef llvm_pg_func(LLVMModuleRef mod, const char *funcname);
extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to); extern void llvm_copy_attributes(LLVMValueRef from, LLVMValueRef to);
extern LLVMValueRef llvm_function_reference(LLVMJitContext *context, extern LLVMValueRef llvm_function_reference(LLVMJitContext *context,
LLVMBuilderRef builder, LLVMBuilderRef builder,
@ -140,6 +138,8 @@ extern char *LLVMGetHostCPUFeatures(void);
#endif #endif
extern unsigned LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx); extern unsigned LLVMGetAttributeCountAtIndexPG(LLVMValueRef F, uint32 Idx);
extern LLVMTypeRef LLVMGetFunctionReturnType(LLVMValueRef r);
extern LLVMTypeRef LLVMGetFunctionType(LLVMValueRef r);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@ -16,6 +16,7 @@
#ifdef USE_LLVM #ifdef USE_LLVM
#include <llvm-c/Core.h> #include <llvm-c/Core.h>
#include <llvm-c/Target.h>
#include "fmgr.h" #include "fmgr.h"
#include "jit/llvmjit.h" #include "jit/llvmjit.h"
@ -104,26 +105,65 @@ l_pbool_const(bool i)
return LLVMConstInt(TypeParamBool, (int) i, false); return LLVMConstInt(TypeParamBool, (int) i, false);
} }
static inline LLVMValueRef
l_struct_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, int32 idx, const char *name)
{
#if LLVM_VERSION_MAJOR < 16
return LLVMBuildStructGEP(b, v, idx, "");
#else
return LLVMBuildStructGEP2(b, t, v, idx, "");
#endif
}
static inline LLVMValueRef
l_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef *indices, int32 nindices, const char *name)
{
#if LLVM_VERSION_MAJOR < 16
return LLVMBuildGEP(b, v, indices, nindices, name);
#else
return LLVMBuildGEP2(b, t, v, indices, nindices, name);
#endif
}
static inline LLVMValueRef
l_load(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, const char *name)
{
#if LLVM_VERSION_MAJOR < 16
return LLVMBuildLoad(b, v, name);
#else
return LLVMBuildLoad2(b, t, v, name);
#endif
}
static inline LLVMValueRef
l_call(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef fn, LLVMValueRef *args, int32 nargs, const char *name)
{
#if LLVM_VERSION_MAJOR < 16
return LLVMBuildCall(b, fn, args, nargs, name);
#else
return LLVMBuildCall2(b, t, fn, args, nargs, name);
#endif
}
/* /*
* Load a pointer member idx from a struct. * Load a pointer member idx from a struct.
*/ */
static inline LLVMValueRef static inline LLVMValueRef
l_load_struct_gep(LLVMBuilderRef b, LLVMValueRef v, int32 idx, const char *name) l_load_struct_gep(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, int32 idx, const char *name)
{ {
LLVMValueRef v_ptr = LLVMBuildStructGEP(b, v, idx, ""); return l_load(b,
LLVMStructGetTypeAtIndex(t, idx),
return LLVMBuildLoad(b, v_ptr, name); l_struct_gep(b, t, v, idx, ""),
name);
} }
/* /*
* Load value of a pointer, after applying one index operation. * Load value of a pointer, after applying one index operation.
*/ */
static inline LLVMValueRef static inline LLVMValueRef
l_load_gep1(LLVMBuilderRef b, LLVMValueRef v, LLVMValueRef idx, const char *name) l_load_gep1(LLVMBuilderRef b, LLVMTypeRef t, LLVMValueRef v, LLVMValueRef idx, const char *name)
{ {
LLVMValueRef v_ptr = LLVMBuildGEP(b, v, &idx, 1, ""); return l_load(b, t, l_gep(b, t, v, &idx, 1, ""), name);
return LLVMBuildLoad(b, v_ptr, name);
} }
/* separate, because pg_attribute_printf(2, 3) can't appear in definition */ /* separate, because pg_attribute_printf(2, 3) can't appear in definition */
@ -211,7 +251,7 @@ l_mcxt_switch(LLVMModuleRef mod, LLVMBuilderRef b, LLVMValueRef nc)
if (!(cur = LLVMGetNamedGlobal(mod, cmc))) if (!(cur = LLVMGetNamedGlobal(mod, cmc)))
cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc); cur = LLVMAddGlobal(mod, l_ptr(StructMemoryContextData), cmc);
ret = LLVMBuildLoad(b, cur, cmc); ret = l_load(b, l_ptr(StructMemoryContextData), cur, cmc);
LLVMBuildStore(b, nc, cur); LLVMBuildStore(b, nc, cur);
return ret; return ret;
@ -226,13 +266,21 @@ l_funcnullp(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
LLVMValueRef v_args; LLVMValueRef v_args;
LLVMValueRef v_argn; LLVMValueRef v_argn;
v_args = LLVMBuildStructGEP(b, v_args = l_struct_gep(b,
v_fcinfo, StructFunctionCallInfoData,
FIELDNO_FUNCTIONCALLINFODATA_ARGS, v_fcinfo,
""); FIELDNO_FUNCTIONCALLINFODATA_ARGS,
v_argn = LLVMBuildStructGEP(b, v_args, argno, ""); "");
v_argn = l_struct_gep(b,
return LLVMBuildStructGEP(b, v_argn, FIELDNO_NULLABLE_DATUM_ISNULL, ""); LLVMArrayType(StructNullableDatum, 0),
v_args,
argno,
"");
return l_struct_gep(b,
StructNullableDatum,
v_argn,
FIELDNO_NULLABLE_DATUM_ISNULL,
"");
} }
/* /*
@ -244,13 +292,21 @@ l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
LLVMValueRef v_args; LLVMValueRef v_args;
LLVMValueRef v_argn; LLVMValueRef v_argn;
v_args = LLVMBuildStructGEP(b, v_args = l_struct_gep(b,
v_fcinfo, StructFunctionCallInfoData,
FIELDNO_FUNCTIONCALLINFODATA_ARGS, v_fcinfo,
""); FIELDNO_FUNCTIONCALLINFODATA_ARGS,
v_argn = LLVMBuildStructGEP(b, v_args, argno, ""); "");
v_argn = l_struct_gep(b,
return LLVMBuildStructGEP(b, v_argn, FIELDNO_NULLABLE_DATUM_DATUM, ""); LLVMArrayType(StructNullableDatum, 0),
v_args,
argno,
"");
return l_struct_gep(b,
StructNullableDatum,
v_argn,
FIELDNO_NULLABLE_DATUM_DATUM,
"");
} }
/* /*
@ -259,7 +315,7 @@ l_funcvaluep(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
static inline LLVMValueRef static inline LLVMValueRef
l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
{ {
return LLVMBuildLoad(b, l_funcnullp(b, v_fcinfo, argno), ""); return l_load(b, TypeStorageBool, l_funcnullp(b, v_fcinfo, argno), "");
} }
/* /*
@ -268,7 +324,7 @@ l_funcnull(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
static inline LLVMValueRef static inline LLVMValueRef
l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno) l_funcvalue(LLVMBuilderRef b, LLVMValueRef v_fcinfo, size_t argno)
{ {
return LLVMBuildLoad(b, l_funcvaluep(b, v_fcinfo, argno), ""); return l_load(b, TypeSizeT, l_funcvaluep(b, v_fcinfo, argno), "");
} }
#endif /* USE_LLVM */ #endif /* USE_LLVM */