@@ -147,16 +147,46 @@ struct InliningState{Interp<:AbstractInterpreter}
147147 edges:: Vector{Any}
148148 world:: UInt
149149 interp:: Interp
150+ opt_cache:: IdDict{MethodInstance,CodeInstance}
150151end
151- function InliningState (sv:: InferenceState , interp:: AbstractInterpreter )
152- return InliningState (sv. edges, frame_world (sv), interp)
152+ function InliningState (sv:: InferenceState , interp:: AbstractInterpreter ,
153+ opt_cache:: IdDict{MethodInstance,CodeInstance} = IdDict {MethodInstance,CodeInstance} ())
154+ return InliningState (sv. edges, frame_world (sv), interp, opt_cache)
153155end
154- function InliningState (interp:: AbstractInterpreter )
155- return InliningState (Any[], get_inference_world (interp), interp)
156+ function InliningState (interp:: AbstractInterpreter ,
157+ opt_cache:: IdDict{MethodInstance,CodeInstance} = IdDict {MethodInstance,CodeInstance} ())
158+ return InliningState (Any[], get_inference_world (interp), interp, opt_cache)
159+ end
160+
161+ struct OptimizerCache{CodeCache}
162+ wvc:: WorldView{CodeCache}
163+ owner
164+ opt_cache:: IdDict{MethodInstance,CodeInstance}
165+ function OptimizerCache (
166+ wvc:: WorldView{CodeCache} ,
167+ @nospecialize (owner),
168+ opt_cache:: IdDict{MethodInstance,CodeInstance} ) where CodeCache
169+ new {CodeCache} (wvc, owner, opt_cache)
170+ end
171+ end
172+ function get ((; wvc, owner, opt_cache):: OptimizerCache , mi:: MethodInstance , default)
173+ if haskey (opt_cache, mi)
174+ codeinst = opt_cache[mi]
175+ @assert codeinst. min_world ≤ wvc. worlds. min_world &&
176+ wvc. worlds. max_world ≤ codeinst. max_world &&
177+ codeinst. owner === owner
178+ @assert isdefined (codeinst, :inferred ) && codeinst. inferred === nothing
179+ return codeinst
180+ end
181+ return get (wvc, mi, default)
156182end
157183
158184# get `code_cache(::AbstractInterpreter)` from `state::InliningState`
159- code_cache (state:: InliningState ) = WorldView (code_cache (state. interp), state. world)
185+ function code_cache (state:: InliningState )
186+ cache = WorldView (code_cache (state. interp), state. world)
187+ owner = cache_owner (state. interp)
188+ return OptimizerCache (cache, owner, state. opt_cache)
189+ end
160190
161191mutable struct OptimizationResult
162192 ir:: IRCode
@@ -183,13 +213,15 @@ mutable struct OptimizationState{Interp<:AbstractInterpreter}
183213 bb_vartables:: Vector{Union{Nothing,VarTable}}
184214 insert_coverage:: Bool
185215end
186- function OptimizationState (sv:: InferenceState , interp:: AbstractInterpreter )
187- inlining = InliningState (sv, interp)
216+ function OptimizationState (sv:: InferenceState , interp:: AbstractInterpreter ,
217+ opt_cache:: IdDict{MethodInstance,CodeInstance} = IdDict {MethodInstance,CodeInstance} ())
218+ inlining = InliningState (sv, interp, opt_cache)
188219 return OptimizationState (sv. linfo, sv. src, nothing , sv. stmt_info, sv. mod,
189220 sv. sptypes, sv. slottypes, inlining, sv. cfg,
190221 sv. unreachable, sv. bb_vartables, sv. insert_coverage)
191222end
192- function OptimizationState (mi:: MethodInstance , src:: CodeInfo , interp:: AbstractInterpreter )
223+ function OptimizationState (mi:: MethodInstance , src:: CodeInfo , interp:: AbstractInterpreter ,
224+ opt_cache:: IdDict{MethodInstance,CodeInstance} = IdDict {MethodInstance,CodeInstance} ())
193225 # prepare src for running optimization passes if it isn't already
194226 nssavalues = src. ssavaluetypes
195227 if nssavalues isa Int
@@ -209,7 +241,7 @@ function OptimizationState(mi::MethodInstance, src::CodeInfo, interp::AbstractIn
209241 mod = isa (def, Method) ? def. module : def
210242 # Allow using the global MI cache, but don't track edges.
211243 # This method is mostly used for unit testing the optimizer
212- inlining = InliningState (interp)
244+ inlining = InliningState (interp, opt_cache )
213245 cfg = compute_basic_blocks (src. code)
214246 unreachable = BitSet ()
215247 bb_vartables = Union{VarTable,Nothing}[]
0 commit comments