Skip to content

Commit

Permalink
Fix scope issue in simd loops
Browse files Browse the repository at this point in the history
The iteration variable being declared local raised errors
when using the simd macro twice in the same scope.

Also, it now behaves like normal for, i.e. if the iteration
variable was defined, its value is updated at the end of the loop.

Also, code cosmetics.
  • Loading branch information
carlobaldassi committed Mar 31, 2014
1 parent 509da87 commit 2863c89
Showing 1 changed file with 21 additions and 27 deletions.
48 changes: 21 additions & 27 deletions base/simdloop.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,28 @@ end
# Parse iteration space expression
# symbol '=' range
# symbol 'in' range
function parse_iteration_space( x )
if !Meta.isexpr(x,[:(=),:in])
throw( SimdError("= or in expected"))
elseif length(x.args)!=2
throw( SimdError("simd range syntax is wrong"))
elseif !isa(x.args[1],Symbol)
throw( SimdError("simd loop index must be a symbol"))
else
x.args # symbol, range
end
function parse_iteration_space(x)
Meta.isexpr(x, [:(=), :in]) || throw(SimdError("= or in expected"))
length(x.args) == 2 || throw(SimdError("simd range syntax is wrong"))
isa(x.args[1], Symbol) || throw(SimdError("simd loop index must be a symbol"))
x.args # symbol, range
end

# Compile Expr x in context of @simd.
function compile(x)
if !Meta.isexpr(x,:for)
throw(SimdError("for loop expected"))
elseif length(x.args)!=2
throw(SimdError("1D for loop expected"))
else
var,range = parse_iteration_space(x.args[1])
r = gensym() # Range
n = gensym() # Trip count
s = gensym() # Step
i = gensym() # Index variable
# LLVM vectorizer needs to compute a trip count, so make it obvious.
quote
local $r = $range
local $n = length($r)
local $s = step($r)
local $var = first($r)
Meta.isexpr(x, :for) || throw(SimdError("for loop expected"))
length(x.args) == 2 || throw(SimdError("1D for loop expected"))

var,range = parse_iteration_space(x.args[1])
svar = Expr(:call, :symbol, string(var))
n = gensym("n") # Trip count
s = gensym("s") # Step
i = gensym("i") # Index variable
# LLVM vectorizer needs to compute a trip count, so make it obvious.
quote
let $var = first($range)
local $n = length($range)
local $s = step($range)
local $i = zero($n)
while $i < $n
$(x.args[2])
Expand All @@ -50,11 +42,13 @@ function compile(x)
$(Expr(:simdloop)) # Mark loop as SIMD loop
end
end
isdefined($svar) && ($var = last($range))
nothing
end
end

macro simd(forloop)
esc(compile(forloop))
end

end # simdloop
end # module SimdLoop

0 comments on commit 2863c89

Please sign in to comment.