|
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