From a17f666f99b189f1d53dcf913420ff1edf9e91d5 Mon Sep 17 00:00:00 2001 From: Tobias Grosser Date: Thu, 1 Nov 2012 05:34:35 +0000 Subject: [PATCH] Codegen: Copy and restore the ValueMap and ClastVars explicitly When generating OpenMP or GPGPU code the original ValueMap and ClastVars must be kept. We already recovered the original ClastVars by reverting the changes, but we did not keep the content of the ValueMap. This patch keeps now an explicit copy of both maps and restores them after generating OpenMP or GPGPU code. This is an adapted version of a patch contributed by: Armin Groesslinger llvm-svn: 167213 --- polly/lib/CodeGen/CodeGeneration.cpp | 57 +++++++++------------- .../CodeGen/OpenMP/clastvar_after_parallel_loop.ll | 56 +++++++++++++++++++++ 2 files changed, 80 insertions(+), 33 deletions(-) create mode 100644 polly/test/CodeGen/OpenMP/clastvar_after_parallel_loop.ll diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp index fcd2d52..d713ae47 100644 --- a/polly/lib/CodeGen/CodeGeneration.cpp +++ b/polly/lib/CodeGen/CodeGeneration.cpp @@ -285,12 +285,10 @@ private: /// structure. SetVector 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. /// @@ -484,37 +482,18 @@ SetVector ClastStmtCodeGen::getOMPValues() { return Values; } -void ClastStmtCodeGen::updateWithValueMap(OMPGenerator::ValueToValueMapTy &VMap, - bool Reverse) { +void ClastStmtCodeGen::updateWithValueMap( + OMPGenerator::ValueToValueMapTy &VMap) { std::set Inserted; - if (Reverse) { - OMPGenerator::ValueToValueMapTy ReverseMap; - - for (std::map::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::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; @@ -552,14 +531,19 @@ void ClastStmtCodeGen::codegenForOpenMP(const clast_for *For) { 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()); @@ -698,9 +682,16 @@ void ClastStmtCodeGen::codegenForGPGPU(const clast_for *F) { VMap.insert(std::make_pair(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()); diff --git a/polly/test/CodeGen/OpenMP/clastvar_after_parallel_loop.ll b/polly/test/CodeGen/OpenMP/clastvar_after_parallel_loop.ll new file mode 100644 index 0000000..3e44784 --- /dev/null +++ b/polly/test/CodeGen/OpenMP/clastvar_after_parallel_loop.ll @@ -0,0 +1,56 @@ +; 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 -- 2.7.4