/// structure.
SetVector<Value*> getOMPValues();
- /// @brief Update the internal structures according to a Value Map.
+ /// @brief Update ClastVars and ValueMap according to a value map.
///
- /// @param VMap A map from old to new values.
- /// @param Reverse If true, we assume the update should be reversed.
- void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
- bool Reverse);
+ /// @param VMap A map from old to new values.
+ void updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap);
/// @brief Create an OpenMP parallel for loop.
///
return Values;
}
-void ClastStmtCodeGen::updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap,
- bool Reverse) {
+void ClastStmtCodeGen::updateWithValueMap(
+ OMPGenerator::ValueToValueMapTy &VMap) {
std::set<Value*> Inserted;
- if (Reverse) {
- OMPGenerator::ValueToValueMapTy ReverseMap;
-
- for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
- I != E; ++I)
- ReverseMap.insert(std::make_pair(I->second, I->first));
-
- for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
- I != E; I++) {
- ClastVars[I->first] = ReverseMap[I->second];
- Inserted.insert(I->second);
- }
-
- /// FIXME: At the moment we do not reverse the update of the ValueMap.
- /// This is incomplet, but the failure should be obvious, such that
- /// we can fix this later.
- return;
- }
-
for (CharMapT::iterator I = ClastVars.begin(), E = ClastVars.end();
I != E; I++) {
ClastVars[I->first] = VMap[I->second];
Inserted.insert(I->second);
}
- for (std::map<Value*, Value*>::iterator I = VMap.begin(), E = VMap.end();
- I != E; ++I) {
+ for (OMPGenerator::ValueToValueMapTy::iterator I = VMap.begin(),
+ E = VMap.end(); I != E; ++I) {
if (Inserted.count(I->first))
continue;
BasicBlock::iterator AfterLoop = Builder.GetInsertPoint();
Builder.SetInsertPoint(LoopBody);
- updateWithValueMap(VMap, /* reverse */ false);
+ // Save the current values.
+ const ValueMapT ValueMapCopy = ValueMap;
+ const CharMapT ClastVarsCopy = ClastVars;
+
+ updateWithValueMap(VMap);
ClastVars[For->iterator] = IV;
if (For->body)
codegen(For->body);
- ClastVars.erase(For->iterator);
- updateWithValueMap(VMap, /* reverse */ true);
+ // Restore the original values.
+ ValueMap = ValueMapCopy;
+ ClastVars = ClastVarsCopy;
clearDomtree((*LoopBody).getParent()->getParent(),
P->getAnalysis<DominatorTree>());
VMap.insert(std::make_pair<Value*, Value*>(OldIV, IV));
}
- updateWithValueMap(VMap, /* reverse */ false);
+ // Preserve the current values.
+ const ValueMapT ValueMapCopy = ValueMap;
+ const CharMapT ClastVarsCopy = ClastVars;
+ updateWithVMap(VMap);
+
BlockGenerator::generate(Builder, *Statement, ValueMap, P);
- updateWithValueMap(VMap, /* reverse */ true);
+
+ // Restore the original values.
+ ValueMap = ValueMapCopy;
+ ClastVars = ClastVarsCopy;
if (AfterBB)
Builder.SetInsertPoint(AfterBB->begin());
--- /dev/null
+; RUN: opt %loadPolly -basicaa -polly-cloog -analyze -S < %s | FileCheck %s -check-prefix=CLOOG
+; RUN: opt %loadPolly -basicaa -polly-codegen -enable-polly-openmp -S < %s | FileCheck %s
+;
+; Test case that checks that after the parallel loop on j the value for i is
+; taken from the right temporary (in particular, _not_ the temporary used for i
+; in the OpenMP subfunction for the loop on j).
+;
+; void f(long * restrict A) {
+; long i, j;
+; for (i=0; i<100; ++i) {
+; #pragma omp parallel
+; for (j=0; j<100; ++j)
+; A[j] += i;
+; A[i] = 42;
+; }
+; }
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f(i64* noalias nocapture %A) {
+entry:
+ br label %for.i
+
+for.i:
+ %i = phi i64 [ %i.next, %for.end ], [ 0, %entry ]
+ br label %for.j
+
+for.j: ; preds = %for.j, %for.i
+ %j = phi i64 [ 0, %for.i ], [ %j.next, %for.j ]
+ %i.arrayidx = getelementptr inbounds i64* %A, i64 %j
+ %load = load i64* %i.arrayidx
+ %add = add nsw i64 %load, %i
+ store i64 %add, i64* %i.arrayidx
+ %j.next = add i64 %j, 1
+ %j.exitcond = icmp eq i64 %j.next, 100
+ br i1 %j.exitcond, label %for.end, label %for.j
+
+for.end: ; preds = %for.j
+ %j.arrayidx = getelementptr inbounds i64* %A, i64 %i
+ store i64 42, i64* %j.arrayidx
+ %i.next = add i64 %i, 1
+ %i.exitcond = icmp eq i64 %i.next, 100
+ br i1 %i.exitcond, label %end, label %for.i
+
+end: ; preds = %for.end, %entry
+ ret void
+}
+
+; CLOOG: for (c2=0;c2<=99;c2++) {
+; CLOOG: for (c4=0;c4<=99;c4++) {
+; CLOOG: Stmt_for_j(c2,c4);
+; CLOOG: }
+; CLOOG: Stmt_for_end(c2);
+; CLOOG: }
+
+; CHECK: @f.omp_subfn