Skip to content

Commit

Permalink
optimizer: simple array SROA
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
aviatesk committed Jan 24, 2022
1 parent ad727df commit 4b513d3
Show file tree
Hide file tree
Showing 4 changed files with 480 additions and 155 deletions.
14 changes: 12 additions & 2 deletions base/compiler/optimize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ end

function foreigncall_effect_free(stmt::Expr, src::Union{IRCode,IncrementalCompact})
args = stmt.args
name = args[1]
isa(name, QuoteNode) && (name = name.value)
name = normalize(args[1])
isa(name, Symbol) || return false
ndims = alloc_array_ndims(name)
if ndims !== nothing
Expand All @@ -295,6 +294,17 @@ function alloc_array_ndims(name::Symbol)
return nothing
end

normalize(@nospecialize x) = isa(x, QuoteNode) ? x.value : x

function is_array_alloc(@nospecialize stmt)
isa(stmt, Expr) || return false
if isexpr(stmt, :foreigncall)
name = normalize(stmt.args[1])
return isa(name, Symbol) && alloc_array_ndims(name) !== nothing
end
return false
end

function alloc_array_no_throw(args::Vector{Any}, ndims::Int, src::Union{IRCode,IncrementalCompact})
length(args) ndims+6 || return false
atype = instanceof_tfunc(argextype(args[6], src))[1]
Expand Down
Loading

0 comments on commit 4b513d3

Please sign in to comment.