Skip to content

Commit 250138a

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 e503797 commit 250138a

File tree

4 files changed

+505
-166
lines changed

4 files changed

+505
-166
lines changed

base/compiler/optimize.jl

+12-2
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,7 @@ end
291291

292292
function foreigncall_effect_free(stmt::Expr, src::Union{IRCode,IncrementalCompact})
293293
args = stmt.args
294-
name = args[1]
295-
isa(name, QuoteNode) && (name = name.value)
294+
name = normalize(args[1])
296295
isa(name, Symbol) || return false
297296
ndims = alloc_array_ndims(name)
298297
if ndims !== nothing
@@ -318,6 +317,17 @@ function alloc_array_ndims(name::Symbol)
318317
return nothing
319318
end
320319

320+
normalize(@nospecialize x) = isa(x, QuoteNode) ? x.value : x
321+
322+
function is_array_alloc(@nospecialize stmt)
323+
isa(stmt, Expr) || return false
324+
if isexpr(stmt, :foreigncall)
325+
name = normalize(stmt.args[1])
326+
return isa(name, Symbol) && alloc_array_ndims(name) !== nothing
327+
end
328+
return false
329+
end
330+
321331
function alloc_array_no_throw(args::Vector{Any}, ndims::Int, src::Union{IRCode,IncrementalCompact})
322332
length(args) ndims+6 || return false
323333
atype = instanceof_tfunc(argextype(args[6], src))[1]

0 commit comments

Comments
 (0)