@@ -5,12 +5,18 @@ using LoopVectorization: LoopVectorization, LoopSet, lower
5
5
6
6
struct Ex{T, Tup} end
7
7
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
10
16
end
11
17
12
- to_type (x) = x
13
- to_type (:: LineNumberNode ) = nothing
18
+ # to_type(x) = x
19
+ # to_type(::LineNumberNode) = nothing
14
20
15
21
# ----------------------------------------------------------------------------------------------------
16
22
@@ -19,42 +25,39 @@ to_expr(x) = x
19
25
20
26
# ----------------------------------------------------------------------------------------------------
21
27
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
35
39
else
36
- x
40
+ ex
37
41
end
38
42
end
39
43
40
- find_vars_and_gensym! (x, vars:: Set{Symbol} , ivars:: Vector{Symbol} ) = x
41
-
42
44
# ----------------------------------------------------------------------------------------------------
43
45
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)
45
48
46
49
macro _avx (ex)
47
50
D = Set {Symbol} ()
48
51
ivars = Symbol[]
49
52
50
- gex = prewalk (x -> find_vars_and_gensym ! (x, D, ivars), ex)
53
+ gex = prewalk (x -> find_vars ! (x, D, ivars), ex)
51
54
52
55
type_ex = to_type (gex)
53
56
54
57
tvars = Tuple (D)
55
58
56
59
quote
57
- kwargs = LoopVectorization. nt ($ (QuoteNode (tvars)), $ (Expr (:tuple , tvars... )))
60
+ kwargs = LoopVectorization. nt (Val { $(QuoteNode(tvars))} ( ), $ (Expr (:tuple , tvars... )))
58
61
$ (Expr (:tuple , tvars... )) = LoopVectorization. _avx ($ (QuoteNode (type_ex)), kwargs)
59
62
# 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.
60
63
end |> esc
0 commit comments