Skip to content

Commit

Permalink
codegen: handle recursive sparam calls in API
Browse files Browse the repository at this point in the history
Fixes #56690
  • Loading branch information
vtjnash committed Jan 14, 2025
1 parent 41363a0 commit c001d46
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 34 deletions.
45 changes: 23 additions & 22 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1377,11 +1377,10 @@ static const auto jlfieldisdefinedchecked_func = new JuliaFunction<TypeFnContext
static const auto jlgetcfunctiontrampoline_func = new JuliaFunction<>{
XSTR(jl_get_cfunction_trampoline),
[](LLVMContext &C) {
auto T_jlvalue = JuliaType::get_jlvalue_ty(C);
auto T_pjlvalue = PointerType::get(T_jlvalue, 0);
auto T_prjlvalue = PointerType::get(T_jlvalue, AddressSpace::Tracked);
auto T_ppjlvalue = PointerType::get(T_pjlvalue, 0);
auto T_pprjlvalue = PointerType::get(T_prjlvalue, 0);
auto T_pjlvalue = PointerType::get(C, 0);
auto T_prjlvalue = PointerType::get(C, AddressSpace::Tracked);
auto T_ppjlvalue = PointerType::get(C, 0);
auto T_derived = PointerType::get(C, AddressSpace::Derived);
return FunctionType::get(T_prjlvalue,
{
T_prjlvalue, // f (object)
Expand All @@ -1390,7 +1389,7 @@ static const auto jlgetcfunctiontrampoline_func = new JuliaFunction<>{
T_pjlvalue, // fill
FunctionType::get(getPointerTy(C), { getPointerTy(C), T_ppjlvalue }, false)->getPointerTo(), // trampoline
T_pjlvalue, // env
T_pprjlvalue, // vals
T_derived, // vals
}, false);
},
[](LLVMContext &C) { return AttributeList::get(C,
Expand Down Expand Up @@ -5610,18 +5609,23 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR
assert(jl_is_method_instance(mi));
if (mi == ctx.linfo) {
// handle self-recursion specially (TODO: assuming ci is a valid invoke for mi?)
jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed;
FunctionType *ft = ctx.f->getFunctionType();
StringRef protoname = ctx.f->getName();
Function *f = ctx.f;
FunctionType *ft = f->getFunctionType();
if (ft == ctx.types().T_jlfunc) {
result = emit_call_specfun_boxed(ctx, ctx.rettype, protoname, nullptr, argv, nargs, rt, age_ok);
handled = true;
Value *ret = emit_jlcall(ctx, f, nullptr, argv, nargs, julia_call);
result = update_julia_type(ctx, mark_julia_type(ctx, ret, true, ctx.rettype), rt);
}
else if (ft == ctx.types().T_jlfuncparams) {
Value *ret = emit_jlcall(ctx, f, ctx.spvals_ptr, argv, nargs, julia_call2);
result = update_julia_type(ctx, mark_julia_type(ctx, ret, true, ctx.rettype), rt);
}
else if (ft != ctx.types().T_jlfuncparams) {
else {
unsigned return_roots = 0;
jl_returninfo_t::CallingConv cc = jl_returninfo_t::CallingConv::Boxed;
StringRef protoname = f->getName();
result = emit_call_specfun_other(ctx, mi, ctx.rettype, protoname, nullptr, argv, nargs, &cc, &return_roots, rt, age_ok);
handled = true;
}
handled = true;
}
else {
if (ci) {
Expand All @@ -5630,7 +5634,6 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR
// check if we know how to handle this specptr
if (invoke == jl_fptr_const_return_addr) {
result = mark_julia_const(ctx, codeinst->rettype_const);
handled = true;
}
else {
bool specsig, needsparams;
Expand All @@ -5640,8 +5643,8 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR
push_frames(ctx, ctx.linfo, mi);
Value *r = emit_jlcall(ctx, jlinvoke_func, track_pjlvalue(ctx, literal_pointer_val(ctx, (jl_value_t*)mi)), argv, nargs, julia_call2);
result = mark_julia_type(ctx, r, true, rt);
handled = true;
} else {
}
else {
std::string name;
StringRef protoname;
bool need_to_emit = true;
Expand Down Expand Up @@ -5689,7 +5692,6 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR
result = emit_call_specfun_other(ctx, codeinst, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, &cc, &return_roots, rt, age_ok);
else
result = emit_call_specfun_boxed(ctx, codeinst->rettype, protoname, external ? codeinst : nullptr, argv, nargs, rt, age_ok);
handled = true;
if (need_to_emit) {
Function *trampoline_decl = cast<Function>(jl_Module->getNamedValue(protoname));
ctx.call_targets[codeinst] = {cc, return_roots, trampoline_decl, nullptr, specsig};
Expand All @@ -5698,6 +5700,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR
}
}
}
handled = true;
}
}
}
Expand Down Expand Up @@ -6078,8 +6081,7 @@ static jl_cgval_t emit_sparam(jl_codectx_t &ctx, size_t i)
return mark_julia_const(ctx, e);
}
}
assert(ctx.spvals_ptr != NULL);
Value *bp = emit_ptrgep(ctx, ctx.spvals_ptr, i * sizeof(jl_value_t*) + sizeof(jl_svec_t));
Value *bp = emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), i * sizeof(jl_value_t*) + sizeof(jl_svec_t));
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
Value *sp = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))));
setName(ctx.emission_context, sp, "sparam");
Expand Down Expand Up @@ -6131,8 +6133,7 @@ static jl_cgval_t emit_isdefined(jl_codectx_t &ctx, jl_value_t *sym, int allow_i
return mark_julia_const(ctx, jl_true);
}
}
assert(ctx.spvals_ptr != NULL);
Value *bp = emit_ptrgep(ctx, ctx.spvals_ptr, i * sizeof(jl_value_t*) + sizeof(jl_svec_t));
Value *bp = emit_ptrgep(ctx, maybe_decay_tracked(ctx, ctx.spvals_ptr), i * sizeof(jl_value_t*) + sizeof(jl_svec_t));
jl_aliasinfo_t ai = jl_aliasinfo_t::fromTBAA(ctx, ctx.tbaa().tbaa_const);
Value *sp = ai.decorateInst(ctx.builder.CreateAlignedLoad(ctx.types().T_prjlvalue, bp, Align(sizeof(void*))));
isnull = ctx.builder.CreateICmpNE(emit_typeof(ctx, sp, false, true), emit_tagfrom(ctx, jl_tvar_type));
Expand Down Expand Up @@ -8000,7 +8001,7 @@ static jl_cgval_t emit_cfunction(jl_codectx_t &ctx, jl_value_t *output_type, con
literal_pointer_val(ctx, (jl_value_t*)fill),
F,
closure_types ? literal_pointer_val(ctx, (jl_value_t*)unionall_env) : Constant::getNullValue(ctx.types().T_pjlvalue),
closure_types ? ctx.spvals_ptr : ConstantPointerNull::get(cast<PointerType>(ctx.types().T_pprjlvalue))
closure_types ? decay_derived(ctx, ctx.spvals_ptr) : ConstantPointerNull::get(ctx.builder.getPtrTy(AddressSpace::Derived))
});
outboxed = true;
}
Expand Down
23 changes: 11 additions & 12 deletions src/llvm-codegen-shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,45 +51,44 @@ namespace JuliaType {

static inline auto get_jlfunc_ty(llvm::LLVMContext &C) {
auto T_prjlvalue = get_prjlvalue_ty(C);
auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0);
auto T_pprjlvalue = llvm::PointerType::get(C, 0);
return llvm::FunctionType::get(T_prjlvalue, {
T_prjlvalue, // function
T_prjlvalue, // function
T_pprjlvalue, // args[]
llvm::Type::getInt32Ty(C)}, // nargs
false);
}

