Skip to content

Commit 7d176fd

Browse files
committed
delete unused code, so the jit no longer uses the inferred field at all
1 parent 4703e8e commit 7d176fd

File tree

5 files changed

+80
-87
lines changed

5 files changed

+80
-87
lines changed

src/codegen.cpp

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10050,29 +10050,19 @@ jl_llvm_functions_t jl_emit_codeinst(
1005010050
{
1005110051
JL_TIMING(CODEGEN, CODEGEN_Codeinst);
1005210052
jl_timing_show_method_instance(jl_get_ci_mi(codeinst), JL_TIMING_DEFAULT_BLOCK);
10053-
JL_GC_PUSH1(&src);
1005410053
if (!src) {
10055-
src = (jl_code_info_t*)jl_atomic_load_relaxed(&codeinst->inferred);
1005610054
jl_method_instance_t *mi = jl_get_ci_mi(codeinst);
10057-
jl_method_t *def = mi->def.method;
10058-
// Check if this is the generic method for opaque closure wrappers -
10059-
// if so, this must compile specptr such that it holds the specptr -> invoke wrapper
10055+
// Assert that this this is the generic method for opaque closure wrappers:
10056+
// this signals to instead compile specptr such that it holds the specptr -> invoke wrapper
1006010057
// to satisfy the dispatching implementation requirements of jl_f_opaque_closure_call
10061-
if (def == jl_opaque_closure_method) {
10062-
JL_GC_POP();
10058+
if (mi->def.method == jl_opaque_closure_method) {
1006310059
return jl_emit_oc_wrapper(m, params, mi, codeinst->rettype);
1006410060
}
10065-
if (src && (jl_value_t*)src != jl_nothing && jl_is_method(def))
10066-
src = jl_uncompress_ir(def, codeinst, (jl_value_t*)src);
10067-
if (!src || !jl_is_code_info(src)) {
10068-
JL_GC_POP();
10069-
m = orc::ThreadSafeModule();
10070-
return jl_llvm_functions_t(); // failed
10071-
}
10061+
m = orc::ThreadSafeModule();
10062+
return jl_llvm_functions_t(); // user error
1007210063
}
1007310064
//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");
1007410065
jl_llvm_functions_t decls = jl_emit_code(m, jl_get_ci_mi(codeinst), src, get_ci_abi(codeinst), params);
10075-
JL_GC_POP();
1007610066
return decls;
1007710067
}
1007810068

src/gf.c

Lines changed: 53 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,59 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a
337337
return dt;
338338
}
339339

340+
// only relevant for bootstrapping. otherwise fairly broken.
341+
static int emit_codeinst_and_edges(jl_code_instance_t *codeinst)
342+
{
343+
jl_value_t *code = jl_atomic_load_relaxed(&codeinst->inferred);
344+
if (code) {
345+
if (jl_atomic_load_relaxed(&codeinst->invoke) != NULL)
346+
return 1;
347+
if (code != jl_nothing) {
348+
JL_GC_PUSH1(&code);
349+
jl_method_instance_t *mi = jl_get_ci_mi(codeinst);
350+
jl_method_t *def = mi->def.method;
351+
if (jl_is_string(code) && jl_is_method(def))
352+
code = (jl_value_t*)jl_uncompress_ir(def, codeinst, (jl_value_t*)code);
353+
if (jl_is_code_info(code)) {
354+
jl_emit_codeinst_to_jit(codeinst, (jl_code_info_t*)code);
355+
if (0) {
356+
// next emit all the invoke edges too (if this seems profitable)
357+
jl_array_t *src = ((jl_code_info_t*)code)->code;
358+
for (size_t i = 0; i < jl_array_dim0(src); i++) {
359+
jl_value_t *stmt = jl_array_ptr_ref(src, i);
360+
if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == jl_assign_sym)
361+
stmt = jl_exprarg(stmt, 1);
362+
if (jl_is_expr(stmt) && ((jl_expr_t*)stmt)->head == jl_invoke_sym) {
363+
jl_value_t *invoke = jl_exprarg(stmt, 0);
364+
if (jl_is_code_instance(invoke))
365+
emit_codeinst_and_edges((jl_code_instance_t*)invoke);
366+
}
367+
}
368+
}
369+
JL_GC_POP();
370+
return 1;
371+
}
372+
JL_GC_POP();
373+
}
374+
}
375+
return 0;
376+
}
377+
378+
// Opportunistic SOURCE_MODE_ABI cache lookup, only for bootstrapping.
379+
static jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world)
380+
{
381+
jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache);
382+
for (; codeinst; codeinst = jl_atomic_load_relaxed(&codeinst->next)) {
383+
if (codeinst->owner != jl_nothing)
384+
continue;
385+
if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)) {
386+
if (emit_codeinst_and_edges(codeinst))
387+
return codeinst;
388+
}
389+
}
390+
return NULL;
391+
}
392+
340393
// run type inference on lambda "mi" for given argument types.
341394
// returns the inferred source, and may cache the result in mi
342395
// if successful, also updates the mi argument to describe the validity of this src
@@ -2571,23 +2624,6 @@ jl_code_instance_t *jl_method_compiled(jl_method_instance_t *mi, size_t world)
25712624
return NULL;
25722625
}
25732626

