Make GVNPRE accurate report whether it modified the function or not.

llvm-svn: 37673
This commit is contained in:
Owen Anderson 2007-06-20 18:30:20 +00:00
parent d9dca9363c
commit 58265d2391

@ -351,7 +351,7 @@ namespace {
// For a given block, calculate the generated expressions, temporaries, // For a given block, calculate the generated expressions, temporaries,
// and the AVAIL_OUT set // and the AVAIL_OUT set
void cleanup(); void cleanup();
void elimination(); void elimination(bool& changed_function);
void val_insert(std::set<Value*>& s, Value* v); void val_insert(std::set<Value*>& s, Value* v);
void val_replace(std::set<Value*>& s, Value* v); void val_replace(std::set<Value*>& s, Value* v);
@ -656,7 +656,7 @@ void GVNPRE::dump(const std::set<Value*>& s) const {
DOUT << "}\n\n"; DOUT << "}\n\n";
} }
void GVNPRE::elimination() { void GVNPRE::elimination(bool& changed_function) {
DOUT << "\n\nPhase 3: Elimination\n\n"; DOUT << "\n\nPhase 3: Elimination\n\n";
std::vector<std::pair<Instruction*, Value*> > replace; std::vector<std::pair<Instruction*, Value*> > replace;
@ -693,6 +693,7 @@ void GVNPRE::elimination() {
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);
changed_function = true;
} }
for (std::vector<Instruction*>::iterator I = erase.begin(), E = erase.end(); for (std::vector<Instruction*>::iterator I = erase.begin(), E = erase.end();
@ -716,6 +717,8 @@ bool GVNPRE::runOnFunction(Function &F) {
availableOut.clear(); availableOut.clear();
anticipatedIn.clear(); anticipatedIn.clear();
invokeDep.clear(); invokeDep.clear();
bool changed_function = false;
std::map<BasicBlock*, std::set<Value*> > generatedExpressions; std::map<BasicBlock*, std::set<Value*> > generatedExpressions;
std::map<BasicBlock*, std::set<PHINode*> > generatedPhis; std::map<BasicBlock*, std::set<PHINode*> > generatedPhis;
@ -798,7 +801,7 @@ bool GVNPRE::runOnFunction(Function &F) {
// If function has no exit blocks, only perform GVN // If function has no exit blocks, only perform GVN
PostDominatorTree &PDT = getAnalysis<PostDominatorTree>(); PostDominatorTree &PDT = getAnalysis<PostDominatorTree>();
if (PDT[&F.getEntryBlock()] == 0) { if (PDT[&F.getEntryBlock()] == 0) {
elimination(); elimination(changed_function);
cleanup(); cleanup();
return true; return true;
@ -1049,6 +1052,8 @@ bool GVNPRE::runOnFunction(Function &F) {
C->getName()+".gvnpre", C->getName()+".gvnpre",
(*PI)->getTerminator()); (*PI)->getTerminator());
changed_function = true;
VN.add(newVal, VN.lookup(U)); VN.add(newVal, VN.lookup(U));
std::set<Value*>& predAvail = availableOut[*PI]; std::set<Value*>& predAvail = availableOut[*PI];
@ -1076,6 +1081,8 @@ bool GVNPRE::runOnFunction(Function &F) {
p->addIncoming(avail[*PI], *PI); p->addIncoming(avail[*PI], *PI);
} }
changed_function = true;
VN.add(p, VN.lookup(e)); VN.add(p, VN.lookup(e));
DOUT << "Creating value: " << std::hex << p << std::dec << "\n"; DOUT << "Creating value: " << std::hex << p << std::dec << "\n";
@ -1106,10 +1113,10 @@ bool GVNPRE::runOnFunction(Function &F) {
} }
// Phase 3: Eliminate // Phase 3: Eliminate
elimination(); elimination(changed_function);
// Phase 4: Cleanup // Phase 4: Cleanup
cleanup(); cleanup();
return true; return changed_function;
} }