Fix a few more bugs, including an instance of walking in reverse topological rather than topological order. This

fixes a testcase extracted from llvm-test.

llvm-svn: 37550
This commit is contained in:
Owen Anderson 2007-06-12 00:50:47 +00:00
parent ee35eab57f
commit a75dd4dc56
1 changed files with 49 additions and 31 deletions

View File

@ -43,14 +43,21 @@ struct ExprLT {
if (BinaryOperator* rightBO = dyn_cast<BinaryOperator>(right)) if (BinaryOperator* rightBO = dyn_cast<BinaryOperator>(right))
return cmpBinaryOperator(leftBO, rightBO); return cmpBinaryOperator(leftBO, rightBO);
else else
return left < right; if (isa<CmpInst>(right)) {
return false;
} else {
return true;
}
} else if (CmpInst* leftCmp = dyn_cast<CmpInst>(left)) { } else if (CmpInst* leftCmp = dyn_cast<CmpInst>(left)) {
if (CmpInst* rightCmp = dyn_cast<CmpInst>(right)) if (CmpInst* rightCmp = dyn_cast<CmpInst>(right))
return cmpComparison(leftCmp, rightCmp); return cmpComparison(leftCmp, rightCmp);
else else
return left < right; return true;
} else { } else {
return left < right; if (isa<BinaryOperator>(right) || isa<CmpInst>(right))
return false;
else
return left < right;
} }
} }
@ -92,7 +99,7 @@ namespace {
typedef std::map<Value*, uint32_t, ExprLT> ValueTable; typedef std::map<Value*, uint32_t, ExprLT> ValueTable;
ValueTable VN; ValueTable VN;
std::set<Value*, ExprLT> MS; std::set<Value*, ExprLT> MS;
std::set<Instruction*> createdExpressions; std::vector<Instruction*> createdExpressions;
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG(); AU.setPreservesCFG();
@ -109,9 +116,9 @@ namespace {
Value* find_leader(std::set<Value*, ExprLT>& vals, Value* find_leader(std::set<Value*, ExprLT>& vals,
Value* v); Value* v);
Value* phi_translate(std::set<Value*, ExprLT>& set, Value* phi_translate(std::set<Value*, ExprLT>& set,
Value* V, BasicBlock* pred); Value* V, BasicBlock* pred, BasicBlock* succ);
void phi_translate_set(std::set<Value*, ExprLT>& anticIn, BasicBlock* B, void phi_translate_set(std::set<Value*, ExprLT>& anticIn, BasicBlock* pred,
std::set<Value*, ExprLT>& out); BasicBlock* succ, std::set<Value*, ExprLT>& out);
void topo_sort(std::set<Value*, ExprLT>& set, void topo_sort(std::set<Value*, ExprLT>& set,
std::vector<Value*>& vec); std::vector<Value*>& vec);
@ -162,7 +169,7 @@ Value* GVNPRE::find_leader(std::set<Value*, ExprLT>& vals, Value* v) {
} }
Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set, Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
Value* V, BasicBlock* pred) { Value* V, BasicBlock* pred, BasicBlock* succ) {
if (V == 0) if (V == 0)
return 0; return 0;
@ -170,7 +177,7 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
Value* newOp1 = isa<Instruction>(BO->getOperand(0)) Value* newOp1 = isa<Instruction>(BO->getOperand(0))
? phi_translate(set, ? phi_translate(set,
find_leader(set, BO->getOperand(0)), find_leader(set, BO->getOperand(0)),
pred) pred, succ)
: BO->getOperand(0); : BO->getOperand(0);
if (newOp1 == 0) if (newOp1 == 0)
return 0; return 0;
@ -178,7 +185,7 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
Value* newOp2 = isa<Instruction>(BO->getOperand(1)) Value* newOp2 = isa<Instruction>(BO->getOperand(1))
? phi_translate(set, ? phi_translate(set,
find_leader(set, BO->getOperand(1)), find_leader(set, BO->getOperand(1)),
pred) pred, succ)
: BO->getOperand(1); : BO->getOperand(1);
if (newOp2 == 0) if (newOp2 == 0)
return 0; return 0;
@ -192,7 +199,7 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
nextValueNumber++; nextValueNumber++;
if (!find_leader(set, newVal)) { if (!find_leader(set, newVal)) {
DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
createdExpressions.insert(newVal); createdExpressions.push_back(newVal);
return newVal; return newVal;
} else { } else {
ValueTable::iterator I = VN.find(newVal); ValueTable::iterator I = VN.find(newVal);
@ -208,13 +215,13 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
} }
} }
} else if (PHINode* P = dyn_cast<PHINode>(V)) { } else if (PHINode* P = dyn_cast<PHINode>(V)) {
if (P->getParent() == pred->getTerminator()->getSuccessor(0)) if (P->getParent() == succ)
return P->getIncomingValueForBlock(pred); return P->getIncomingValueForBlock(pred);
} else if (CmpInst* C = dyn_cast<CmpInst>(V)) { } else if (CmpInst* C = dyn_cast<CmpInst>(V)) {
Value* newOp1 = isa<Instruction>(C->getOperand(0)) Value* newOp1 = isa<Instruction>(C->getOperand(0))
? phi_translate(set, ? phi_translate(set,
find_leader(set, C->getOperand(0)), find_leader(set, C->getOperand(0)),
pred) pred, succ)
: C->getOperand(0); : C->getOperand(0);
if (newOp1 == 0) if (newOp1 == 0)
return 0; return 0;
@ -222,7 +229,7 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
Value* newOp2 = isa<Instruction>(C->getOperand(1)) Value* newOp2 = isa<Instruction>(C->getOperand(1))
? phi_translate(set, ? phi_translate(set,
find_leader(set, C->getOperand(1)), find_leader(set, C->getOperand(1)),
pred) pred, succ)
: C->getOperand(1); : C->getOperand(1);
if (newOp2 == 0) if (newOp2 == 0)
return 0; return 0;
@ -237,7 +244,7 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
nextValueNumber++; nextValueNumber++;
if (!find_leader(set, newVal)) { if (!find_leader(set, newVal)) {
DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
createdExpressions.insert(newVal); createdExpressions.push_back(newVal);
return newVal; return newVal;
} else { } else {
ValueTable::iterator I = VN.find(newVal); ValueTable::iterator I = VN.find(newVal);
@ -257,11 +264,12 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
return V; return V;
} }
void GVNPRE::phi_translate_set(std::set<Value*, ExprLT>& anticIn, BasicBlock* B, void GVNPRE::phi_translate_set(std::set<Value*, ExprLT>& anticIn,
std::set<Value*, ExprLT>& out) { BasicBlock* pred, BasicBlock* succ,
std::set<Value*, ExprLT>& out) {
for (std::set<Value*, ExprLT>::iterator I = anticIn.begin(), for (std::set<Value*, ExprLT>::iterator I = anticIn.begin(),
E = anticIn.end(); I != E; ++I) { E = anticIn.end(); I != E; ++I) {
Value* V = phi_translate(anticIn, *I, B); Value* V = phi_translate(anticIn, *I, pred, succ);
if (V != 0) if (V != 0)
out.insert(V); out.insert(V);
} }
@ -544,10 +552,12 @@ bool GVNPRE::runOnFunction(Function &F) {
if (BB->getTerminator()->getNumSuccessors() == 1) { if (BB->getTerminator()->getNumSuccessors() == 1) {
if (visited.find(BB->getTerminator()->getSuccessor(0)) == if (visited.find(BB->getTerminator()->getSuccessor(0)) ==
visited.end()) visited.end())
phi_translate_set(MS, BB, anticOut); phi_translate_set(MS, BB, BB->getTerminator()->getSuccessor(0),
anticOut);
else else
phi_translate_set( phi_translate_set(anticipatedIn[BB->getTerminator()->getSuccessor(0)],
anticipatedIn[BB->getTerminator()->getSuccessor(0)], BB, anticOut); BB, BB->getTerminator()->getSuccessor(0),
anticOut);
} else if (BB->getTerminator()->getNumSuccessors() > 1) { } else if (BB->getTerminator()->getNumSuccessors() > 1) {
BasicBlock* first = BB->getTerminator()->getSuccessor(0); BasicBlock* first = BB->getTerminator()->getSuccessor(0);
anticOut.insert(anticipatedIn[first].begin(), anticOut.insert(anticipatedIn[first].begin(),
@ -673,9 +683,8 @@ bool GVNPRE::runOnFunction(Function &F) {
dump_unique(anticIn); dump_unique(anticIn);
DOUT << "\n"; DOUT << "\n";
while (!workList.empty()) { for (unsigned i = 0; i < workList.size(); ++i) {
Value* e = workList.back(); Value* e = workList[i];
workList.pop_back();
if (isa<BinaryOperator>(e) || isa<CmpInst>(e)) { if (isa<BinaryOperator>(e) || isa<CmpInst>(e)) {
if (find_leader(availableOut[DI->getIDom()->getBlock()], e) != 0) if (find_leader(availableOut[DI->getIDom()->getBlock()], e) != 0)
@ -687,7 +696,7 @@ bool GVNPRE::runOnFunction(Function &F) {
for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE; for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB); PI != PE;
++PI) { ++PI) {
Value *e2 = phi_translate(anticIn, e, *PI); Value *e2 = phi_translate(anticIn, e, *PI, BB);
Value *e3 = find_leader(availableOut[*PI], e2); Value *e3 = find_leader(availableOut[*PI], e2);
if (e3 == 0) { if (e3 == 0) {
@ -720,13 +729,21 @@ bool GVNPRE::runOnFunction(Function &F) {
Value* s1 = 0; Value* s1 = 0;
if (isa<Instruction>(U->getOperand(0))) if (isa<Instruction>(U->getOperand(0)))
s1 = find_leader(availableOut[*PI], U->getOperand(0)); s1 = find_leader(availableOut[*PI],
phi_translate(availableOut[*PI],
U->getOperand(0),
*PI, BB)
);
else else
s1 = U->getOperand(0); s1 = U->getOperand(0);
Value* s2 = 0; Value* s2 = 0;
if (isa<Instruction>(U->getOperand(1))) if (isa<Instruction>(U->getOperand(1)))
s2 = find_leader(availableOut[*PI], U->getOperand(1)); s2 = find_leader(availableOut[*PI],
phi_translate(availableOut[*PI],
U->getOperand(1),
*PI, BB)
);
else else
s2 = U->getOperand(1); s2 = U->getOperand(1);
@ -842,7 +859,6 @@ bool GVNPRE::runOnFunction(Function &F) {
while (!replace.empty()) { while (!replace.empty()) {
std::pair<Instruction*, Value*> rep = replace.back(); std::pair<Instruction*, Value*> rep = replace.back();
replace.pop_back(); replace.pop_back();
rep.first->replaceAllUsesWith(rep.second); rep.first->replaceAllUsesWith(rep.second);
} }
@ -851,9 +867,11 @@ bool GVNPRE::runOnFunction(Function &F) {
(*I)->eraseFromParent(); (*I)->eraseFromParent();
// Phase 4: Cleanup // Phase 4: Cleanup
for (std::set<Instruction*>::iterator I = createdExpressions.begin(), while (!createdExpressions.empty()) {
E = createdExpressions.end(); I != E; ++I) { Instruction* I = createdExpressions.back();
delete *I; createdExpressions.pop_back();
delete I;
} }
return false; return false;