@@ -147,16 +147,46 @@ struct InliningState{Interp<:AbstractInterpreter}
147
147
edges:: Vector{Any}
148
148
world:: UInt
149
149
interp:: Interp
150
+ opt_cache:: IdDict{MethodInstance,CodeInstance}
150
151
end
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)
153
155
end
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)
156
182
end
157
183
158
184
# 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
160
190
161
191
mutable struct OptimizationResult
162
192
ir:: IRCode
@@ -183,13 +213,15 @@ mutable struct OptimizationState{Interp<:AbstractInterpreter}
183
213
bb_vartables:: Vector{Union{Nothing,VarTable}}
184
214
insert_coverage:: Bool
185
215
end
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)
188
219
return OptimizationState (sv. linfo, sv. src, nothing , sv. stmt_info, sv. mod,
189
220
sv. sptypes, sv. slottypes, inlining, sv. cfg,
190
221
sv. unreachable, sv. bb_vartables, sv. insert_coverage)
191
222
end
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} ())
193
225
# prepare src for running optimization passes if it isn't already
194
226
nssavalues = src. ssavaluetypes
195
227
if nssavalues isa Int
@@ -209,7 +241,7 @@ function OptimizationState(mi::MethodInstance, src::CodeInfo, interp::AbstractIn
209
241
mod = isa (def, Method) ? def. module : def
210
242
# Allow using the global MI cache, but don't track edges.
211
243
# This method is mostly used for unit testing the optimizer
212
- inlining = InliningState (interp)
244
+ inlining = InliningState (interp, opt_cache )
213
245
cfg = compute_basic_blocks (src. code)
214
246
unreachable = BitSet ()
215
247
bb_vartables = Union{VarTable,Nothing}[]
0 commit comments