Skip to content

Commit d0e03c7

Browse files
committed
Refactor CodeInfo/CodeInstance separation and interfaces
The `CodeInfo` type is one of the oldest types in the system and has grown a bit of cruft. In particular, the `rettype`, `parent`, `edges`, `min_world`, `max_world` fields are not used for the original purpose of representing code, but for one or more of (in decreasing order of badness): 1. Smuggling extra results from inference into the compiler 2. Sumggling extra arguments into OpaqueClosure constructors 3. Passing extra information from generated functions to inference The first of these points in particular causes a fair bit of mixup between caching concerns and compiler concerns and results in external abstract interpreters maintainging their own dummy CodeInfos, just to comply with the interface. Originally, I just wanted to clean up that bit, but it didn't really make sense as a standalone piece, so this PR is more comprehensive. In particular, this PR: 1. Removes the `parent` and `rettype` fields of `CodeInfo`. They are largely vestigal and code accessing these is probably doing the wrong thing. They should instead be looking at either the CodeInstance or remembering the query that was asked of the cache in the first place. 2. Makes `edges`, `min_world` and `max_world` used for generated functions only. All other uses were replaced by appropriate queries on the CodeInstance. In particular, inference no longer sets these. In the future we may want to consider removing these also and having generated functions return some other object, but that is a topic to revisit once the broader compiler plugins landscape is more clear. 3. Makes the external type inference interface return `CodeInstance` rather than `CodeInfo`. This results in a lot of cleanup, because many functions had multiple code paths, some for CodeInstance and others for fallback to inference/CodeInfo. This is all cleaned up now. If you don't have a CodeInstance, you can ask inference for one. This CodeInstance may or may not be in the cache, but you can look at its types, compile it, etc. 4. Moves the main inference entrypoint out of the codegen library. There is still a little bit of entangelement, but this makes codegen much more of an independent system that you give a CodeInstance and it just fills in the invoke pointer for. The overall theme here is decoupling. Over time, various parties have wanted to use the julia compiler with custom IR datastructure, backend code generators, caches, etc. This doesn't quite get us all the way there, but makes inference and codegen much more independent with a clear IR-format-independent interface (CodeInstance).
1 parent a26bd7f commit d0e03c7

35 files changed

+489
-549
lines changed

base/compiler/inferencestate.jl

+11-3
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ mutable struct InferenceState
315315
dont_work_on_me = false
316316
parent = nothing
317317

318-
valid_worlds = WorldRange(src.min_world, src.max_world == typemax(UInt) ? get_world_counter() : src.max_world)
318+
valid_worlds = WorldRange(1, get_world_counter())
319319
bestguess = Bottom
320320
exc_bestguess = Bottom
321321
ipo_effects = EFFECTS_TOTAL
@@ -335,13 +335,21 @@ mutable struct InferenceState
335335
InferenceParams(interp).unoptimize_throw_blocks && mark_throw_blocks!(src, handler_at)
336336
!iszero(cache_mode & CACHE_MODE_LOCAL) && push!(get_inference_cache(interp), result)
337337

338-
return new(
338+
this = new(
339339
linfo, world, mod, sptypes, slottypes, src, cfg, method_info,
340340
currbb, currpc, ip, handlers, handler_at, ssavalue_uses, bb_vartables, ssavaluetypes, stmt_edges, stmt_info,
341341
pclimitations, limitations, cycle_backedges, callers_in_cycle, dont_work_on_me, parent,
342342
result, unreachable, valid_worlds, bestguess, exc_bestguess, ipo_effects,
343343
restrict_abstract_call_sites, cache_mode, insert_coverage,
344344
interp)
345+
346+
# Apply generated function restrictions
347+
if src.min_world != 1 || src.max_world != typemax(UInt)
348+
# From generated functions
349+
this.valid_worlds = WorldRange(src.min_world, src.max_world)
350+
end
351+
352+
return this
345353
end
346354
end
347355

@@ -796,7 +804,7 @@ function IRInterpretationState(interp::AbstractInterpreter,
796804
method_info = MethodInfo(src)
797805
ir = inflate_ir(src, mi)
798806
return IRInterpretationState(interp, method_info, ir, mi, argtypes, world,
799-
src.min_world, src.max_world)
807+
code.min_world, code.max_world)
800808
end
801809

802810
# AbsIntState

base/compiler/optimize.jl

+2-7
Original file line numberDiff line numberDiff line change
@@ -107,19 +107,17 @@ is_declared_noinline(@nospecialize src::MaybeCompressed) =
107107
# OptimizationState #
108108
#####################
109109

110-
is_source_inferred(@nospecialize src::MaybeCompressed) =
111-
ccall(:jl_ir_flag_inferred, Bool, (Any,), src)
112-
113110
function inlining_policy(interp::AbstractInterpreter,
114111
@nospecialize(src), @nospecialize(info::CallInfo), stmt_flag::UInt32)
115112
if isa(src, MaybeCompressed)
116-
is_source_inferred(src) || return nothing
117113
src_inlineable = is_stmt_inline(stmt_flag) || is_inlineable(src)
118114
return src_inlineable ? src : nothing
119115
elseif isa(src, IRCode)
120116
return src
121117
elseif isa(src, SemiConcreteResult)
122118
return src
119+
elseif isa(src, CodeInstance)
120+
return inlining_policy(interp, src.inferred, info, stmt_flag)
123121
end
124122
return nothing
125123
end
@@ -222,7 +220,6 @@ end
222220
function ir_to_codeinf!(src::CodeInfo, ir::IRCode)
223221
replace_code_newstyle!(src, ir)
224222
widen_all_consts!(src)
225-
src.inferred = true
226223
return src
227224
end
228225

@@ -240,8 +237,6 @@ function widen_all_consts!(src::CodeInfo)
240237
end
241238
end
242239

243-
src.rettype = widenconst(src.rettype)
244-
245240
return src
246241
end
247242

base/compiler/ssair/legacy.jl

-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ Mainly used for testing or interactive use.
5555
inflate_ir(ci::CodeInfo, linfo::MethodInstance) = inflate_ir!(copy(ci), linfo)
5656
inflate_ir(ci::CodeInfo, sptypes::Vector{VarState}, argtypes::Vector{Any}) = inflate_ir!(copy(ci), sptypes, argtypes)
5757
function inflate_ir(ci::CodeInfo)
58-
parent = ci.parent
59-
isa(parent, MethodInstance) && return inflate_ir(ci, parent)
6058
# XXX the length of `ci.slotflags` may be different from the actual number of call
6159
# arguments, but we really don't know that information in this case
6260
argtypes = Any[ Any for i = 1:length(ci.slotflags) ]

0 commit comments

Comments
 (0)