[llvm-commits] CVS: llvm/lib/Transforms/Scalar/GVNPRE.cpp
Owen Anderson
resistor at mac.com
Fri Jun 8 13:44:24 PDT 2007
Changes in directory llvm/lib/Transforms/Scalar:
GVNPRE.cpp updated: 1.24 -> 1.25
---
Log message:
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.
---
Diffs of the changes: (+56 -13)
GVNPRE.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 56 insertions(+), 13 deletions(-)
Index: llvm/lib/Transforms/Scalar/GVNPRE.cpp
diff -u llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.24 llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.25
--- llvm/lib/Transforms/Scalar/GVNPRE.cpp:1.24 Thu Jun 7 20:52:45 2007
+++ llvm/lib/Transforms/Scalar/GVNPRE.cpp Fri Jun 8 15:44:02 2007
@@ -45,7 +45,9 @@
BinaryOperator* BO1 = cast<BinaryOperator>(left);
BinaryOperator* BO2 = cast<BinaryOperator>(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 @@
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 @@
createdExpressions.insert(newVal);
return newVal;
} else {
+ ValueTable::iterator I = VN.find(newVal);
+ if (I->first == newVal)
+ VN.erase(newVal);
+
+ std::set<Value*, ExprLT>::iterator F = MS.find(newVal);
+ if (*F == newVal)
+ MS.erase(newVal);
+
delete newVal;
return 0;
}
@@ -486,7 +497,6 @@
// Phase 2: Insert
-
DOUT<< "\nPhase 2: Insertion\n";
std::map<BasicBlock*, std::set<Value*, ExprLT> > new_sets;
@@ -503,6 +513,8 @@
std::set<Value*, ExprLT>& availOut = availableOut[BB];
std::set<Value*, ExprLT>& anticIn = anticipatedIn[BB];
+ new_set.clear();
+
// Replace leaders with leaders inherited from dominator
if (DI->getIDom() != 0) {
std::set<Value*, ExprLT>& dom_set = new_sets[DI->getIDom()->getBlock()];
@@ -510,9 +522,11 @@
E = dom_set.end(); I != E; ++I) {
new_set.insert(*I);
- std::set<Value*, ExprLT>::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 @@
BO->getName()+".gvnpre",
(*PI)->getTerminator());
add(newVal, VN[BO]);
- availableOut[*PI].insert(newVal);
+
+ std::set<Value*, ExprLT>& 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 @@
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 @@
}
// Phase 3: Eliminate
+ DOUT << "\n\nPhase 3: Elimination\n\n";
+
+ std::vector<std::pair<Instruction*, Value*> > replace;
+ std::vector<Instruction*> erase;
+
for (df_iterator<DomTreeNode*> DI = df_begin(DT.getRootNode()),
E = df_end(DT.getRootNode()); DI != E; ++DI) {
BasicBlock* BB = DI->getBlock();
- std::vector<Instruction*> 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<BinaryOperator>(BI)) {
+ Value *leader = find_leader(availableOut[BB], BI);
+
if (leader != 0)
if (Instruction* Instr = dyn_cast<Instruction>(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<Instruction*>::iterator I = erase.begin(), E = erase.end();
- I != E; ++I)
- (*I)->eraseFromParent();
}
+ while (!replace.empty()) {
+ std::pair<Instruction*, Value*> rep = replace.back();
+ replace.pop_back();
+
+ rep.first->replaceAllUsesWith(rep.second);
+ }
+
+ for (std::vector<Instruction*>::iterator I = erase.begin(), E = erase.end();
+ I != E; ++I)
+ (*I)->eraseFromParent();
+
// Phase 4: Cleanup
for (std::set<Instruction*>::iterator I = createdExpressions.begin(),
E = createdExpressions.end(); I != E; ++I) {
More information about the llvm-commits
mailing list