2574-
// Opportunistic SOURCE_MODE_ABI cache lookup.
2575-
jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world)
2576-
{
2577-
jl_code_instance_t *codeinst = jl_atomic_load_relaxed(&mi->cache);
2578-
for (; codeinst; codeinst = jl_atomic_load_relaxed(&codeinst->next)) {
2579-
if (codeinst->owner != jl_nothing)
2580-
continue;
2581-
2582-
if (jl_atomic_load_relaxed(&codeinst->min_world) <= world && world <= jl_atomic_load_relaxed(&codeinst->max_world)) {
2583-
jl_value_t *code = jl_atomic_load_relaxed(&codeinst->inferred);
2584-
if (code && (code != jl_nothing || (jl_atomic_load_relaxed(&codeinst->invoke) != NULL)))
2585-
return codeinst;
2586-
}
2587-
}
2588-
return NULL;
2589-
}
2590-
25912627
jl_mutex_t precomp_statement_out_lock;
25922628

25932629
_Atomic(uint8_t) jl_force_trace_compile_timing_enabled = 0;

src/jitlayers.cpp

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -794,47 +794,6 @@ void jl_emit_codeinst_to_jit_impl(
794794
emittedmodules[codeinst] = std::move(result_m);
795795
}
796796

797-
static void recursive_compile_graph(
798-
jl_code_instance_t *codeinst,
799-
jl_code_info_t *src)
800-
{
801-
jl_emit_codeinst_to_jit(codeinst, src);
802-
DenseSet<jl_code_instance_t*> Seen;
803-
SmallVector<jl_code_instance_t*> workqueue;
804-
workqueue.push_back(codeinst);
805-
// if any edges were incomplete, try to complete them now
806-
while (!workqueue.empty()) {
807-
auto this_code = workqueue.pop_back_val();
808-
if (Seen.insert(this_code).second) {
809-
jl_code_instance_t *compiled_ci = jl_method_compiled_egal(codeinst);
810-
if (!compiled_ci) {
811-
if (this_code != codeinst) {
812-
JL_GC_PROMISE_ROOTED(this_code); // rooted transitively from following edges from original argument
813-
jl_emit_codeinst_to_jit(this_code, nullptr); // contains safepoints
814-
}
815-
jl_unique_gcsafe_lock lock(engine_lock);
816-
auto edges = complete_graph.find(this_code);
817-
if (edges != complete_graph.end()) {
818-
workqueue.append(edges->second);
819-
}
820-
}
821-
}
822-
}
823-
}
824-
825-
// this generates llvm code for the lambda info
826-
// and adds the result to the jitlayers
827-
// (and the shadow module),
828-
// and generates code for it
829-
static void _jl_compile_codeinst(
830-
jl_code_instance_t *codeinst,
831-
jl_code_info_t *src)
832-
{
833-
recursive_compile_graph(codeinst, src);
834-
jl_compile_codeinst_now(codeinst);
835-
assert(jl_is_compiled_codeinst(codeinst));
836-
}
837-
838797

