@@ -3046,9 +3046,8 @@ static bool uses_specsig(jl_value_t *sig, bool needsparams, jl_value_t *rettype,
3046
3046
return false; // jlcall sig won't require any box allocations
3047
3047
}
3048
3048
3049
- static std::pair<bool, bool> uses_specsig(jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig)
3049
+ static std::pair<bool, bool> uses_specsig(jl_value_t *abi, jl_method_instance_t *lam, jl_value_t *rettype, bool prefer_specsig)
3050
3050
{
3051
- jl_value_t *sig = lam->specTypes;
3052
3051
bool needsparams = false;
3053
3052
if (jl_is_method(lam->def.method)) {
3054
3053
if ((size_t)jl_subtype_env_size(lam->def.method->sig) != jl_svec_len(lam->sparam_vals))
@@ -3058,7 +3057,7 @@ static std::pair<bool, bool> uses_specsig(jl_method_instance_t *lam, jl_value_t
3058
3057
needsparams = true;
3059
3058
}
3060
3059
}
3061
- return std::make_pair(uses_specsig(sig , needsparams, rettype, prefer_specsig), needsparams);
3060
+ return std::make_pair(uses_specsig(abi , needsparams, rettype, prefer_specsig), needsparams);
3062
3061
}
3063
3062
3064
3063
@@ -4373,6 +4372,7 @@ static jl_llvm_functions_t
4373
4372
orc::ThreadSafeModule &TSM,
4374
4373
jl_method_instance_t *lam,
4375
4374
jl_code_info_t *src,
4375
+ jl_value_t *abi,
4376
4376
jl_value_t *rettype,
4377
4377
jl_codegen_params_t ¶ms);
4378
4378
@@ -5490,6 +5490,13 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, jl_expr_t *ex, jl_value_t *rt)
5490
5490
return emit_invoke(ctx, lival, argv, nargs, rt);
5491
5491
}
5492
5492
5493
+ static jl_value_t *get_ci_abi(jl_code_instance_t *ci)
5494
+ {
5495
+ if (jl_typeof(ci->def) == (jl_value_t*)jl_abioverwrite_type)
5496
+ return ((jl_abi_overwrite_t*)ci->def)->abi;
5497
+ return jl_get_ci_mi(ci)->specTypes;
5498
+ }
5499
+
5493
5500
static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayRef<jl_cgval_t> argv, size_t nargs, jl_value_t *rt)
5494
5501
{
5495
5502
++EmittedInvokes;
@@ -5525,7 +5532,7 @@ static jl_cgval_t emit_invoke(jl_codectx_t &ctx, const jl_cgval_t &lival, ArrayR
5525
5532
}
5526
5533
else if (invoke != jl_fptr_sparam_addr) {
5527
5534
bool specsig, needsparams;
5528
- std::tie(specsig, needsparams) = uses_specsig(mi, codeinst->rettype, ctx.params->prefer_specsig);
5535
+ std::tie(specsig, needsparams) = uses_specsig(get_ci_abi(codeinst), mi, codeinst->rettype, ctx.params->prefer_specsig);
5529
5536
std::string name;
5530
5537
StringRef protoname;
5531
5538
bool need_to_emit = true;
@@ -7200,7 +7207,7 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M
7200
7207
jl_init_function(f, params.TargetTriple);
7201
7208
if (trim_may_error(params.params->trim)) {
7202
7209
// TODO: Debuginfo!
7203
- push_frames(ctx, ctx.linfo, codeinst->def , 1);
7210
+ push_frames(ctx, ctx.linfo, jl_get_ci_mi( codeinst) , 1);
7204
7211
}
7205
7212
jl_name_jlfunc_args(params, f);
7206
7213
//f->setAlwaysInline();
@@ -7217,7 +7224,7 @@ Function *emit_tojlinvoke(jl_code_instance_t *codeinst, StringRef theFptrName, M
7217
7224
}
7218
7225
else {
7219
7226
theFunc = prepare_call(jlinvoke_func);
7220
- theFarg = literal_pointer_val(ctx, (jl_value_t*)codeinst->def );
7227
+ theFarg = literal_pointer_val(ctx, (jl_value_t*)jl_get_ci_mi( codeinst) );
7221
7228
}
7222
7229
theFarg = track_pjlvalue(ctx, theFarg);
7223
7230
auto args = f->arg_begin();
@@ -8327,13 +8334,13 @@ get_specsig_di(jl_codectx_t &ctx, jl_debugcache_t &debuginfo, jl_value_t *rt, jl
8327
8334
}
8328
8335
8329
8336
/* aka Core.Compiler.tuple_tfunc */
8330
- static jl_datatype_t *compute_va_type(jl_method_instance_t *lam , size_t nreq)
8337
+ static jl_datatype_t *compute_va_type(jl_value_t *sig , size_t nreq)
8331
8338
{
8332
- size_t nvargs = jl_nparams(lam->specTypes )-nreq;
8339
+ size_t nvargs = jl_nparams(sig )-nreq;
8333
8340
jl_svec_t *tupargs = jl_alloc_svec(nvargs);
8334
8341
JL_GC_PUSH1(&tupargs);
8335
- for (size_t i = nreq; i < jl_nparams(lam->specTypes ); ++i) {
8336
- jl_value_t *argType = jl_nth_slot_type(lam->specTypes , i);
8342
+ for (size_t i = nreq; i < jl_nparams(sig ); ++i) {
8343
+ jl_value_t *argType = jl_nth_slot_type(sig , i);
8337
8344
// n.b. specTypes is required to be a datatype by construction for specsig
8338
8345
if (is_uniquerep_Type(argType))
8339
8346
argType = jl_typeof(jl_tparam0(argType));
@@ -8373,6 +8380,7 @@ static jl_llvm_functions_t
8373
8380
orc::ThreadSafeModule &TSM,
8374
8381
jl_method_instance_t *lam,
8375
8382
jl_code_info_t *src,
8383
+ jl_value_t *abi,
8376
8384
jl_value_t *jlrettype,
8377
8385
jl_codegen_params_t ¶ms)
8378
8386
{
@@ -8453,7 +8461,7 @@ static jl_llvm_functions_t
8453
8461
int n_ssavalues = jl_is_long(src->ssavaluetypes) ? jl_unbox_long(src->ssavaluetypes) : jl_array_nrows(src->ssavaluetypes);
8454
8462
size_t vinfoslen = jl_array_dim0(src->slotflags);
8455
8463
ctx.slots.resize(vinfoslen, jl_varinfo_t(ctx.builder.getContext()));
8456
- assert(lam->specTypes ); // the specTypes field should always be assigned
8464
+ assert(abi ); // the specTypes field should always be assigned
8457
8465
8458
8466
8459
8467
// create SAvalue locations for SSAValue objects
@@ -8462,7 +8470,7 @@ static jl_llvm_functions_t
8462
8470
ctx.ssavalue_usecount.assign(n_ssavalues, 0);
8463
8471
8464
8472
bool specsig, needsparams;
8465
- std::tie(specsig, needsparams) = uses_specsig(lam, jlrettype, params.params->prefer_specsig);
8473
+ std::tie(specsig, needsparams) = uses_specsig(abi, lam, jlrettype, params.params->prefer_specsig);
8466
8474
8467
8475
// step 3. some variable analysis
8468
8476
size_t i;
@@ -8472,7 +8480,7 @@ static jl_llvm_functions_t
8472
8480
jl_sym_t *argname = slot_symbol(ctx, i);
8473
8481
if (argname == jl_unused_sym)
8474
8482
continue;
8475
- jl_value_t *ty = jl_nth_slot_type(lam->specTypes , i);
8483
+ jl_value_t *ty = jl_nth_slot_type(abi , i);
8476
8484
// TODO: jl_nth_slot_type should call jl_rewrap_unionall
8477
8485
// specTypes is required to be a datatype by construction for specsig, but maybe not otherwise
8478
8486
// OpaqueClosure implicitly loads the env
@@ -8490,7 +8498,7 @@ static jl_llvm_functions_t
8490
8498
if (va && ctx.vaSlot != -1) {
8491
8499
jl_varinfo_t &varinfo = ctx.slots[ctx.vaSlot];
8492
8500
varinfo.isArgument = true;
8493
- vatyp = specsig ? compute_va_type(lam , nreq) : (jl_tuple_type);
8501
+ vatyp = specsig ? compute_va_type(abi , nreq) : (jl_tuple_type);
8494
8502
varinfo.value = mark_julia_type(ctx, (Value*)NULL, false, vatyp);
8495
8503
}
8496
8504
@@ -8542,7 +8550,7 @@ static jl_llvm_functions_t
8542
8550
ArgNames[i] = name;
8543
8551
}
8544
8552
}
8545
- returninfo = get_specsig_function(ctx, M, NULL, declarations.specFunctionObject, lam->specTypes ,
8553
+ returninfo = get_specsig_function(ctx, M, NULL, declarations.specFunctionObject, abi ,
8546
8554
jlrettype, ctx.is_opaque_closure, JL_FEAT_TEST(ctx,gcstack_arg),
8547
8555
ArgNames, nreq);
8548
8556
f = cast<Function>(returninfo.decl.getCallee());
@@ -8576,7 +8584,7 @@ static jl_llvm_functions_t
8576
8584
std::string wrapName;
8577
8585
raw_string_ostream(wrapName) << "jfptr_" << ctx.name << "_" << jl_atomic_fetch_add_relaxed(&globalUniqueGeneratedNames, 1);
8578
8586
declarations.functionObject = wrapName;
8579
- size_t nparams = jl_nparams(lam->specTypes );
8587
+ size_t nparams = jl_nparams(abi );
8580
8588
gen_invoke_wrapper(lam, jlrettype, returninfo, nparams, retarg, ctx.is_opaque_closure, declarations.functionObject, M, ctx.emission_context);
8581
8589
// TODO: add attributes: maybe_mark_argument_dereferenceable(Arg, argType)
8582
8590
// TODO: add attributes: dereferenceable<sizeof(void*) * nreq>
@@ -8596,10 +8604,10 @@ static jl_llvm_functions_t
8596
8604
declarations.functionObject = needsparams ? "jl_fptr_sparam" : "jl_fptr_args";
8597
8605
}
8598
8606
8599
- if (ctx.emission_context.debug_level >= 2 && lam->def.method && jl_is_method(lam->def.method) && lam->specTypes != (jl_value_t*)jl_emptytuple_type) {
8607
+ if (ctx.emission_context.debug_level >= 2 && lam->def.method && jl_is_method(lam->def.method) && abi != (jl_value_t*)jl_emptytuple_type) {
8600
8608
ios_t sigbuf;
8601
8609
ios_mem(&sigbuf, 0);
8602
- jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)lam->specTypes );
8610
+ jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)abi );
8603
8611
f->addFnAttr("julia.fsig", StringRef(sigbuf.buf, sigbuf.size));
8604
8612
ios_close(&sigbuf);
8605
8613
}
@@ -8656,7 +8664,7 @@ static jl_llvm_functions_t
8656
8664
else if (!specsig)
8657
8665
subrty = debugcache.jl_di_func_sig;
8658
8666
else
8659
- subrty = get_specsig_di(ctx, debugcache, jlrettype, lam->specTypes , dbuilder);
8667
+ subrty = get_specsig_di(ctx, debugcache, jlrettype, abi , dbuilder);
8660
8668
SP = dbuilder.createFunction(nullptr
8661
8669
,dbgFuncName // Name
8662
8670
,f->getName() // LinkageName
@@ -8987,7 +8995,7 @@ static jl_llvm_functions_t
8987
8995
nullptr, nullptr, /*isboxed*/true, AtomicOrdering::NotAtomic, false, sizeof(void*));
8988
8996
}
8989
8997
else {
8990
- jl_value_t *argType = jl_nth_slot_type(lam->specTypes , i);
8998
+ jl_value_t *argType = jl_nth_slot_type(abi , i);
8991
8999
// TODO: jl_nth_slot_type should call jl_rewrap_unionall?
8992
9000
// specTypes is required to be a datatype by construction for specsig, but maybe not otherwise
8993
9001
bool isboxed = deserves_argbox(argType);
@@ -9061,10 +9069,10 @@ static jl_llvm_functions_t
9061
9069
assert(vi.boxroot == NULL);
9062
9070
}
9063
9071
else if (specsig) {
9064
- ctx.nvargs = jl_nparams(lam->specTypes ) - nreq;
9072
+ ctx.nvargs = jl_nparams(abi ) - nreq;
9065
9073
SmallVector<jl_cgval_t, 0> vargs(ctx.nvargs);
9066
- for (size_t i = nreq; i < jl_nparams(lam->specTypes ); ++i) {
9067
- jl_value_t *argType = jl_nth_slot_type(lam->specTypes , i);
9074
+ for (size_t i = nreq; i < jl_nparams(abi ); ++i) {
9075
+ jl_value_t *argType = jl_nth_slot_type(abi , i);
9068
9076
// n.b. specTypes is required to be a datatype by construction for specsig
9069
9077
bool isboxed = deserves_argbox(argType);
9070
9078
Type *llvmArgType = isboxed ? ctx.types().T_prjlvalue : julia_type_to_llvm(ctx, argType);
@@ -10011,6 +10019,7 @@ jl_llvm_functions_t jl_emit_code(
10011
10019
orc::ThreadSafeModule &m,
10012
10020
jl_method_instance_t *li,
10013
10021
jl_code_info_t *src,
10022
+ jl_value_t *abi,
10014
10023
jl_codegen_params_t ¶ms)
10015
10024
{
10016
10025
JL_TIMING(CODEGEN, CODEGEN_LLVM);
@@ -10019,8 +10028,10 @@ jl_llvm_functions_t jl_emit_code(
10019
10028
assert((params.params == &jl_default_cgparams /* fast path */ || !params.cache ||
10020
10029
compare_cgparams(params.params, &jl_default_cgparams)) &&
10021
10030
"functions compiled with custom codegen params must not be cached");
10031
+ if (!abi)
10032
+ abi = li->specTypes;
10022
10033
JL_TRY {
10023
- decls = emit_function(m, li, src, src->rettype, params);
10034
+ decls = emit_function(m, li, src, abi, src->rettype, params);
10024
10035
auto stream = *jl_ExecutionEngine->get_dump_emitted_mi_name_stream();
10025
10036
if (stream) {
10026
10037
jl_printf(stream, "%s\t", decls.specFunctionObject.c_str());
@@ -10089,11 +10100,11 @@ jl_llvm_functions_t jl_emit_codeinst(
10089
10100
jl_codegen_params_t ¶ms)
10090
10101
{
10091
10102
JL_TIMING(CODEGEN, CODEGEN_Codeinst);
10092
- jl_timing_show_method_instance(codeinst->def , JL_TIMING_DEFAULT_BLOCK);
10103
+ jl_timing_show_method_instance(jl_get_ci_mi( codeinst) , JL_TIMING_DEFAULT_BLOCK);
10093
10104
JL_GC_PUSH1(&src);
10094
10105
if (!src) {
10095
10106
src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred);
10096
- jl_method_instance_t *mi = codeinst->def ;
10107
+ jl_method_instance_t *mi = jl_get_ci_mi( codeinst) ;
10097
10108
jl_method_t *def = mi->def.method;
10098
10109
// Check if this is the generic method for opaque closure wrappers -
10099
10110
// if so, this must compile specptr such that it holds the specptr -> invoke wrapper
@@ -10111,15 +10122,15 @@ jl_llvm_functions_t jl_emit_codeinst(
10111
10122
}
10112
10123
}
10113
10124
assert(jl_egal((jl_value_t*)jl_atomic_load_relaxed(&codeinst->debuginfo), (jl_value_t*)src->debuginfo) && "trying to generate code for a codeinst for an incompatible src");
10114
- jl_llvm_functions_t decls = jl_emit_code(m, codeinst->def , src, params);
10125
+ jl_llvm_functions_t decls = jl_emit_code(m, jl_get_ci_mi( codeinst) , src, get_ci_abi(codeinst) , params);
10115
10126
10116
10127
const std::string &specf = decls.specFunctionObject;
10117
10128
const std::string &f = decls.functionObject;
10118
10129
if (params.cache && !f.empty()) {
10119
10130
// Prepare debug info to receive this function
10120
10131
// record that this function name came from this linfo,
10121
10132
// so we can build a reverse mapping for debug-info.
10122
- bool toplevel = !jl_is_method(codeinst->def ->def.method);
10133
+ bool toplevel = !jl_is_method(jl_get_ci_mi( codeinst) ->def.method);
10123
10134
if (!toplevel) {
10124
10135
//Safe b/c params holds context lock
10125
10136
const DataLayout &DL = m.getModuleUnlocked()->getDataLayout();
@@ -10135,7 +10146,7 @@ jl_llvm_functions_t jl_emit_codeinst(
10135
10146
jl_value_t *inferred = jl_atomic_load_relaxed(&codeinst->inferred);
10136
10147
// don't change inferred state
10137
10148
if (inferred) {
10138
- jl_method_t *def = codeinst->def ->def.method;
10149
+ jl_method_t *def = jl_get_ci_mi( codeinst) ->def.method;
10139
10150
if (// keep code when keeping everything
10140
10151
!(JL_DELETE_NON_INLINEABLE) ||
10141
10152
// aggressively keep code when debugging level >= 2
0 commit comments