diff --git a/base/boot.jl b/base/boot.jl index 734738b48aa99..bfdc86b95c1f2 100644 --- a/base/boot.jl +++ b/base/boot.jl @@ -503,12 +503,12 @@ end function CodeInstance( mi::MethodInstance, owner, @nospecialize(rettype), @nospecialize(exctype), @nospecialize(inferred_const), @nospecialize(inferred), const_flags::Int32, min_world::UInt, max_world::UInt, - ipo_effects::UInt32, effects::UInt32, @nospecialize(analysis_results), + effects::UInt32, @nospecialize(analysis_results), relocatability::UInt8, edges::Union{DebugInfo,Nothing}) return ccall(:jl_new_codeinst, Ref{CodeInstance}, - (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, UInt32, Any, UInt8, Any), + (Any, Any, Any, Any, Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any), mi, owner, rettype, exctype, inferred_const, inferred, const_flags, min_world, max_world, - ipo_effects, effects, analysis_results, relocatability, edges) + effects, analysis_results, relocatability, edges) end GlobalRef(m::Module, s::Symbol) = ccall(:jl_module_globalref, Ref{GlobalRef}, (Any, Any), m, s) Module(name::Symbol=:anonymous, std_imports::Bool=true, default_names::Bool=true) = ccall(:jl_f_new_module, Ref{Module}, (Any, Bool, Bool), name, std_imports, default_names) diff --git a/base/compiler/optimize.jl b/base/compiler/optimize.jl index 2f5459646dabc..e27cd06bcb625 100644 --- a/base/compiler/optimize.jl +++ b/base/compiler/optimize.jl @@ -622,7 +622,7 @@ function ((; code_cache)::GetNativeEscapeCache)(mi::MethodInstance) if argescapes !== nothing return argescapes end - effects = decode_effects(codeinst.ipo_purity_bits) + effects = decode_effects(codeinst.purity_bits) if is_effect_free(effects) && is_inaccessiblememonly(effects) # We might not have run EA on simple frames without any escapes (e.g. when optimization # is skipped when result is constant-folded by abstract interpretation). If those diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index a77a67ab262de..6ba2214e5ff65 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -857,7 +857,7 @@ function resolve_todo(mi::MethodInstance, result::Union{Nothing,InferenceResult, (; src, effects) = inferred_result elseif inferred_result isa CodeInstance src = @atomic :monotonic inferred_result.inferred - effects = decode_effects(inferred_result.ipo_purity_bits) + effects = decode_effects(inferred_result.purity_bits) else src = nothing effects = Effects() @@ -898,7 +898,7 @@ function resolve_todo(mi::MethodInstance, @nospecialize(info::CallInfo), flag::U (; src, effects) = cached_result elseif cached_result isa CodeInstance src = @atomic :monotonic cached_result.inferred - effects = decode_effects(cached_result.ipo_purity_bits) + effects = decode_effects(cached_result.purity_bits) else src = nothing effects = Effects() @@ -1325,7 +1325,7 @@ function info_effects(@nospecialize(result), match::MethodMatch, state::Inlining if isa(mi, MethodInstance) code = get(code_cache(state), mi, nothing) if code isa CodeInstance - return decode_effects(code.ipo_purity_bits) + return decode_effects(code.purity_bits) end end return Effects() diff --git a/base/compiler/ssair/irinterp.jl b/base/compiler/ssair/irinterp.jl index 83881354e494e..19dbfe0ec00cb 100644 --- a/base/compiler/ssair/irinterp.jl +++ b/base/compiler/ssair/irinterp.jl @@ -7,7 +7,7 @@ end function concrete_eval_invoke(interp::AbstractInterpreter, ci::CodeInstance, argtypes::Vector{Any}, parent::IRInterpretationState) world = frame_world(parent) - effects = decode_effects(ci.ipo_purity_bits) + effects = decode_effects(ci.purity_bits) if (is_foldable(effects) && is_all_const_arg(argtypes, #=start=#1) && (is_nonoverlayed(interp) || is_nonoverlayed(effects))) args = collect_const_args(argtypes, #=start=#1) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index d61cb20dc2c88..009ace4334cd8 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -260,11 +260,10 @@ function finish!(interp::AbstractInterpreter, caller::InferenceState; if !@isdefined edges edges = DebugInfo(result.linfo) end - ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, UInt32, Any, UInt8, Any), + ccall(:jl_update_codeinst, Cvoid, (Any, Any, Int32, UInt, UInt, UInt32, Any, UInt8, Any), ci, inferred_result, const_flag, first(result.valid_worlds), last(result.valid_worlds), - # TODO: Actually do something with non-IPO effects - encode_effects(result.ipo_effects), encode_effects(result.ipo_effects), result.analysis_results, + encode_effects(result.ipo_effects), result.analysis_results, relocatability, edges) end return nothing @@ -384,8 +383,7 @@ function CodeInstance(interp::AbstractInterpreter, result::InferenceResult) return CodeInstance(result.linfo, owner, widenconst(result_type), widenconst(result.exc_result), rettype_const, nothing, const_flags, first(result.valid_worlds), last(result.valid_worlds), - # TODO: Actually do something with non-IPO effects - encode_effects(result.ipo_effects), encode_effects(result.ipo_effects), result.analysis_results, + encode_effects(result.ipo_effects), result.analysis_results, relocatability, nothing) end @@ -854,7 +852,7 @@ function resolve_call_cycle!(interp::AbstractInterpreter, mi::MethodInstance, pa return false end -ipo_effects(code::CodeInstance) = decode_effects(code.ipo_purity_bits) +ipo_effects(code::CodeInstance) = decode_effects(code.purity_bits) struct EdgeCallResult rt @@ -1006,7 +1004,7 @@ function codeinstance_for_const_with_code(interp::AbstractInterpreter, code::Cod src = codeinfo_for_const(interp, code.def, code.rettype_const) return CodeInstance(code.def, cache_owner(interp), code.rettype, code.exctype, code.rettype_const, src, Int32(0x3), code.min_world, code.max_world, - code.ipo_purity_bits, code.purity_bits, code.analysis_results, + code.purity_bits, code.analysis_results, code.relocatability, src.debuginfo) end @@ -1168,7 +1166,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance, source_mod src isa CodeInfo || return nothing return CodeInstance(mi, cache_owner(interp), Any, Any, nothing, src, Int32(0), get_inference_world(interp), get_inference_world(interp), - UInt32(0), UInt32(0), nothing, UInt8(0), src.debuginfo) + UInt32(0), nothing, UInt8(0), src.debuginfo) end end lock_mi_inference(interp, mi) diff --git a/src/codegen.cpp b/src/codegen.cpp index 31f40470962ee..5df639db3b5c3 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9875,7 +9875,7 @@ jl_llvm_functions_t jl_emit_codeinst( else if (jl_is_method(def) && // don't delete toplevel code def->source != NULL && // don't delete code from optimized opaque closures that can't be reconstructed inferred != jl_nothing && // and there is something to delete (test this before calling jl_ir_inlining_cost) - !effects_foldable(codeinst->ipo_purity_bits) && // don't delete code we may want for irinterp + !effects_foldable(jl_atomic_load_relaxed(&codeinst->purity_bits)) && // don't delete code we may want for irinterp ((jl_ir_inlining_cost(inferred) == UINT16_MAX) || // don't delete inlineable code jl_atomic_load_relaxed(&codeinst->invoke) == jl_fptr_const_return_addr) && // unless it is constant !(params.imaging_mode || jl_options.incremental)) { // don't delete code when generating a precompile file diff --git a/src/gf.c b/src/gf.c index a80708f54cf9a..e698bd1e7ac45 100644 --- a/src/gf.c +++ b/src/gf.c @@ -320,7 +320,7 @@ jl_datatype_t *jl_mk_builtin_func(jl_datatype_t *dt, const char *name, jl_fptr_a jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, jl_nothing, - 0, 1, ~(size_t)0, 0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); jl_mi_cache_insert(mi, codeinst); jl_atomic_store_relaxed(&codeinst->specptr.fptr1, fptr); jl_atomic_store_relaxed(&codeinst->invoke, jl_fptr_args); @@ -503,7 +503,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_get_method_inferred( } codeinst = jl_new_codeinst( mi, owner, rettype, (jl_value_t*)jl_any_type, NULL, NULL, - 0, min_world, max_world, 0, 0, jl_nothing, 0, edges); + 0, min_world, max_world, 0, jl_nothing, 0, edges); jl_mi_cache_insert(mi, codeinst); return codeinst; } @@ -525,7 +525,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_value_t *rettype, jl_value_t *exctype, jl_value_t *inferred_const, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, - uint32_t ipo_effects, uint32_t effects, jl_value_t *analysis_results, + uint32_t effects, jl_value_t *analysis_results, uint8_t relocatability, jl_debuginfo_t *edges /* , int absolute_max*/) { @@ -553,7 +553,6 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_atomic_store_relaxed(&codeinst->specsigflags, 0); jl_atomic_store_relaxed(&codeinst->precompile, 0); jl_atomic_store_relaxed(&codeinst->next, NULL); - codeinst->ipo_purity_bits = ipo_effects; jl_atomic_store_relaxed(&codeinst->purity_bits, effects); codeinst->analysis_results = analysis_results; codeinst->relocatability = relocatability; @@ -563,7 +562,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( JL_DLLEXPORT void jl_update_codeinst( jl_code_instance_t *codeinst, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, - uint32_t ipo_effects, uint32_t effects, jl_value_t *analysis_results, + uint32_t effects, jl_value_t *analysis_results, uint8_t relocatability, jl_debuginfo_t *edges /* , int absolute_max*/) { jl_atomic_store_relaxed(&codeinst->min_world, min_world); @@ -571,7 +570,6 @@ JL_DLLEXPORT void jl_update_codeinst( codeinst->relocatability = relocatability; codeinst->analysis_results = analysis_results; jl_gc_wb(codeinst, analysis_results); - codeinst->ipo_purity_bits = ipo_effects; jl_atomic_store_relaxed(&codeinst->purity_bits, effects); jl_atomic_store_relaxed(&codeinst->debuginfo, edges); jl_gc_wb(codeinst, edges); @@ -2584,7 +2582,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t if (unspec && (unspec_invoke = jl_atomic_load_acquire(&unspec->invoke))) { jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); void *unspec_fptr = jl_atomic_load_relaxed(&unspec->specptr.fptr); if (unspec_fptr) { // wait until invoke and specsigflags are properly set @@ -2611,7 +2609,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t if (!jl_code_requires_compiler(src, 0)) { jl_code_instance_t *codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); jl_atomic_store_release(&codeinst->invoke, jl_fptr_interpret_call); jl_mi_cache_insert(mi, codeinst); record_precompile_statement(mi); @@ -2686,7 +2684,7 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t } codeinst = jl_new_codeinst(mi, jl_nothing, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, NULL, NULL, - 0, 1, ~(size_t)0, 0, 0, jl_nothing, 0, NULL); + 0, 1, ~(size_t)0, 0, jl_nothing, 0, NULL); void *unspec_fptr = jl_atomic_load_relaxed(&ucache->specptr.fptr); if (unspec_fptr) { // wait until invoke and specsigflags are properly set diff --git a/src/jltypes.c b/src/jltypes.c index 2402838ec09a5..20fe50f068ffc 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -3469,7 +3469,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_code_instance_type = jl_new_datatype(jl_symbol("CodeInstance"), core, jl_any_type, jl_emptysvec, - jl_perm_symsvec(18, + jl_perm_symsvec(17, "def", "owner", "next", @@ -3481,11 +3481,11 @@ void jl_init_types(void) JL_GC_DISABLED "inferred", "debuginfo", // TODO: rename to edges? //"absolute_max", - "ipo_purity_bits", "purity_bits", + "purity_bits", "analysis_results", "specsigflags", "precompile", "relocatability", "invoke", "specptr"), // function object decls - jl_svec(18, + jl_svec(17, jl_method_instance_type, jl_any_type, jl_any_type, @@ -3497,7 +3497,7 @@ void jl_init_types(void) JL_GC_DISABLED jl_any_type, jl_debuginfo_type, //jl_bool_type, - jl_uint32_type, jl_uint32_type, + jl_uint32_type, jl_any_type, jl_bool_type, jl_bool_type, @@ -3506,10 +3506,10 @@ void jl_init_types(void) JL_GC_DISABLED jl_emptysvec, 0, 1, 1); jl_svecset(jl_code_instance_type->types, 2, jl_code_instance_type); - const static uint32_t code_instance_constfields[1] = { 0b000001010011100011 }; // Set fields 1, 2, 6-8, 11, 13 as const - const static uint32_t code_instance_atomicfields[1] = { 0b110110101100011100 }; // Set fields 3-5, 9, 10, 12, 14-15, 17-18 as atomic + const static uint32_t code_instance_constfields[1] = { 0b00000100011100011 }; // Set fields 1, 2, 6-8, 12 as const + const static uint32_t code_instance_atomicfields[1] = { 0b11011011100011100 }; // Set fields 3-5, 9, 10, 11, 13-14, 16-17 as atomic // Fields 4-5 are only operated on by construction and deserialization, so are effectively const at runtime - // Fields ipo_purity_bits and analysis_results are not currently threadsafe or reliable, as they get mutated after optimization, but are not declared atomic + // Fields purity_bits and analysis_results are not currently threadsafe or reliable, as they get mutated after optimization, but are not declared atomic // and there is no way to tell (during inference) if their value is finalized yet (to wait for them to be narrowed if applicable) jl_code_instance_type->name->constfields = code_instance_constfields; jl_code_instance_type->name->atomicfields = code_instance_atomicfields; @@ -3651,8 +3651,8 @@ void jl_init_types(void) JL_GC_DISABLED jl_svecset(jl_method_type->types, 13, jl_method_instance_type); //jl_svecset(jl_debuginfo_type->types, 0, jl_method_instance_type); // union(jl_method_instance_type, jl_method_type, jl_symbol_type) jl_svecset(jl_method_instance_type->types, 4, jl_code_instance_type); + jl_svecset(jl_code_instance_type->types, 15, jl_voidpointer_type); jl_svecset(jl_code_instance_type->types, 16, jl_voidpointer_type); - jl_svecset(jl_code_instance_type->types, 17, jl_voidpointer_type); jl_svecset(jl_binding_type->types, 1, jl_globalref_type); jl_svecset(jl_binding_type->types, 2, jl_binding_type); diff --git a/src/julia.h b/src/julia.h index 4534d00caa888..08047e79e5e47 100644 --- a/src/julia.h +++ b/src/julia.h @@ -457,15 +457,6 @@ typedef struct _jl_code_instance_t { // purity results // see also encode_effects() and decode_effects() in `base/compiler/effects.jl`, - uint32_t ipo_purity_bits; - // ipo_purity_flags: - // uint8_t ipo_consistent : 2; - // uint8_t ipo_effect_free : 2; - // uint8_t ipo_nothrow : 2; - // uint8_t ipo_terminates : 2; - // uint8_t ipo_nonoverlayed : 1; - // uint8_t ipo_notaskstate : 2; - // uint8_t ipo_inaccessiblememonly : 2; _Atomic(uint32_t) purity_bits; // purity_flags: // uint8_t consistent : 2; diff --git a/src/julia_internal.h b/src/julia_internal.h index 6f71b6018606f..7d29459304878 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -665,7 +665,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst( jl_value_t *rettype, jl_value_t *exctype, jl_value_t *inferred_const, jl_value_t *inferred, int32_t const_flags, size_t min_world, size_t max_world, - uint32_t ipo_effects, uint32_t effects, jl_value_t *analysis_results, + uint32_t effects, jl_value_t *analysis_results, uint8_t relocatability, jl_debuginfo_t *edges /* , int absolute_max*/); JL_DLLEXPORT const char *jl_debuginfo_file(jl_debuginfo_t *debuginfo) JL_NOTSAFEPOINT; diff --git a/src/opaque_closure.c b/src/opaque_closure.c index 01c14065c8217..394001665db3b 100644 --- a/src/opaque_closure.c +++ b/src/opaque_closure.c @@ -159,7 +159,7 @@ JL_DLLEXPORT jl_opaque_closure_t *jl_new_opaque_closure_from_code_info(jl_tuplet sigtype = jl_argtype_with_function_type(argslotty, (jl_value_t*)argt); jl_method_instance_t *mi = jl_specializations_get_linfo((jl_method_t*)root, sigtype, jl_emptysvec); inst = jl_new_codeinst(mi, jl_nothing, rt_ub, (jl_value_t*)jl_any_type, NULL, (jl_value_t*)ci, - 0, world, world, 0, 0, jl_nothing, 0, ci->debuginfo); + 0, world, world, 0, jl_nothing, 0, ci->debuginfo); jl_mi_cache_insert(mi, inst); } diff --git a/src/toplevel.c b/src/toplevel.c index 1899c9e18db30..dfe108dea1859 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -604,7 +604,7 @@ JL_DLLEXPORT jl_code_instance_t *jl_new_codeinst_for_uninferred(jl_method_instan jl_code_instance_t *ci = jl_new_codeinst(mi, (jl_value_t*)jl_uninferred_sym, (jl_value_t*)jl_any_type, (jl_value_t*)jl_any_type, jl_nothing, (jl_value_t*)src, 0, src->min_world, src->max_world, - 0, 0, NULL, 1, NULL); + 0, NULL, 1, NULL); return ci; } diff --git a/test/core.jl b/test/core.jl index 7066aff953dab..24b444f62ad53 100644 --- a/test/core.jl +++ b/test/core.jl @@ -14,7 +14,7 @@ include("testenv.jl") # sanity tests that our built-in types are marked correctly for const fields for (T, c) in ( (Core.CodeInfo, []), - (Core.CodeInstance, [:def, :owner, :rettype, :exctype, :rettype_const, :ipo_purity_bits, :analysis_results]), + (Core.CodeInstance, [:def, :owner, :rettype, :exctype, :rettype_const, :purity_bits, :analysis_results]), (Core.Method, [#=:name, :module, :file, :line, :primary_world, :sig, :slot_syms, :external_mt, :nargs, :called, :nospecialize, :nkw, :isva, :is_for_opaque_closure, :constprop=#]), (Core.MethodInstance, [#=:def, :specTypes, :sparam_vals=#]), (Core.MethodTable, [:module]), diff --git a/test/precompile.jl b/test/precompile.jl index e164c2917d06f..9862899ce7465 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -1699,7 +1699,7 @@ precompile_test_harness("issue #46296") do load_path mi = first(Base.specializations(first(methods(identity)))) ci = Core.CodeInstance(mi, nothing, Any, Any, nothing, nothing, zero(Int32), typemin(UInt), - typemax(UInt), zero(UInt32), zero(UInt32), nothing, 0x00, + typemax(UInt), zero(UInt32), nothing, 0x00, Core.DebugInfo(mi)) __init__() = @assert ci isa Core.CodeInstance