From 4036ad485fbd32280e567ff7ddb92c84c25ddf08 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Tue, 12 Jun 2007 22:43:57 +0000 Subject: [PATCH] Fix test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll llvm-svn: 37564 --- llvm/lib/Transforms/Scalar/GVNPRE.cpp | 77 ++++++++++++++------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/GVNPRE.cpp b/llvm/lib/Transforms/Scalar/GVNPRE.cpp index cfa45bba52a3..0e5e77c629ef 100644 --- a/llvm/lib/Transforms/Scalar/GVNPRE.cpp +++ b/llvm/lib/Transforms/Scalar/GVNPRE.cpp @@ -101,6 +101,9 @@ namespace { std::set MS; std::vector createdExpressions; + std::map > availableOut; + std::map > anticipatedIn; + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); @@ -115,8 +118,7 @@ namespace { bool add(Value* V, uint32_t number); Value* find_leader(std::set& vals, Value* v); - Value* phi_translate(std::set& set, - Value* V, BasicBlock* pred, BasicBlock* succ); + Value* phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ); void phi_translate_set(std::set& anticIn, BasicBlock* pred, BasicBlock* succ, std::set& out); @@ -132,8 +134,7 @@ namespace { std::set& currAvail, std::map > availOut); void cleanup(); - void elimination(std::map >& availOut); + void elimination(); }; @@ -160,6 +161,9 @@ bool GVNPRE::add(Value* V, uint32_t number) { } Value* GVNPRE::find_leader(std::set& vals, Value* v) { + if (!isa(v)) + return v; + for (std::set::iterator I = vals.begin(), E = vals.end(); I != E; ++I) { assert(VN.find(v) != VN.end() && "Value not numbered?"); @@ -171,24 +175,23 @@ Value* GVNPRE::find_leader(std::set& vals, Value* v) { return 0; } -Value* GVNPRE::phi_translate(std::set& set, - Value* V, BasicBlock* pred, BasicBlock* succ) { +Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) { if (V == 0) return 0; if (BinaryOperator* BO = dyn_cast(V)) { Value* newOp1 = isa(BO->getOperand(0)) - ? phi_translate(set, - find_leader(set, BO->getOperand(0)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], BO->getOperand(0)), + pred, succ) : BO->getOperand(0); if (newOp1 == 0) return 0; Value* newOp2 = isa(BO->getOperand(1)) - ? phi_translate(set, - find_leader(set, BO->getOperand(1)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], BO->getOperand(1)), + pred, succ) : BO->getOperand(1); if (newOp2 == 0) return 0; @@ -200,7 +203,9 @@ Value* GVNPRE::phi_translate(std::set& set, if (add(newVal, nextValueNumber)) nextValueNumber++; - if (!find_leader(set, newVal)) { + + Value* leader = find_leader(availableOut[pred], newVal); + if (leader == 0) { DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; createdExpressions.push_back(newVal); return newVal; @@ -214,7 +219,7 @@ Value* GVNPRE::phi_translate(std::set& set, MS.erase(newVal); delete newVal; - return 0; + return leader; } } } else if (PHINode* P = dyn_cast(V)) { @@ -222,17 +227,17 @@ Value* GVNPRE::phi_translate(std::set& set, return P->getIncomingValueForBlock(pred); } else if (CmpInst* C = dyn_cast(V)) { Value* newOp1 = isa(C->getOperand(0)) - ? phi_translate(set, - find_leader(set, C->getOperand(0)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], C->getOperand(0)), + pred, succ) : C->getOperand(0); if (newOp1 == 0) return 0; Value* newOp2 = isa(C->getOperand(1)) - ? phi_translate(set, - find_leader(set, C->getOperand(1)), - pred, succ) + ? phi_translate( + find_leader(anticipatedIn[succ], C->getOperand(1)), + pred, succ) : C->getOperand(1); if (newOp2 == 0) return 0; @@ -245,7 +250,9 @@ Value* GVNPRE::phi_translate(std::set& set, if (add(newVal, nextValueNumber)) nextValueNumber++; - if (!find_leader(set, newVal)) { + + Value* leader = find_leader(availableOut[pred], newVal); + if (leader == 0) { DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; createdExpressions.push_back(newVal); return newVal; @@ -259,7 +266,7 @@ Value* GVNPRE::phi_translate(std::set& set, MS.erase(newVal); delete newVal; - return 0; + return leader; } } } @@ -272,7 +279,7 @@ void GVNPRE::phi_translate_set(std::set& anticIn, std::set& out) { for (std::set::iterator I = anticIn.begin(), E = anticIn.end(); I != E; ++I) { - Value* V = phi_translate(anticIn, *I, pred, succ); + Value* V = phi_translate(*I, pred, succ); if (V != 0) out.insert(V); } @@ -485,8 +492,7 @@ void GVNPRE::CalculateAvailOut(DomTreeNode* DI, } } -void GVNPRE::elimination(std::map >& availableOut) { +void GVNPRE::elimination() { DOUT << "\n\nPhase 3: Elimination\n\n"; std::vector > replace; @@ -544,12 +550,13 @@ bool GVNPRE::runOnFunction(Function &F) { VN.clear(); MS.clear(); createdExpressions.clear(); + availableOut.clear(); + anticipatedIn.clear(); std::map > generatedExpressions; std::map > generatedPhis; std::map > generatedTemporaries; - std::map > availableOut; - std::map > anticipatedIn; + DominatorTree &DT = getAnalysis(); @@ -578,7 +585,7 @@ bool GVNPRE::runOnFunction(Function &F) { // If function has no exit blocks, only perform GVN PostDominatorTree &PDT = getAnalysis(); if (PDT[&F.getEntryBlock()] == 0) { - elimination(availableOut); + elimination(); cleanup(); return true; @@ -761,7 +768,7 @@ bool GVNPRE::runOnFunction(Function &F) { for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; ++PI) { - Value *e2 = phi_translate(anticIn, e, *PI, BB); + Value *e2 = phi_translate(e, *PI, BB); Value *e3 = find_leader(availableOut[*PI], e2); if (e3 == 0) { @@ -795,20 +802,14 @@ bool GVNPRE::runOnFunction(Function &F) { Value* s1 = 0; if (isa(U->getOperand(0))) s1 = find_leader(availableOut[*PI], - phi_translate(availableOut[*PI], - U->getOperand(0), - *PI, BB) - ); + phi_translate(U->getOperand(0), *PI, BB)); else s1 = U->getOperand(0); Value* s2 = 0; if (isa(U->getOperand(1))) s2 = find_leader(availableOut[*PI], - phi_translate(availableOut[*PI], - U->getOperand(1), - *PI, BB) - ); + phi_translate(U->getOperand(1), *PI, BB)); else s2 = U->getOperand(1); @@ -891,7 +892,7 @@ bool GVNPRE::runOnFunction(Function &F) { } // Phase 3: Eliminate - elimination(availableOut); + elimination(); // Phase 4: Cleanup cleanup();