static inline auto get_jlfunc2_ty(llvm::LLVMContext &C) {
auto T_prjlvalue = get_prjlvalue_ty(C);
auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0);
auto T_pprjlvalue = llvm::PointerType::get(C, 0);
return llvm::FunctionType::get(T_prjlvalue, {
T_prjlvalue, // function
T_prjlvalue, // function
T_pprjlvalue, // args[]
llvm::Type::getInt32Ty(C), // nargs
T_prjlvalue}, // linfo
T_prjlvalue}, // linfo
false);
}

static inline auto get_jlfunc3_ty(llvm::LLVMContext &C) {
auto T_prjlvalue = get_prjlvalue_ty(C);
auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0);
auto T_pprjlvalue = llvm::PointerType::get(C, 0);
auto T = get_pjlvalue_ty(C, Derived);
return llvm::FunctionType::get(T_prjlvalue, {
T, // function
T, // function
T_pprjlvalue, // args[]
llvm::Type::getInt32Ty(C)}, // nargs
false);
}

static inline auto get_jlfuncparams_ty(llvm::LLVMContext &C) {
auto T_prjlvalue = get_prjlvalue_ty(C);
auto T_pprjlvalue = llvm::PointerType::get(T_prjlvalue, 0);
auto T_pprjlvalue = llvm::PointerType::get(C, 0);
return llvm::FunctionType::get(T_prjlvalue, {
T_prjlvalue, // function
T_prjlvalue, // function
T_pprjlvalue, // args[]
llvm::Type::getInt32Ty(C),
T_pprjlvalue, // linfo->sparam_vals
}, // nargs
llvm::Type::getInt32Ty(C), // nargs
T_prjlvalue}, // linfo->sparam_vals
false);
}

Expand Down

0 comments on commit c001d46

Please sign in to comment.