Skip to content

Commit 40339ac

Browse files
committed
optimizer: move inlineable constants into statement position during compact!-ion
In code like below ```julia Base.@assume_effects :nothrow function erase_before_inlining(x, y) z = sin(y) if x return "julia" end return z end let y::Float64 length(erase_before_inlining(true, y)) end ``` the constant prop' can figure out the constant return type of `erase_before_inlining(true, y)` while it is profitable not to inline expand it since otherwise we left some `!:nothrow` callees there (xref: #47305). In order to workaround this problem, this commit makes `compact!`move inlineable constants into statement positions so that such "inlineable, but safe as a whole" calls to be erased during compaction. This should give us general compile-time performance improvement too as we no longer need to expand the IR for those calls.
1 parent 5b49d06 commit 40339ac

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

base/compiler/ssair/ir.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,12 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
13411341
return result_idx
13421342
end
13431343
end
1344-
ssa_rename[idx] = SSAValue(result_idx)
1344+
typ = inst[:type]
1345+
if isa(typ, Const) && is_inlineable_constant(typ.val)
1346+
ssa_rename[idx] = quoted(typ.val)
1347+
else
1348+
ssa_rename[idx] = SSAValue(result_idx)
1349+
end
13451350
result[result_idx][:inst] = stmt
13461351
result_idx += 1
13471352
elseif isa(stmt, PiNode)

test/compiler/EscapeAnalysis/interprocedural.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,8 @@ identity_if_string(x::SafeRef) = nothing
9898
let result = code_escapes((SafeRef{String},); optimize=false) do x
9999
identity_if_string(x)
100100
end
101-
i = only(findall(iscall((result.ir, identity_if_string)), result.ir.stmts.inst))
102-
r = only(findall(isreturn, result.ir.stmts.inst))
103-
@test !has_thrown_escape(result.state[Argument(2)], i)
104-
@test !has_return_escape(result.state[Argument(2)], r)
101+
@test !has_thrown_escape(result.state[Argument(2)])
102+
@test !has_return_escape(result.state[Argument(2)])
105103
end
106104
let result = code_escapes((Union{SafeRef{String},Vector{String}},); optimize=false) do x
107105
identity_if_string(x)

test/compiler/inline.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,3 +2065,20 @@ end
20652065
# https://github.com/JuliaLang/julia/issues/50612
20662066
f50612(x) = UInt32(x)
20672067
@test all(!isinvoke(:UInt32),get_code(f50612,Tuple{Char}))
2068+
2069+
# move inlineable constant values into statement position during `compact!`-ion
2070+
# so that we don't inline DCE-eligibile calls
2071+
Base.@assume_effects :nothrow function erase_before_inlining(x, y)
2072+
z = sin(y)
2073+
if x
2074+
return "julia"
2075+
end
2076+
return z
2077+
end
2078+
@test fully_eliminated((Float64,); retval=5) do y
2079+
length(erase_before_inlining(true, y))
2080+
end
2081+
@test fully_eliminated((Float64,); retval=(5,5)) do y
2082+
z = erase_before_inlining(true, y)
2083+
return length(z), length(z)
2084+
end

0 commit comments

Comments
 (0)