Skip to content

Commit ee89d70

Browse files
committed
@nospecialize a few type unstable functions and reduce to a single method to avoid dynamic dispatches.
1 parent 88103ef commit ee89d70

File tree

2 files changed

+35
-23
lines changed

2 files changed

+35
-23
lines changed

src/_avx.jl

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@ using LoopVectorization: LoopVectorization, LoopSet, lower
55

66
struct Ex{T, Tup} end
77

8-
function to_type(ex::Expr)
9-
Ex{ex.head, Tuple{to_type.(ex.args)...}}
8+
function to_type(@nospecialize(ex))
9+
if ex isa Expr
10+
Ex{ex.head, Tuple{to_type.(ex.args)...}}
11+
elseif ex isa LineNumberNode
12+
nothing
13+
else
14+
ex
15+
end
1016
end
1117

12-
to_type(x) = x
13-
to_type(::LineNumberNode) = nothing
18+
# to_type(x) = x
19+
# to_type(::LineNumberNode) = nothing
1420

1521
#----------------------------------------------------------------------------------------------------
1622

@@ -19,42 +25,39 @@ to_expr(x) = x
1925

2026
#----------------------------------------------------------------------------------------------------
2127

22-
function find_vars_and_gensym!(ex::Expr, vars::Set{Symbol}, ivars::Vector{Symbol})
23-
if ex.head == :(=) && ex.args[1] isa Symbol
24-
push!(ivars, ex.args[1])
25-
elseif ex.head == :call
26-
push!(ivars, ex.args[1])
27-
end
28-
ex
29-
end
30-
31-
function find_vars_and_gensym!(x::Symbol, vars::Set{Symbol}, ivars::Vector{Symbol})
32-
if (x vars) && (x ivars)
33-
push!(vars, x)
34-
x
28+
function find_vars!(@nospecialize(ex), vars::Set{Symbol}, ivars::Vector{Symbol})
29+
if ex isa Expr
30+
if ex.head == :(=) && ex.args[1] isa Symbol
31+
push!(ivars, ex.args[1])
32+
elseif ex.head == :call
33+
push!(ivars, ex.args[1])
34+
end
35+
ex
36+
elseif ex isa Symbol && (ex vars) && (ex ivars)
37+
push!(vars, ex)
38+
ex
3539
else
36-
x
40+
ex
3741
end
3842
end
3943

40-
find_vars_and_gensym!(x, vars::Set{Symbol}, ivars::Vector{Symbol}) = x
41-
4244
#----------------------------------------------------------------------------------------------------
4345

44-
nt(keys, vals) = NamedTuple{keys, typeof(vals)}(vals)
46+
# Not sure whether or not it's better to rely on inlining and const prop. I just like to make things explicit.
47+
@inline nt(::Val{keys}, vals) where {keys} = NamedTuple{keys, typeof(vals)}(vals)
4548

4649
macro _avx(ex)
4750
D = Set{Symbol}()
4851
ivars = Symbol[]
4952

50-
gex = prewalk(x -> find_vars_and_gensym!(x, D, ivars), ex)
53+
gex = prewalk(x -> find_vars!(x, D, ivars), ex)
5154

5255
type_ex = to_type(gex)
5356

5457
tvars = Tuple(D)
5558

5659
quote
57-
kwargs = LoopVectorization.nt($(QuoteNode(tvars)), $(Expr(:tuple, tvars...)))
60+
kwargs = LoopVectorization.nt(Val{$(QuoteNode(tvars))}(), $(Expr(:tuple, tvars...)))
5861
$(Expr(:tuple, tvars...)) = LoopVectorization._avx($(QuoteNode(type_ex)), kwargs)
5962
# LoopVectorization._avx($(QuoteNode(type_ex)), kwargs) # comment out the above line, uncomment this one, and get rid of the `@generated` on _avx to see the function body.
6063
end |> esc

src/constructors.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ function LoopSet(q::Expr)
4848
ls
4949
end
5050

51+
function LoopSet(q::Expr, types::Dict{Symbol,DataType})
52+
q = SIMDPirates.contract_pass(q)
53+
ls = LoopSet()
54+
copyto!(ls, q, types)
55+
resize!(ls.loop_order, num_loops(ls))
56+
ls
57+
end
58+
59+
5160
"""
5261
@avx
5362

0 commit comments

Comments
 (0)