Skip to content

Commit 5f1eb66

Browse files
committed
WIP: Add ABIOverwrite type for def field
Together with #54899, this PR is intending to replicate the functionality of #54373, which allowed particular specializations to have a different ABI signature than what would be suggested by the MethodInstance's `specTypes` field. This PR handles that by adding a special `ABIOverwrite` type, which, when placed in the `def` field of a `CodeInstance` instructs the system to use the given signature instead.
1 parent 582585b commit 5f1eb66

21 files changed

+129
-85
lines changed

Compiler/src/stmtinfo.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function _add_edges_impl(edges::Vector{Any}, info::MethodMatchInfo, mi_edge::Boo
7171
mi = specialize_method(m) # don't allow `Method`-edge for this optimized format
7272
edge = mi
7373
else
74-
mi = edge.def
74+
mi = edge.def::MethodInstance
7575
end
7676
if mi.specTypes === m.spec_types
7777
add_one_edge!(edges, edge)
@@ -103,7 +103,7 @@ function add_one_edge!(edges::Vector{Any}, edge::MethodInstance)
103103
while i <= length(edges)
104104
edgeᵢ = edges[i]
105105
edgeᵢ isa Int && (i += 2 + edgeᵢ; continue)
106-
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def)
106+
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def::MethodInstance)
107107
edgeᵢ isa MethodInstance || (i += 1; continue)
108108
if edgeᵢ === edge && !(i > 1 && edges[i-1] isa Type)
109109
return # found existing covered edge
@@ -118,7 +118,7 @@ function add_one_edge!(edges::Vector{Any}, edge::CodeInstance)
118118
while i <= length(edges)
119119
edgeᵢ_orig = edgeᵢ = edges[i]
120120
edgeᵢ isa Int && (i += 2 + edgeᵢ; continue)
121-
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def)
121+
edgeᵢ isa CodeInstance && (edgeᵢ = edgeᵢ.def::MethodInstance)
122122
edgeᵢ isa MethodInstance || (i += 1; continue)
123123
if edgeᵢ === edge.def && !(i > 1 && edges[i-1] isa Type)
124124
if edgeᵢ_orig isa MethodInstance

base/boot.jl

+6
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,12 @@ struct InitError <: WrappedException
465465
error
466466
end
467467

468+
struct ABIOverwrite
469+
abi::Type
470+
def::MethodInstance
471+
ABIOverwrite(@nospecialize(abi::Type), def::MethodInstance) = new(abi, def)
472+
end
473+
468474
struct PrecompilableError <: Exception end
469475

470476
String(s::String) = s # no constructor yet

base/show.jl

+7-1
Original file line numberDiff line numberDiff line change
@@ -1353,7 +1353,13 @@ end
13531353
show(io::IO, mi::Core.MethodInstance) = show_mi(io, mi)
13541354
function show(io::IO, codeinst::Core.CodeInstance)
13551355
print(io, "CodeInstance for ")
1356-
show_mi(io, codeinst.def)
1356+
def = codeinst.def
1357+
if isa(def, Core.ABIOverwrite)
1358+
show_mi(io, def.def)
1359+
print(io, " (ABI Overridden)")
1360+
else
1361+
show_mi(io, def::MethodInstance)
1362+
end
13571363
end
13581364

13591365
function show_mi(io::IO, mi::Core.MethodInstance, from_stackframe::Bool=false)

src/aotcompile.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ jl_get_llvm_mis_impl(void *native_code, size_t *num_elements, jl_method_instance
105105
assert(*num_elements == map.size());
106106
size_t i = 0;
107107
for (auto &ci : map) {
108-
data[i++] = ci.first->def;
108+
data[i++] = jl_get_ci_mi(ci.first);
109109
}
110110
}
111111

