Skip to content

Commit

Permalink
optimizer: move inlineable constants into argument position during `c…
Browse files Browse the repository at this point in the history
…ompact!`-ion (#50767)

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 argument positions so that the 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.

Requires:
- #50764
- #50765
- #50768
  • Loading branch information
aviatesk committed Aug 4, 2023
1 parent 2a70dac commit 9e9f67d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 5 deletions.
7 changes: 6 additions & 1 deletion base/compiler/ssair/ir.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1338,7 +1338,12 @@ function process_node!(compact::IncrementalCompact, result_idx::Int, inst::Instr
return result_idx
end
end
ssa_rename[idx] = SSAValue(result_idx)
typ = inst[:type]
if isa(typ, Const) && is_inlineable_constant(typ.val)
ssa_rename[idx] = quoted(typ.val)
else
ssa_rename[idx] = SSAValue(result_idx)
end
result[result_idx][:inst] = stmt
result_idx += 1
elseif isa(stmt, PiNode)
Expand Down
6 changes: 2 additions & 4 deletions test/compiler/EscapeAnalysis/interprocedural.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,8 @@ identity_if_string(x::SafeRef) = nothing
let result = code_escapes((SafeRef{String},); optimize=false) do x
identity_if_string(x)
end
i = only(findall(iscall((result.ir, identity_if_string)), result.ir.stmts.inst))
r = only(findall(isreturn, result.ir.stmts.inst))
@test !has_thrown_escape(result.state[Argument(2)], i)
@test !has_return_escape(result.state[Argument(2)], r)
@test !has_thrown_escape(result.state[Argument(2)])
@test !has_return_escape(result.state[Argument(2)])
end
let result = code_escapes((Union{SafeRef{String},Vector{String}},); optimize=false) do x
identity_if_string(x)
Expand Down
17 changes: 17 additions & 0 deletions test/compiler/inline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2065,3 +2065,20 @@ end
# https://github.com/JuliaLang/julia/issues/50612
f50612(x) = UInt32(x)
@test all(!isinvoke(:UInt32),get_code(f50612,Tuple{Char}))

# move inlineable constant values into statement position during `compact!`-ion
# so that we don't inline DCE-eligibile calls
Base.@assume_effects :nothrow function erase_before_inlining(x, y)
z = sin(y)
if x
return "julia"
end
return z
end
@test fully_eliminated((Float64,); retval=5) do y
length(erase_before_inlining(true, y))
end
@test fully_eliminated((Float64,); retval=(5,5)) do y
z = erase_before_inlining(true, y)
return length(z), length(z)
end

0 comments on commit 9e9f67d

Please sign in to comment.