Skip to content

Commit b3dd634

Browse files
committed
replace julia.ivdep with julia.ivdep.begin/end
1 parent d112903 commit b3dd634

File tree

3 files changed

+47
-33
lines changed

3 files changed

+47
-33
lines changed

base/simdloop.jl

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function compile(x, ivdep)
5959
length(x.args) == 2 || throw(SimdError("1D for loop expected"))
6060
check_body!(x)
6161

62-
var,range = parse_iteration_space(x.args[1])
62+
var, range = parse_iteration_space(x.args[1])
6363
r = gensym("r") # Range value
6464
j = gensym("i") # Iteration variable for outer loop
6565
n = gensym("n") # Trip count for inner loop
@@ -68,15 +68,16 @@ function compile(x, ivdep)
6868
# Evaluate range value once, to enhance type and data flow analysis by optimizers.
6969
let $r = $range
7070
for $j in Base.simd_outer_range($r)
71-
let $n = Base.simd_inner_length($r,$j)
71+
let $n = Base.simd_inner_length($r, $j)
7272
if zero($n) < $n
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-
local $var = Base.simd_index($r,$j,$i)
76+
$(Expr(:loopinfo, ivdep))
77+
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+
$(Expr(:loopinfo, Symbol("julia.simdloop"), Symbol("julia.ivdep.end"))) # Mark loop as SIMD loop
8081
end
8182
end
8283
end
@@ -125,12 +126,12 @@ either case, your inner loop should have the following properties to allow vecto
125126
* No iteration ever waits on a previous iteration to make forward progress.
126127
"""
127128
macro simd(forloop)
128-
esc(compile(forloop, nothing))
129+
esc(compile(forloop, Symbol("julia.ivdep.end")))
129130
end
130131

131132
macro simd(ivdep, forloop)
132133
if ivdep === :ivdep
133-
esc(compile(forloop, Symbol("julia.ivdep")))
134+
esc(compile(forloop, Symbol("julia.ivdep.begin")))
134135
else
135136
throw(SimdError("Only ivdep is valid as the first argument to @simd"))
136137
end

src/llvm-simdloop.cpp

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ static bool markLoopInfo(Module &M, Function *marker, function_ref<LoopInfo &(Fu
115115

116116
LoopInfo &LI = GetLI(*I->getParent()->getParent());
117117
Loop *L = LI.getLoopFor(I->getParent());
118-
I->removeFromParent();
119118
if (!L)
120119
continue;
121120

@@ -131,7 +130,7 @@ static bool markLoopInfo(Module &M, Function *marker, function_ref<LoopInfo &(Fu
131130
TempMDTuple TempNode = MDNode::getTemporary(Lh->getContext(), None);
132131
MDs.push_back(TempNode.get());
133132

134-
// Walk `julia.loopinfo` metadata and filter out `julia.simdloop` and `julia.ivdep`
133+
// Walk `julia.loopinfo` metadata and filter out `julia.simdloop`
135134
if (I->hasMetadataOtherThanDebugLoc()) {
136135
MDNode *JLMD= I->getMetadata("julia.loopinfo");
137136
if (JLMD) {
@@ -144,8 +143,6 @@ static bool markLoopInfo(Module &M, Function *marker, function_ref<LoopInfo &(Fu
144143
if (S->getString().startswith("julia")) {
145144
if (S->getString().equals("julia.simdloop"))
146145
simd = true;
147-
if (S->getString().equals("julia.ivdep"))
148-
ivdep = true;
149146
continue;
150147
}
151148
}
@@ -154,7 +151,10 @@ static bool markLoopInfo(Module &M, Function *marker, function_ref<LoopInfo &(Fu
154151
}
155152
}
156153

157-
LLVM_DEBUG(dbgs() << "LSL: simd: " << simd << " ivdep: " << ivdep << "\n");
154+
if (!simd)
155+
continue;
156+
157+
LLVM_DEBUG(dbgs() << "LSL: Transform start.\n");
158158

159159
MDNode *n = L->getLoopID();
160160
if (n) {
@@ -173,35 +173,44 @@ static bool markLoopInfo(Module &M, Function *marker, function_ref<LoopInfo &(Fu
173173

174174
MDNode *m = MDNode::get(Lh->getContext(), ArrayRef<Metadata *>(LoopID));
175175

176-
// If ivdep is true we assume that there is no memory dependency between loop iterations
177-
// This is a fairly strong assumption and does often not hold true for generic code.
178-
if (ivdep) {
179-
// Mark memory references so that Loop::isAnnotatedParallel will return true for this loop.
180-
for (BasicBlock *BB : L->blocks()) {
181-
for (Instruction &I : *BB) {
182-
if (I.mayReadOrWriteMemory()) {
183-
I.setMetadata(LLVMContext::MD_mem_parallel_loop_access, m);
184-
}
185-
}
186-
}
187-
assert(L->isAnnotatedParallel());
176+
// Mark floating-point reductions as okay to reassociate/commute.
177+
for (BasicBlock::iterator I = Lh->begin(), E = Lh->end(); I != E; ++I) {
178+
if (PHINode *Phi = dyn_cast<PHINode>(I))
179+
enableUnsafeAlgebraIfReduction(Phi, L);
180+
else
181+
break;
188182
}
189183

190-
if (simd) {
191-
// Mark floating-point reductions as okay to reassociate/commute.
192-
for (BasicBlock::iterator I = Lh->begin(), E = Lh->end(); I != E; ++I) {
193-
if (PHINode *Phi = dyn_cast<PHINode>(I))
194-
enableUnsafeAlgebraIfReduction(Phi, L);
195-
else
196-
break;
184+
for (BasicBlock *BB : L->blocks()) {
185+
for (Instruction &I : *BB) {
186+
// find julia.ivdep.begin/end block
187+
if (I.hasMetadataOtherThanDebugLoc()) {
188+
MDNode *JLMD= I.getMetadata("julia.loopinfo");
189+
if (JLMD) {
190+
for (unsigned i = 0, ie = JLMD->getNumOperands(); i < ie; ++i) {
191+
Metadata *Op = JLMD->getOperand(i);
192+
const MDString *S = dyn_cast<MDString>(Op);
193+
if (S && S->getString().startswith("julia.ivdep")) {
194+
if (S->getString().equals("julia.ivdep.begin"))
195+
ivdep = true; // turn on ivdep
196+
if (S->getString().equals("julia.ivdep.end"))
197+
ivdep = false; // turn off ivdep
198+
break; // only accept 1 julia.ivdep.begin/end
199+
}
200+
}
201+
}
202+
}
203+
if (ivdep && I.mayReadOrWriteMemory())
204+
I.setMetadata(LLVMContext::MD_mem_parallel_loop_access, m);
197205
}
198206
}
207+
LLVM_DEBUG(dbgs() << "LSL: Transform end.\n");
199208

200209
Changed = true;
201210
}
202211

203212
for (Instruction *I : ToDelete)
204-
I->deleteValue();
213+
I->eraseFromParent();
205214
marker->eraseFromParent();
206215

207216
return Changed;

test/llvmpasses/simdloop.ll

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ top:
88
br label %loop
99
loop:
1010
%i = phi i64 [0, %top], [%nexti, %loop]
11+
call void @julia.loopinfo_marker(), !julia.loopinfo !6
1112
%aptr = getelementptr double, double *%a, i64 %i
1213
%bptr = getelementptr double, double *%b, i64 %i
1314
; CHECK: llvm.mem.parallel_loop_access
@@ -30,6 +31,7 @@ top:
3031
loop:
3132
%i = phi i64 [0, %top], [%nexti, %loop]
3233
%v = phi double [0.000000e+00, %top], [%nextv, %loop]
34+
call void @julia.loopinfo_marker(), !julia.loopinfo !6
3335
%aptr = getelementptr double, double *%a, i64 %i
3436
; CHECK: llvm.mem.parallel_loop_access
3537
%aval = load double, double *%aptr
@@ -70,6 +72,7 @@ entry:
7072

7173
for.body: ; preds = %for.body, %entry
7274
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
75+
call void @julia.loopinfo_marker(), !julia.loopinfo !6
7376
%arrayidx = getelementptr inbounds i32, i32* %b, i64 %indvars.iv
7477
%0 = load i32, i32* %arrayidx, align 4
7578
%add = add nsw i32 %0, %N
@@ -88,8 +91,9 @@ for.end: ; preds = %for.body
8891

8992
!1 = !{}
9093
!2 = !{!"julia.simdloop"}
91-
!3 = !{!"julia.simdloop", !"julia.ivdep"}
92-
!4 = !{!"julia.simdloop", !"julia.ivdep", !5}
94+
!3 = !{!"julia.simdloop", !"julia.ivdep.end"}
95+
!4 = !{!"julia.simdloop", !"julia.ivdep.end", !5}
9396
!5 = !{!"llvm.loop.vectorize.disable", i1 0}
97+
!6 = !{!"julia.ivdep.begin"}
9498
; CHECK: [[LOOP]] = distinct !{[[LOOP]], [[LOOP_DISABLE:![0-9]+]]}
9599
; CHECK-NEXT: [[LOOP_DISABLE]] = !{!"llvm.loop.vectorize.disable", i1 false}

0 commit comments

Comments
 (0)