44
55module SimdLoop
66
7- export @simd , simd_outer_range, simd_inner_length, simd_index
7+ export @simd , @ivdep , simd_outer_range, simd_inner_length, simd_index
88
99# Error thrown from ill-formed uses of @simd
1010struct SimdError <: Exception
@@ -58,7 +58,7 @@ function compile(x, ivdep)
5858 (isa (x, Expr) && x. head === :for ) || throw (SimdError (" for loop expected" ))
5959 length (x. args) == 2 || throw (SimdError (" 1D for loop expected" ))
6060 check_body! (x)
61-
61+ ivdepend = ivdep === nothing ? nothing : Expr ( :ivdepscope , :end )
6262 var,range = parse_iteration_space (x. args[1 ])
6363 r = gensym (" r" ) # Range value
6464 j = gensym (" i" ) # Iteration variable for outer loop
@@ -73,10 +73,12 @@ function compile(x, ivdep)
7373 # Lower loop in way that seems to work best for LLVM 3.3 vectorizer.
7474 let $ i = zero ($ n)
7575 while $ i < $ n
76+ $ ivdep
7677 local $ var = Base. simd_index ($ r,$ j,$ i)
7778 $ (x. args[2 ]) # Body of loop
7879 $ i += 1
79- $ (Expr (:loopinfo , Symbol (" julia.simdloop" ), ivdep)) # Mark loop as SIMD loop
80+ $ ivdepend
81+ $ (Expr (:loopinfo , Symbol (" julia.simdloop" ))) # Mark loop as SIMD loop
8082 end
8183 end
8284 end
@@ -130,10 +132,27 @@ end
130132
131133macro simd (ivdep, forloop)
132134 if ivdep === :ivdep
133- esc (compile (forloop, Symbol ( " julia.ivdep " )))
135+ esc (compile (forloop, Expr ( :ivdepscope , :begin )))
134136 else
135137 throw (SimdError (" Only ivdep is valid as the first argument to @simd" ))
136138 end
137139end
138140
141+ """
142+ @ivdep
143+
144+ Annotate the following scope is free of loop-carried memory dependencies.
145+
146+ !!! note
147+ @ivdep is valid only within a @simd loop
148+ """
149+ macro ivdep (ex)
150+ esc (quote
151+ $ (Expr (:ivdepscope , :begin ))
152+ temp = $ ex
153+ $ (Expr (:ivdepscope , :end ))
154+ temp
155+ end )
156+ end
157+
139158end # module SimdLoop
0 commit comments