839798
const char *jl_generate_ccallable(Module *llvmmod, void *sysimg_handle, jl_value_t *declrt, jl_value_t *sigt, jl_codegen_params_t &params);
840799

@@ -858,7 +817,6 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
858817
orc::ThreadSafeModule backing;
859818
bool success = true;
860819
const char *name = "";
861-
SmallVector<jl_code_instance_t*,0> dependencies;
862820
if (into == NULL) {
863821
ctx = pparams ? pparams->tsctx : jl_ExecutionEngine->makeContext();
864822
backing = jl_create_ts_module("cextern", ctx, DL, TargetTriple);
@@ -886,11 +844,16 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
886844
}
887845
params.tsctx_lock = params.tsctx.getLock(); // re-acquire lock
888846
if (success && params.cache) {
889-
for (auto &it : params.workqueue) {
847+
size_t newest_world = jl_atomic_load_acquire(&jl_world_counter);
848+
for (auto &it : params.workqueue) { // really just zero or one, and just the ABI not the rest of the metadata
890849
jl_code_instance_t *codeinst = it.first;
891850
JL_GC_PROMISE_ROOTED(codeinst);
892-
dependencies.push_back(codeinst);
893-
recursive_compile_graph(codeinst, nullptr);
851+
jl_code_instance_t *newest_ci = jl_type_infer(jl_get_ci_mi(codeinst), newest_world, SOURCE_MODE_ABI);
852+
if (newest_ci) {
853+
if (jl_egal(codeinst->rettype, newest_ci->rettype))
854+
it.first = codeinst;
855+
jl_compile_codeinst_now(newest_ci);
856+
}
894857
}
895858
jl_analyze_workqueue(nullptr, params, true);
896859
assert(params.workqueue.empty());
@@ -903,8 +866,6 @@ int jl_compile_extern_c_impl(LLVMOrcThreadSafeModuleRef llvmmod, void *p, void *
903866
{ // lock scope
904867
jl_unique_gcsafe_lock lock(extern_c_lock);
905868
if (!jl_ExecutionEngine->getGlobalValueAddress(name)) {
906-
for (auto dep : dependencies)
907-
jl_compile_codeinst_now(dep);
908869
{
909870
auto Lock = backing.getContext().getLock();
910871
jl_ExecutionEngine->optimizeDLSyms(*backing.getModuleUnlocked()); // safepoint
@@ -975,7 +936,7 @@ int jl_compile_codeinst_impl(jl_code_instance_t *ci)
975936
if (!jl_is_compiled_codeinst(ci)) {
976937
++SpecFPtrCount;
977938
uint64_t start = jl_typeinf_timing_begin();
978-
_jl_compile_codeinst(ci, NULL);
939+
jl_compile_codeinst_now(ci);
979940
jl_typeinf_timing_end(start, 0);
980941
newly_compiled = 1;
981942
}
@@ -1006,8 +967,7 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec)
1006967
}
1007968
else {
1008969
jl_method_instance_t *mi = jl_get_ci_mi(unspec);
1009-
jl_code_instance_t *uninferred = jl_cached_uninferred(
1010-
jl_atomic_load_relaxed(&mi->cache), 1);
970+
jl_code_instance_t *uninferred = jl_cached_uninferred(jl_atomic_load_relaxed(&mi->cache), 1);
1011971
assert(uninferred);
1012972
src = (jl_code_info_t*)jl_atomic_load_relaxed(&uninferred->inferred);
1013973
assert(src);
@@ -1018,10 +978,16 @@ void jl_generate_fptr_for_unspecialized_impl(jl_code_instance_t *unspec)
1018978
if (!jl_is_compiled_codeinst(unspec)) {
1019979
assert(jl_is_code_info(src));
1020980
++UnspecFPtrCount;
981+
jl_svec_t *edges = (jl_svec_t*)src->edges;
982+
if (jl_is_svec(edges)) {
983+
jl_atomic_store_release(&unspec->edges, edges); // n.b. this assumes the field was always empty svec(), which is not entirely true
984+
jl_gc_wb(unspec, edges);
985+
}
1021986
jl_debuginfo_t *debuginfo = src->debuginfo;
1022987
jl_atomic_store_release(&unspec->debuginfo, debuginfo); // n.b. this assumes the field was previously NULL, which is not entirely true
1023988
jl_gc_wb(unspec, debuginfo);
1024-
_jl_compile_codeinst(unspec, src);
989+
jl_emit_codeinst_to_jit(unspec, src);
990+
jl_compile_codeinst_now(unspec);
1025991
}
1026992
JL_UNLOCK(&jitlock); // Might GC
1027993
}

src/julia_internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ JL_DLLEXPORT void jl_engine_fulfill(jl_code_instance_t *ci, jl_code_info_t *src)
673673
void jl_engine_sweep(jl_ptls_t *gc_all_tls_states) JL_NOTSAFEPOINT;
674674
int jl_engine_hasreserved(jl_method_instance_t *m, jl_value_t *owner) JL_NOTSAFEPOINT;
675675

676-
JL_DLLEXPORT jl_code_instance_t *jl_type_infer(jl_method_instance_t *li, size_t world, uint8_t source_mode);
676+
JL_DLLEXPORT jl_code_instance_t *jl_type_infer(jl_method_instance_t *li JL_PROPAGATES_ROOT, size_t world, uint8_t source_mode);
677677
JL_DLLEXPORT jl_code_info_t *jl_gdbcodetyped1(jl_method_instance_t *mi, size_t world);
678678
JL_DLLEXPORT jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *meth JL_PROPAGATES_ROOT, size_t world);
679679
JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred(
@@ -1210,7 +1210,6 @@ jl_method_instance_t *jl_get_specialized(jl_method_t *m, jl_value_t *types, jl_s
12101210
JL_DLLEXPORT jl_value_t *jl_rettype_inferred(jl_value_t *owner, jl_method_instance_t *li JL_PROPAGATES_ROOT, size_t min_world, size_t max_world);
12111211
JL_DLLEXPORT jl_value_t *jl_rettype_inferred_native(jl_method_instance_t *mi, size_t min_world, size_t max_world) JL_NOTSAFEPOINT;
12121212
JL_DLLEXPORT jl_code_instance_t *jl_method_compiled(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) JL_NOTSAFEPOINT;
1213-
JL_DLLEXPORT jl_code_instance_t *jl_method_inferred_with_abi(jl_method_instance_t *mi JL_PROPAGATES_ROOT, size_t world) JL_NOTSAFEPOINT;
12141213
JL_DLLEXPORT jl_value_t *jl_methtable_lookup(jl_methtable_t *mt JL_PROPAGATES_ROOT, jl_value_t *type, size_t world);
12151214
JL_DLLEXPORT jl_method_instance_t *jl_specializations_get_linfo(
12161215
jl_method_t *m JL_PROPAGATES_ROOT, jl_value_t *type, jl_svec_t *sparams);

src/opaque_closure.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,10 @@ static jl_opaque_closure_t *new_opaque_closure(jl_tupletype_t *argt, jl_value_t
118118

119119
// OC wrapper methods are not world dependent and have no edges or other info
120120
ci = jl_get_method_inferred(mi_generic, selected_rt, 1, ~(size_t)0, NULL, NULL);
121-
if (!jl_atomic_load_acquire(&ci->invoke))
122-
jl_compile_codeinst(ci); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible since it cannot have source)
121+
if (!jl_atomic_load_acquire(&ci->invoke)) {
122+
jl_emit_codeinst_to_jit(ci, NULL); // confusing this actually calls jl_emit_oc_wrapper and never actually compiles ci (which would be impossible since it cannot have source)
123+
jl_compile_codeinst(ci);
124+
}
123125
specptr = jl_atomic_load_relaxed(&ci->specptr.fptr);
124126
}
125127
jl_opaque_closure_t *oc = (jl_opaque_closure_t*)jl_gc_alloc(ct->ptls, sizeof(jl_opaque_closure_t), oc_type);

0 commit comments

Comments
 (0)