From 8338ff5ff1819b64845774dc008667a3f05bd082 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 8 Jun 2007 20:44:02 +0000 Subject: [PATCH] Fix a bug that was causing the elimination phase not to replace values when it should be. With this patch, GVN-PRE now correctly optimizes the example from the thesis. Many thanks to Daniel Berlin for helping me find errors in this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37525 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/GVNPRE.cpp | 69 ++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/lib/Transforms/Scalar/GVNPRE.cpp b/lib/Transforms/Scalar/GVNPRE.cpp index db8e7f0634f..ecc3005541e 100644 --- a/lib/Transforms/Scalar/GVNPRE.cpp +++ b/lib/Transforms/Scalar/GVNPRE.cpp @@ -45,7 +45,9 @@ struct ExprLT { BinaryOperator* BO1 = cast(left); BinaryOperator* BO2 = cast(right); - if ((*this)(BO1->getOperand(0), BO2->getOperand(0))) + if (BO1->getOpcode() != BO2->getOpcode()) + return BO1->getOpcode() < BO2->getOpcode(); + else if ((*this)(BO1->getOperand(0), BO2->getOperand(0))) return true; else if ((*this)(BO2->getOperand(0), BO1->getOperand(0))) return false; @@ -158,6 +160,7 @@ Value* GVNPRE::phi_translate(std::set& set, Instruction* newVal = BinaryOperator::create(BO->getOpcode(), newOp1, newOp2, BO->getName()+".gvnpre"); + if (add(newVal, nextValueNumber)) nextValueNumber++; if (!find_leader(set, newVal)) { @@ -165,6 +168,14 @@ Value* GVNPRE::phi_translate(std::set& set, createdExpressions.insert(newVal); return newVal; } else { + ValueTable::iterator I = VN.find(newVal); + if (I->first == newVal) + VN.erase(newVal); + + std::set::iterator F = MS.find(newVal); + if (*F == newVal) + MS.erase(newVal); + delete newVal; return 0; } @@ -486,7 +497,6 @@ bool GVNPRE::runOnFunction(Function &F) { // Phase 2: Insert - DOUT<< "\nPhase 2: Insertion\n"; std::map > new_sets; @@ -503,6 +513,8 @@ bool GVNPRE::runOnFunction(Function &F) { std::set& availOut = availableOut[BB]; std::set& anticIn = anticipatedIn[BB]; + new_set.clear(); + // Replace leaders with leaders inherited from dominator if (DI->getIDom() != 0) { std::set& dom_set = new_sets[DI->getIDom()->getBlock()]; @@ -510,9 +522,11 @@ bool GVNPRE::runOnFunction(Function &F) { E = dom_set.end(); I != E; ++I) { new_set.insert(*I); - std::set::iterator val = availOut.find(*I); - if (val != availOut.end()) + Value* val = find_leader(availOut, *I); + while (val != 0) { availOut.erase(val); + val = find_leader(availOut, *I); + } availOut.insert(*I); } } @@ -589,7 +603,14 @@ bool GVNPRE::runOnFunction(Function &F) { BO->getName()+".gvnpre", (*PI)->getTerminator()); add(newVal, VN[BO]); - availableOut[*PI].insert(newVal); + + std::set& predAvail = availableOut[*PI]; + Value* val = find_leader(predAvail, newVal); + while (val != 0) { + predAvail.erase(val); + val = find_leader(predAvail, newVal); + } + predAvail.insert(newVal); DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; @@ -614,7 +635,13 @@ bool GVNPRE::runOnFunction(Function &F) { add(p, VN[e]); DOUT << "Creating value: " << std::hex << p << std::dec << "\n"; + Value* val = find_leader(availOut, p); + while (val != 0) { + availOut.erase(val); + val = find_leader(availOut, p); + } availOut.insert(p); + new_stuff = true; DOUT << "Preds After Processing: "; @@ -637,30 +664,46 @@ bool GVNPRE::runOnFunction(Function &F) { } // Phase 3: Eliminate + DOUT << "\n\nPhase 3: Elimination\n\n"; + + std::vector > replace; + std::vector erase; + for (df_iterator DI = df_begin(DT.getRootNode()), E = df_end(DT.getRootNode()); DI != E; ++DI) { BasicBlock* BB = DI->getBlock(); - std::vector erase; + DOUT << "Block: " << BB->getName() << "\n"; + dump_unique(availableOut[BB]); + DOUT << "\n\n"; for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) { - if (!BI->isTerminator()) { - Value* leader = find_leader(availableOut[BB], BI); + + if (isa(BI)) { + Value *leader = find_leader(availableOut[BB], BI); + if (leader != 0) if (Instruction* Instr = dyn_cast(leader)) if (Instr->getParent() != 0 && Instr != BI) { - BI->replaceAllUsesWith(leader); + replace.push_back(std::make_pair(BI, leader)); erase.push_back(BI); } } } - - for (std::vector::iterator I = erase.begin(), E = erase.end(); - I != E; ++I) - (*I)->eraseFromParent(); } + while (!replace.empty()) { + std::pair rep = replace.back(); + replace.pop_back(); + + rep.first->replaceAllUsesWith(rep.second); + } + + for (std::vector::iterator I = erase.begin(), E = erase.end(); + I != E; ++I) + (*I)->eraseFromParent(); + // Phase 4: Cleanup for (std::set::iterator I = createdExpressions.begin(), E = createdExpressions.end(); I != E; ++I) {