Skip to content

Commit e22ef67

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 619edba commit e22ef67

File tree

4 files changed

+431
-155
lines changed

4 files changed

+431
-155
lines changed

base/compiler/optimize.jl

+12-2
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,7 @@ end
268268

269269
function foreigncall_effect_free(stmt::Expr, src::Union{IRCode,IncrementalCompact})
270270
args = stmt.args
271-
name = args[1]
272-
isa(name, QuoteNode) && (name = name.value)
271+
name = normalize(args[1])
273272
isa(name, Symbol) || return false
274273
ndims = alloc_array_ndims(name)
275274
if ndims !== nothing
@@ -295,6 +294,17 @@ function alloc_array_ndims(name::Symbol)
295294
return nothing
296295
end
297296

297+
normalize(@nospecialize x) = isa(x, QuoteNode) ? x.value : x
298+
299+
function is_array_alloc(@nospecialize stmt)
300+
isa(stmt, Expr) || return false
301+
if isexpr(stmt, :foreigncall)
302+
name = normalize(stmt.args[1])
303+
return isa(name, Symbol) && alloc_array_ndims(name) !== nothing
304+
end
305+
return false
306+
end
307+
298308
function alloc_array_no_throw(args::Vector{Any}, ndims::Int, src::Union{IRCode,IncrementalCompact})
299309
length(args) ndims+6 || return false
300310
atype = instanceof_tfunc(argextype(args[6], src))[1]

0 commit comments

Comments
 (0)