@@ -116,11 +116,14 @@ function inline_cost_clamp(x::Int)
116116 return convert (InlineCostType, x)
117117end
118118
119+ const SRC_FLAG_DECLARED_INLINE = 0x1
120+ const SRC_FLAG_DECLARED_NOINLINE = 0x2
121+
119122is_declared_inline (@nospecialize src:: MaybeCompressed ) =
120- ccall (:jl_ir_flag_inlining , UInt8, (Any,), src) == 1
123+ ccall (:jl_ir_flag_inlining , UInt8, (Any,), src) == SRC_FLAG_DECLARED_INLINE
121124
122125is_declared_noinline (@nospecialize src:: MaybeCompressed ) =
123- ccall (:jl_ir_flag_inlining , UInt8, (Any,), src) == 2
126+ ccall (:jl_ir_flag_inlining , UInt8, (Any,), src) == SRC_FLAG_DECLARED_NOINLINE
124127
125128# ####################
126129# OptimizationState #
@@ -157,6 +160,7 @@ code_cache(state::InliningState) = WorldView(code_cache(state.interp), state.wor
157160
158161mutable struct OptimizationResult
159162 ir:: IRCode
163+ inline_flag:: UInt8
160164 simplified:: Bool # indicates whether the IR was processed with `cfg_simplify!`
161165end
162166
168172mutable struct OptimizationState{Interp<: AbstractInterpreter }
169173 linfo:: MethodInstance
170174 src:: CodeInfo
171- result :: Union{Nothing, OptimizationResult}
175+ optresult :: Union{Nothing, OptimizationResult}
172176 stmt_info:: Vector{CallInfo}
173177 mod:: Module
174178 sptypes:: Vector{VarState}
@@ -236,13 +240,29 @@ include("ssair/EscapeAnalysis.jl")
236240include (" ssair/passes.jl" )
237241include (" ssair/irinterp.jl" )
238242
243+ function ir_to_codeinf! (opt:: OptimizationState , frame:: InferenceState , edges:: SimpleVector )
244+ ir_to_codeinf! (opt, edges, compute_inlining_cost (frame. interp, frame. result, opt. optresult))
245+ end
246+
247+ function ir_to_codeinf! (opt:: OptimizationState , edges:: SimpleVector , inlining_cost:: InlineCostType )
248+ src = ir_to_codeinf! (opt, edges)
249+ src. inlining_cost = inlining_cost
250+ src
251+ end
252+
253+ function ir_to_codeinf! (opt:: OptimizationState , edges:: SimpleVector )
254+ src = ir_to_codeinf! (opt)
255+ src. edges = edges
256+ src
257+ end
258+
239259function ir_to_codeinf! (opt:: OptimizationState )
240- (; linfo, src, result ) = opt
241- if result === nothing
260+ (; linfo, src, optresult ) = opt
261+ if optresult === nothing
242262 return src
243263 end
244- src = ir_to_codeinf! (src, result . ir)
245- opt. result = nothing
264+ src = ir_to_codeinf! (src, optresult . ir)
265+ opt. optresult = nothing
246266 opt. src = src
247267 maybe_validate_code (linfo, src, " optimized" )
248268 return src
@@ -485,63 +505,12 @@ end
485505abstract_eval_ssavalue (s:: SSAValue , src:: Union{IRCode,IncrementalCompact} ) = types (src)[s]
486506
487507"""
488- finish(interp::AbstractInterpreter, opt::OptimizationState,
489- ir::IRCode, caller::InferenceResult)
508+ finishopt!(interp::AbstractInterpreter, opt::OptimizationState, ir::IRCode)
490509
491- Post-process information derived by Julia-level optimizations for later use.
492- In particular, this function determines the inlineability of the optimized code.
510+ Called at the end of optimization to store the resulting IR back into the OptimizationState.
493511"""
494- function finish (interp:: AbstractInterpreter , opt:: OptimizationState ,
495- ir:: IRCode , caller:: InferenceResult )
496- (; src, linfo) = opt
497- (; def, specTypes) = linfo
498-
499- force_noinline = is_declared_noinline (src)
500-
501- # compute inlining and other related optimizations
502- result = caller. result
503- @assert ! (result isa LimitedAccuracy)
504- result = widenslotwrapper (result)
505-
506- opt. result = OptimizationResult (ir, false )
507-
508- # determine and cache inlineability
509- if ! force_noinline
510- sig = unwrap_unionall (specTypes)
511- if ! (isa (sig, DataType) && sig. name === Tuple. name)
512- force_noinline = true
513- end
514- if ! is_declared_inline (src) && result === Bottom
515- force_noinline = true
516- end
517- end
518- if force_noinline
519- set_inlineable! (src, false )
520- elseif isa (def, Method)
521- if is_declared_inline (src) && isdispatchtuple (specTypes)
522- # obey @inline declaration if a dispatch barrier would not help
523- set_inlineable! (src, true )
524- else
525- # compute the cost (size) of inlining this code
526- params = OptimizationParams (interp)
527- cost_threshold = default = params. inline_cost_threshold
528- if ⊑ (optimizer_lattice (interp), result, Tuple) && ! isconcretetype (widenconst (result))
529- cost_threshold += params. inline_tupleret_bonus
530- end
531- # if the method is declared as `@inline`, increase the cost threshold 20x
532- if is_declared_inline (src)
533- cost_threshold += 19 * default
534- end
535- # a few functions get special treatment
536- if def. module === _topmod (def. module)
537- name = def. name
538- if name === :iterate || name === :unsafe_convert || name === :cconvert
539- cost_threshold += 4 * default
540- end
541- end
542- src. inlining_cost = inline_cost (ir, params, cost_threshold)
543- end
544- end
512+ function finishopt! (interp:: AbstractInterpreter , opt:: OptimizationState , ir:: IRCode )
513+ opt. optresult = OptimizationResult (ir, ccall (:jl_ir_flag_inlining , UInt8, (Any,), opt. src), false )
545514 return nothing
546515end
547516
1015984function optimize (interp:: AbstractInterpreter , opt:: OptimizationState , caller:: InferenceResult )
1016985 @zone " CC: OPTIMIZER" ir = run_passes_ipo_safe (opt. src, opt)
1017986 ipo_dataflow_analysis! (interp, opt, ir, caller)
1018- return finish (interp, opt, ir, caller)
987+ finishopt! (interp, opt, ir)
988+ return nothing
1019989end
1020990
1021991const ALL_PASS_NAMES = String[]
@@ -1466,7 +1436,7 @@ function statement_or_branch_cost(@nospecialize(stmt), line::Int, src::Union{Cod
14661436 return thiscost
14671437end
14681438
1469- function inline_cost (ir:: IRCode , params:: OptimizationParams , cost_threshold:: Int )
1439+ function inline_cost_model (ir:: IRCode , params:: OptimizationParams , cost_threshold:: Int )
14701440 bodycost = 0
14711441 for i = 1 : length (ir. stmts)
14721442 stmt = ir[SSAValue (i)][:stmt ]
0 commit comments