|
1 | 1 | # This file is a part of Julia. License is MIT: https://julialang.org/license |
2 | 2 |
|
| 3 | +############# |
| 4 | +# constants # |
| 5 | +############# |
| 6 | + |
| 7 | +# The slot has uses that are not statically dominated by any assignment |
| 8 | +# This is implied by `SLOT_USEDUNDEF`. |
| 9 | +# If this is not set, all the uses are (statically) dominated by the defs. |
| 10 | +# In particular, if a slot has `AssignedOnce && !StaticUndef`, it is an SSA. |
| 11 | +const SLOT_STATICUNDEF = 1 # slot might be used before it is defined (structurally) |
| 12 | +const SLOT_ASSIGNEDONCE = 16 # slot is assigned to only once |
| 13 | +const SLOT_USEDUNDEF = 32 # slot has uses that might raise UndefVarError |
| 14 | +# const SLOT_CALLED = 64 |
| 15 | + |
| 16 | +# NOTE make sure to sync the flag definitions below with julia.h and `jl_code_info_set_ir` in method.c |
| 17 | + |
| 18 | +const IR_FLAG_NULL = 0x00 |
| 19 | +# This statement is marked as @inbounds by user. |
| 20 | +# Ff replaced by inlining, any contained boundschecks may be removed. |
| 21 | +const IR_FLAG_INBOUNDS = 0x01 << 0 |
| 22 | +# This statement is marked as @inline by user |
| 23 | +const IR_FLAG_INLINE = 0x01 << 1 |
| 24 | +# This statement is marked as @noinline by user |
| 25 | +const IR_FLAG_NOINLINE = 0x01 << 2 |
| 26 | +const IR_FLAG_THROW_BLOCK = 0x01 << 3 |
| 27 | +# This statement may be removed if its result is unused. In particular it must |
| 28 | +# thus be both pure and effect free. |
| 29 | +const IR_FLAG_EFFECT_FREE = 0x01 << 4 |
| 30 | + |
| 31 | +# known to be always effect-free (in particular nothrow) |
| 32 | +const _PURE_BUILTINS = Any[tuple, svec, ===, typeof, nfields] |
| 33 | + |
| 34 | +# known to be effect-free if the are nothrow |
| 35 | +const _PURE_OR_ERROR_BUILTINS = [ |
| 36 | + fieldtype, apply_type, isa, UnionAll, |
| 37 | + getfield, arrayref, const_arrayref, arraysize, isdefined, Core.sizeof, |
| 38 | + Core.kwfunc, Core.ifelse, Core._typevar, (<:) |
| 39 | +] |
| 40 | + |
| 41 | +const TOP_TUPLE = GlobalRef(Core, :tuple) |
| 42 | + |
3 | 43 | ##################### |
4 | 44 | # OptimizationState # |
5 | 45 | ##################### |
@@ -52,7 +92,10 @@ function inlining_policy(interp::AbstractInterpreter, @nospecialize(src), stmt_f |
52 | 92 | return nothing |
53 | 93 | end |
54 | 94 |
|
| 95 | +function argextype end # imported by EscapeAnalysis |
55 | 96 | include("compiler/ssair/driver.jl") |
| 97 | +using .EscapeAnalysis |
| 98 | +import .EscapeAnalysis: EscapeState |
56 | 99 |
|
57 | 100 | mutable struct OptimizationState |
58 | 101 | linfo::MethodInstance |
@@ -121,46 +164,6 @@ function ir_to_codeinf!(opt::OptimizationState) |
121 | 164 | return src |
122 | 165 | end |
123 | 166 |
|
124 | | -############# |
125 | | -# constants # |
126 | | -############# |
127 | | - |
128 | | -# The slot has uses that are not statically dominated by any assignment |
129 | | -# This is implied by `SLOT_USEDUNDEF`. |
130 | | -# If this is not set, all the uses are (statically) dominated by the defs. |
131 | | -# In particular, if a slot has `AssignedOnce && !StaticUndef`, it is an SSA. |
132 | | -const SLOT_STATICUNDEF = 1 # slot might be used before it is defined (structurally) |
133 | | -const SLOT_ASSIGNEDONCE = 16 # slot is assigned to only once |
134 | | -const SLOT_USEDUNDEF = 32 # slot has uses that might raise UndefVarError |
135 | | -# const SLOT_CALLED = 64 |
136 | | - |
137 | | -# NOTE make sure to sync the flag definitions below with julia.h and `jl_code_info_set_ir` in method.c |
138 | | - |
139 | | -const IR_FLAG_NULL = 0x00 |
140 | | -# This statement is marked as @inbounds by user. |
141 | | -# Ff replaced by inlining, any contained boundschecks may be removed. |
142 | | -const IR_FLAG_INBOUNDS = 0x01 << 0 |
143 | | -# This statement is marked as @inline by user |
144 | | -const IR_FLAG_INLINE = 0x01 << 1 |
145 | | -# This statement is marked as @noinline by user |
146 | | -const IR_FLAG_NOINLINE = 0x01 << 2 |
147 | | -const IR_FLAG_THROW_BLOCK = 0x01 << 3 |
148 | | -# This statement may be removed if its result is unused. In particular it must |
149 | | -# thus be both pure and effect free. |
150 | | -const IR_FLAG_EFFECT_FREE = 0x01 << 4 |
151 | | - |
152 | | -# known to be always effect-free (in particular nothrow) |
153 | | -const _PURE_BUILTINS = Any[tuple, svec, ===, typeof, nfields] |
154 | | - |
155 | | -# known to be effect-free if the are nothrow |
156 | | -const _PURE_OR_ERROR_BUILTINS = [ |
157 | | - fieldtype, apply_type, isa, UnionAll, |
158 | | - getfield, arrayref, const_arrayref, arraysize, isdefined, Core.sizeof, |
159 | | - Core.kwfunc, Core.ifelse, Core._typevar, (<:) |
160 | | -] |
161 | | - |
162 | | -const TOP_TUPLE = GlobalRef(Core, :tuple) |
163 | | - |
164 | 167 | ######### |
165 | 168 | # logic # |
166 | 169 | ######### |
@@ -514,7 +517,8 @@ function run_passes(ci::CodeInfo, sv::OptimizationState) |
514 | 517 | @timeit "Inlining" ir = ssa_inlining_pass!(ir, ir.linetable, sv.inlining, ci.propagate_inbounds) |
515 | 518 | # @timeit "verify 2" verify_ir(ir) |
516 | 519 | @timeit "compact 2" ir = compact!(ir) |
517 | | - @timeit "SROA" ir = sroa_pass!(ir) |
| 520 | + nargs = let def = sv.linfo.def; isa(def, Method) ? Int(def.nargs) : 0; end |
| 521 | + @timeit "SROA" ir = sroa_pass!(ir, nargs) |
518 | 522 | @timeit "ADCE" ir = adce_pass!(ir) |
519 | 523 | @timeit "type lift" ir = type_lift_pass!(ir) |
520 | 524 | @timeit "compact 3" ir = compact!(ir) |
|
0 commit comments