1+ function get_mi (ci:: Core.CodeInstance )
2+ @static isdefined (CC, :get_ci_mi ) ? CC. get_ci_mi (ci) : ci. def
3+ end
4+ get_mi (mi:: Core.MethodInstance ) = mi
15
26"""
37 replace_captures(oc::Toc, new_captures) where {Toc<:OpaqueClosure}
@@ -218,6 +222,55 @@ function opaque_closure(
218222 ):: Core.OpaqueClosure{sig,ret_type}
219223end
220224
225+ function optimized_opaque_closure (rtype, ir:: IRCode , env... ; kwargs... )
226+ oc = opaque_closure (rtype, ir, env... ; kwargs... )
227+ world = UInt (oc. world)
228+ set_world_bounds_for_optimization! (oc)
229+ optimized_oc = optimize_opaque_closure (oc, rtype, env... ; kwargs... )
230+ return optimized_oc
231+ end
232+
233+ function optimize_opaque_closure (oc:: Core.OpaqueClosure , rtype, env... ; kwargs... )
234+ method = oc. source
235+ ci = method. specializations. cache
236+ world = UInt (oc. world)
237+ ir = reinfer_and_inline (ci, world)
238+ ir === nothing && return oc # nothing to optimize
239+ return opaque_closure (rtype, ir, env... ; kwargs... )
240+ end
241+
242+ # Allows optimization to make assumptions about binding access,
243+ # enabling inlining and other optimizations.
244+ function set_world_bounds_for_optimization! (oc:: Core.OpaqueClosure )
245+ ci = oc. source. specializations. cache
246+ ci. inferred === nothing && return nothing
247+ ci. inferred. min_world = oc. world
248+ return ci. inferred. max_world = oc. world
249+ end
250+
251+ function reinfer_and_inline (ci:: Core.CodeInstance , world:: UInt )
252+ interp = CC. NativeInterpreter (world)
253+ mi = get_mi (ci)
254+ argtypes = collect (Any, mi. specTypes. parameters)
255+ irsv = CC. IRInterpretationState (interp, ci, mi, argtypes, world)
256+ irsv === nothing && return nothing
257+ for stmt in irsv. ir. stmts
258+ inst = stmt[:inst ]
259+ if Meta. isexpr (inst, :loopinfo ) ||
260+ Meta. isexpr (inst, :pop_exception ) ||
261+ isa (inst, CC. GotoIfNot) ||
262+ isa (inst, CC. GotoNode) ||
263+ Meta. isexpr (inst, :copyast )
264+ continue
265+ end
266+ stmt[:flag ] |= CC. IR_FLAG_REFINED
267+ end
268+ CC. ir_abstract_constant_propagation (interp, irsv)
269+ state = CC. InliningState (interp)
270+ ir = CC. ssa_inlining_pass! (irsv. ir, state, CC. propagate_inbounds (irsv))
271+ return ir
272+ end
273+
221274"""
222275 misty_closure(
223276 ret_type::Type,
@@ -239,3 +292,15 @@ function misty_closure(
239292)
240293 return MistyClosure (opaque_closure (ret_type, ir, env... ; isva, do_compile), Ref (ir))
241294end
295+
296+ function optimized_misty_closure (
297+ ret_type:: Type ,
298+ ir:: IRCode ,
299+ @nospecialize env... ;
300+ isva:: Bool = false ,
301+ do_compile:: Bool = true ,
302+ )
303+ return MistyClosure (
304+ optimized_opaque_closure (ret_type, ir, env... ; isva, do_compile), Ref (ir)
305+ )
306+ end
0 commit comments