Commit 2111a48a authored by Andres Freund's avatar Andres Freund

Adapt expression JIT to stdbool.h introduction.

The LLVM JIT provider uses clang to synchronize types between normal C
code and runtime generated code. Clang represents stdbool.h style
booleans in return values & parameters differently from booleans
stored in variables.

Thus the expression compilation code from 2a0faed9 needs to be
adapted to 9a95a77d. Instead of hardcoding i8 as the type for
booleans (which already was wrong on some edge case platforms!), use
postgres' notion of a boolean as used for storage and for parameters.

Per buildfarm animal xenodermus.

Author: Andres Freund
parent fdb78948
......@@ -46,6 +46,8 @@ typedef struct LLVMJitHandle
/* types & functions commonly needed for JITing */
LLVMTypeRef TypeSizeT;
LLVMTypeRef TypeParamBool;
LLVMTypeRef TypeStorageBool;
LLVMTypeRef TypePGFunction;
LLVMTypeRef StructHeapTupleFieldsField3;
LLVMTypeRef StructHeapTupleFields;
......@@ -682,7 +684,7 @@ llvm_shutdown(int code, Datum arg)
}
}
/* helper for llvm_create_types */
/* helper for llvm_create_types, returning a global var's type */
static LLVMTypeRef
load_type(LLVMModuleRef mod, const char *name)
{
......@@ -702,6 +704,31 @@ load_type(LLVMModuleRef mod, const char *name)
return typ;
}
/* helper for llvm_create_types, returning a function's return type */
static LLVMTypeRef
load_return_type(LLVMModuleRef mod, const char *name)
{
LLVMValueRef value;
LLVMTypeRef typ;
/* this'll return a *pointer* to the function */
value = LLVMGetNamedFunction(mod, name);
if (!value)
elog(ERROR, "function %s is unknown", name);
/* get type of function pointer */
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;
}
/*
* Load required information, types, function signatures from llvmjit_types.c
* and make them available in global variables.
......@@ -740,6 +767,8 @@ llvm_create_types(void)
llvm_layout = pstrdup(LLVMGetDataLayoutStr(mod));
TypeSizeT = load_type(mod, "TypeSizeT");
TypeParamBool = load_return_type(mod, "FunctionReturningBool");
TypeStorageBool = load_type(mod, "TypeStorageBool");
TypePGFunction = load_type(mod, "TypePGFunction");
StructExprContext = load_type(mod, "StructExprContext");
StructExprEvalStep = load_type(mod, "StructExprEvalStep");
......
This diff is collapsed.
......@@ -45,8 +45,9 @@
* clang/LLVM will omit them. As this file will never be linked into
* anything, that's harmless.
*/
size_t TypeSizeT;
PGFunction TypePGFunction;
size_t TypeSizeT;
bool TypeStorageBool;
AggState StructAggState;
AggStatePerGroupData StructAggStatePerGroupData;
......@@ -73,6 +74,19 @@ AttributeTemplate(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
}
/*
* 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
* TypeBool (above), but also a way to determine the width of a returned
* integer. This allows us to keep compatible with non-stdbool using
* architectures.
*/
extern bool FunctionReturningBool(void);
bool
FunctionReturningBool(void)
{
return false;
}
/*
* To force signatures of functions used during JITing to be present,
......
......@@ -56,8 +56,11 @@ typedef struct LLVMJitContext
/* type and struct definitions */
extern LLVMTypeRef TypeSizeT;
extern LLVMTypeRef TypeParamBool;
extern LLVMTypeRef TypePGFunction;
extern LLVMTypeRef TypeSizeT;
extern LLVMTypeRef TypeStorageBool;
extern LLVMTypeRef StructtupleDesc;
extern LLVMTypeRef StructHeapTupleData;
extern LLVMTypeRef StructTupleTableSlot;
......
......@@ -78,6 +78,24 @@ l_sizet_const(size_t i)
return LLVMConstInt(TypeSizeT, i, false);
}
/*
* Emit constant boolean, as used for storage (e.g. global vars, structs).
*/
static inline LLVMValueRef
l_sbool_const(bool i)
{
return LLVMConstInt(TypeStorageBool, (int) i, false);
}
/*
* Emit constant boolean, as used for parameters (e.g. function parameters).
*/
static inline LLVMValueRef
l_pbool_const(bool i)
{
return LLVMConstInt(TypeParamBool, (int) i, false);
}
/*
* Load a pointer member idx from a struct.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment