jit: Stop emitting lifetime.end for LLVM 22.

The lifetime.end intrinsic can now only be used for stack memory
allocated with alloca[1][2][3].  We use it to tell LLVM about the
lifetime of function arguments/isnull values that we keep in palloc'd
memory, so that it can avoid spilling registers to memory.

We might need to rearrange things and put them on the stack, but that'll
take some research.  In the meantime, unbreak the build on LLVM 22.

[1] https://github.com/llvm/llvm-project/pull/149310
[2] https://llvm.org/docs/LangRef.html#llvm-lifetime-end-intrinsic
[3] https://llvm.org/docs/LangRef.html#i-alloca

Backpatch-through: 14
Reviewed-by: Matheus Alcantara <matheusssilv97@gmail.com> (earlier attempt)
Reviewed-by: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com> (earlier attempt)
Reviewed-by: Andres Freund <andres@anarazel.de> (earlier attempt)
Discussion: https://postgr.es/m/CA%2BhUKGJTumad75o8Zao-LFseEbt%3DenbUFCM7LZVV%3Dc8yg2i7dg%40mail.gmail.com
This commit is contained in:
Thomas Munro 2026-04-02 15:24:44 +13:00
parent 9ed5015f0d
commit 78cea19bf7

View file

@ -62,7 +62,9 @@ static LLVMValueRef build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod,
LLVMValueRef v_state,
ExprEvalStep *op,
int natts, LLVMValueRef *v_args);
#if LLVM_VERSION_MAJOR < 22
static LLVMValueRef create_LifetimeEnd(LLVMModuleRef mod);
#endif
/* macro making it easier to call ExecEval* functions */
#define build_EvalXFunc(b, mod, funcname, v_state, op, ...) \
@ -3007,14 +3009,11 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
LLVMModuleRef mod, FunctionCallInfo fcinfo,
LLVMValueRef *v_fcinfo_isnull)
{
LLVMContextRef lc;
LLVMValueRef v_fn;
LLVMValueRef v_fcinfo_isnullp;
LLVMValueRef v_retval;
LLVMValueRef v_fcinfo;
lc = LLVMGetModuleContext(mod);
v_fn = llvm_function_reference(context, b, mod, fcinfo);
v_fcinfo = l_ptr_const(fcinfo, l_ptr(StructFunctionCallInfoData));
@ -3030,11 +3029,14 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
if (v_fcinfo_isnull)
*v_fcinfo_isnull = l_load(b, TypeStorageBool, v_fcinfo_isnullp, "");
#if LLVM_VERSION_MAJOR < 22
/*
* Add lifetime-end annotation, signaling that writes to memory don't have
* to be retained (important for inlining potential).
*/
{
LLVMContextRef lc = LLVMGetModuleContext(mod);
LLVMValueRef v_lifetime = create_LifetimeEnd(mod);
LLVMValueRef params[2];
@ -3046,6 +3048,7 @@ BuildV1Call(LLVMJitContext *context, LLVMBuilderRef b,
params[1] = l_ptr_const(&fcinfo->isnull, l_ptr(LLVMInt8TypeInContext(lc)));
l_call(b, LLVMGetFunctionType(v_lifetime), v_lifetime, params, lengthof(params), "");
}
#endif
return v_retval;
}
@ -3083,6 +3086,7 @@ build_EvalXFuncInt(LLVMBuilderRef b, LLVMModuleRef mod, const char *funcname,
return v_ret;
}
#if LLVM_VERSION_MAJOR < 22
static LLVMValueRef
create_LifetimeEnd(LLVMModuleRef mod)
{
@ -3112,3 +3116,4 @@ create_LifetimeEnd(LLVMModuleRef mod)
return fn;
}
#endif