@@ -455,14 +455,14 @@ static void compile_workqueue(jl_codegen_params_t &params, egal_set &method_root
455455
if ((policy != CompilationPolicy::Default || params.params->trim) &&
456456
jl_atomic_load_relaxed(&codeinst->inferred) == jl_nothing) {
457457
// XXX: SOURCE_MODE_FORCE_SOURCE is wrong here (neither sufficient nor necessary)
458-
codeinst = jl_type_infer(codeinst->def, jl_atomic_load_relaxed(&codeinst->max_world), SOURCE_MODE_FORCE_SOURCE);
458+
codeinst = jl_type_infer(jl_get_ci_mi(codeinst), jl_atomic_load_relaxed(&codeinst->max_world), SOURCE_MODE_FORCE_SOURCE);
459459
}
460460
if (codeinst) {
461461
orc::ThreadSafeModule result_m =
462-
jl_create_ts_module(name_from_method_instance(codeinst->def),
462+
jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)),
463463
params.tsctx, params.DL, params.TargetTriple);
464464
auto decls = jl_emit_codeinst(result_m, codeinst, NULL, params);
465-
record_method_roots(method_roots, codeinst->def);
465+
record_method_roots(method_roots, jl_get_ci_mi(codeinst));
466466
if (result_m)
467467
it = compiled_functions.insert(std::make_pair(codeinst, std::make_pair(std::move(result_m), std::move(decls)))).first;
468468
}
@@ -501,7 +501,7 @@ static void compile_workqueue(jl_codegen_params_t &params, egal_set &method_root
501501
proto.decl->setLinkage(GlobalVariable::InternalLinkage);
502502
//protodecl->setAlwaysInline();
503503
jl_init_function(proto.decl, params.TargetTriple);
504-
jl_method_instance_t *mi = codeinst->def;
504+
jl_method_instance_t *mi = jl_get_ci_mi(codeinst);
505505
size_t nrealargs = jl_nparams(mi->specTypes); // number of actual arguments being passed
506506
bool is_opaque_closure = jl_is_method(mi->def.value) && mi->def.method->is_for_opaque_closure;
507507
// TODO: maybe this can be cached in codeinst->specfptr?
@@ -641,12 +641,12 @@ void *jl_create_native_impl(jl_array_t *methods, LLVMOrcThreadSafeModuleRef llvm
641641
data->jl_fvar_map[codeinst] = std::make_tuple((uint32_t)-3, (uint32_t)-3);
642642
}
643643
else {
644-
orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(codeinst->def),
644+
orc::ThreadSafeModule result_m = jl_create_ts_module(name_from_method_instance(jl_get_ci_mi(codeinst)),
645645
params.tsctx, clone.getModuleUnlocked()->getDataLayout(),
646646
Triple(clone.getModuleUnlocked()->getTargetTriple()));
647647
jl_llvm_functions_t decls = jl_emit_codeinst(result_m, codeinst, NULL, params);
648648
JL_GC_PROMISE_ROOTED(codeinst->def); // analyzer seems confused
649-
record_method_roots(method_roots, codeinst->def);
649+
record_method_roots(method_roots, jl_get_ci_mi(codeinst));
650650
if (result_m)
651651
compiled_functions[codeinst] = {std::move(result_m), std::move(decls)};
652652
else if (jl_options.trim != JL_TRIM_NO) {
@@ -2267,7 +2267,7 @@ void jl_get_llvmf_defn_impl(jl_llvmf_dump_t* dump, jl_method_instance_t *mi, jl_
22672267
// To get correct names in the IR this needs to be at least 2
22682268
output.temporary_roots = jl_alloc_array_1d(jl_array_any_type, 0);
22692269
JL_GC_PUSH1(&output.temporary_roots);
2270-
auto decls = jl_emit_code(m, mi, src, output);
2270+
auto decls = jl_emit_code(m, mi, src, NULL, output);
22712271
output.temporary_roots = nullptr;
22722272
JL_GC_POP(); // GC the global_targets array contents now since reflection doesn't need it
22732273

src/builtins.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -1589,11 +1589,12 @@ JL_CALLABLE(jl_f_invoke)
15891589
return jl_gf_invoke_by_method(m, args[0], &args[2], nargs - 1);
15901590
} else if (jl_is_code_instance(argtypes)) {
15911591
jl_code_instance_t *codeinst = (jl_code_instance_t*)args[1];
1592+
jl_method_instance_t *mi = jl_get_ci_mi(codeinst);
15921593
jl_callptr_t invoke = jl_atomic_load_acquire(&codeinst->invoke);
15931594
// N.B.: specTypes need not be a subtype of the method signature. We need to check both.
1594-
if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->specTypes) ||
1595-
(jl_is_method(codeinst->def->def.value) && !jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)codeinst->def->def.method->sig))) {
1596-
jl_type_error("invoke: argument type error", codeinst->def->specTypes, arg_tuple(args[0], &args[2], nargs - 1));
1595+
if (!jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)mi->specTypes) ||
1596+
(jl_is_method(mi->def.value) && !jl_tuple1_isa(args[0], &args[2], nargs - 1, (jl_datatype_t*)mi->def.method->sig))) {
1597+
jl_type_error("invoke: argument type error", mi->specTypes, arg_tuple(args[0], &args[2], nargs - 1));
15971598
}
15981599
if (jl_atomic_load_relaxed(&codeinst->min_world) > jl_current_task->world_age ||
15991600
jl_current_task->world_age > jl_atomic_load_relaxed(&codeinst->max_world)) {
@@ -1609,7 +1610,7 @@ JL_CALLABLE(jl_f_invoke)
16091610
if (codeinst->owner != jl_nothing) {
16101611
jl_error("Failed to invoke or compile external codeinst");
16111612
}
1612-
return jl_invoke(args[0], &args[2], nargs - 1, codeinst->def);
1613+
return jl_invoke(args[0], &args[2], nargs - 1, mi);
16131614
}
16141615
}
16151616
if (!jl_is_tuple_type(jl_unwrap_unionall(argtypes)))

0 commit comments

Comments
 (0)