Skip to content

Commit 7b05508

Browse files
committed
optimizer: simple array SROA
Implements a simple Julia-level array allocation elimination on top of #43888. ```julia julia> code_typed((String,String)) do s, t a = Vector{Base.RefValue{String}}(undef, 2) a[1] = Ref(s) a[2] = Ref(t) return a[1][] end ``` ```diff diff --git a/master b/pr index 9c8da14380..5b63d08190 100644 --- a/master +++ b/pr @@ -1,11 +1,4 @@ 1-element Vector{Any}: CodeInfo( -1 ─ %1 = $(Expr(:foreigncall, :(:jl_alloc_array_1d), Vector{Base.RefValue{String}}, svec(Any, Int64), 0, :(:ccall), Vector{Base.RefValue{String}}, 2, 2))::Vector{Base.RefValue{String}} -│ %2 = %new(Base.RefValue{String}, s)::Base.RefValue{String} -│ Base.arrayset(true, %1, %2, 1)::Vector{Base.RefValue{String}} -│ %4 = %new(Base.RefValue{String}, t)::Base.RefValue{String} -│ Base.arrayset(true, %1, %4, 2)::Vector{Base.RefValue{String}} -│ %6 = Base.arrayref(true, %1, 1)::Base.RefValue{String} -│ %7 = Base.getfield(%6, :x)::String -└── return %7 +1 ─ return s ) => String ``` Still this array SROA handle is very limited and able to handle only trivial examples (though I confirmed this version already eliminates few array allocations during sysimg build). For those who interested, I added some discussions on array optimization [here](https://aviatesk.github.io/EscapeAnalysis.jl/dev/#EA-Array-Analysis).
1 parent 04f2d48 commit 7b05508

File tree

4 files changed

+508
-168
lines changed

4 files changed

+508
-168
lines changed

base/compiler/optimize.jl

+12-2
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,7 @@ end
288288

289289
function foreigncall_effect_free(stmt::Expr, src::Union{IRCode,IncrementalCompact})
290290
args = stmt.args
291-
name = args[1]
292-
isa(name, QuoteNode) && (name = name.value)
291+
name = normalize(args[1])
293292
isa(name, Symbol) || return false
294293
ndims = alloc_array_ndims(name)
295294
if ndims !== nothing
@@ -315,6 +314,17 @@ function alloc_array_ndims(name::Symbol)
315314
return nothing
316315
end
317316

317+
normalize(@nospecialize x) = isa(x, QuoteNode) ? x.value : x
318+
319+
function is_array_alloc(@nospecialize stmt)
320+
isa(stmt, Expr) || return false
321+
if isexpr(stmt, :foreigncall)
322+
name = normalize(stmt.args[1])
323+
return isa(name, Symbol) && alloc_array_ndims(name) !== nothing
324+
end
325+
return false
326+
end
327+
318328
const FOREIGNCALL_ARG_START = 6
319329

320330
function alloc_array_no_throw(args::Vector{Any}, ndims::Int, src::Union{IRCode,IncrementalCompact})

0 commit comments

Comments
 (0)