mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-05 02:07:16 +00:00
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
This commit is contained in:
parent
2acdbcccd8
commit
8338ff5ff1
@ -45,7 +45,9 @@ struct ExprLT {
|
||||
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 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& 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<Value*, ExprLT>& set,
|
||||
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 @@ bool GVNPRE::runOnFunction(Function &F) {
|
||||
|
||||
|
||||
// Phase 2: Insert
|
||||
|
||||
DOUT<< "\nPhase 2: Insertion\n";
|
||||
|
||||
std::map<BasicBlock*, std::set<Value*, ExprLT> > new_sets;
|
||||
@ -503,6 +513,8 @@ bool GVNPRE::runOnFunction(Function &F) {
|
||||
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 @@ bool GVNPRE::runOnFunction(Function &F) {
|
||||
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 @@ bool GVNPRE::runOnFunction(Function &F) {
|
||||
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 @@ 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<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) {
|
||||
|
Loading…
Reference in New Issue
Block a user