Fix test/Transforms/GVNPRE/2007-06-12-PhiTranslate.ll

llvm-svn: 37564
This commit is contained in:
Owen Anderson 2007-06-12 22:43:57 +00:00
parent b1c82db828
commit 4036ad485f
1 changed files with 39 additions and 38 deletions

View File

@ -101,6 +101,9 @@ namespace {
std::set<Value*, ExprLT> MS; std::set<Value*, ExprLT> MS;
std::vector<Instruction*> createdExpressions; std::vector<Instruction*> createdExpressions;
std::map<BasicBlock*, std::set<Value*, ExprLT> > availableOut;
std::map<BasicBlock*, std::set<Value*, ExprLT> > anticipatedIn;
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG(); AU.setPreservesCFG();
AU.addRequired<DominatorTree>(); AU.addRequired<DominatorTree>();
@ -115,8 +118,7 @@ namespace {
bool add(Value* V, uint32_t number); bool add(Value* V, uint32_t number);
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(Value* V, BasicBlock* pred, BasicBlock* succ);
Value* V, BasicBlock* pred, BasicBlock* succ);
void phi_translate_set(std::set<Value*, ExprLT>& anticIn, BasicBlock* pred, void phi_translate_set(std::set<Value*, ExprLT>& anticIn, BasicBlock* pred,
BasicBlock* succ, std::set<Value*, ExprLT>& out); BasicBlock* succ, std::set<Value*, ExprLT>& out);
@ -132,8 +134,7 @@ namespace {
std::set<Value*, ExprLT>& currAvail, std::set<Value*, ExprLT>& currAvail,
std::map<BasicBlock*, std::set<Value*, ExprLT> > availOut); std::map<BasicBlock*, std::set<Value*, ExprLT> > availOut);
void cleanup(); void cleanup();
void elimination(std::map<BasicBlock*, void elimination();
std::set<Value*, ExprLT> >& availOut);
}; };
@ -160,6 +161,9 @@ bool GVNPRE::add(Value* V, uint32_t number) {
} }
Value* GVNPRE::find_leader(std::set<Value*, ExprLT>& vals, Value* v) { Value* GVNPRE::find_leader(std::set<Value*, ExprLT>& vals, Value* v) {
if (!isa<Instruction>(v))
return v;
for (std::set<Value*, ExprLT>::iterator I = vals.begin(), E = vals.end(); for (std::set<Value*, ExprLT>::iterator I = vals.begin(), E = vals.end();
I != E; ++I) { I != E; ++I) {
assert(VN.find(v) != VN.end() && "Value not numbered?"); assert(VN.find(v) != VN.end() && "Value not numbered?");
@ -171,24 +175,23 @@ Value* GVNPRE::find_leader(std::set<Value*, ExprLT>& vals, Value* v) {
return 0; return 0;
} }
Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set, Value* GVNPRE::phi_translate(Value* V, BasicBlock* pred, BasicBlock* succ) {
Value* V, BasicBlock* pred, BasicBlock* succ) {
if (V == 0) if (V == 0)
return 0; return 0;
if (BinaryOperator* BO = dyn_cast<BinaryOperator>(V)) { if (BinaryOperator* BO = dyn_cast<BinaryOperator>(V)) {
Value* newOp1 = isa<Instruction>(BO->getOperand(0)) Value* newOp1 = isa<Instruction>(BO->getOperand(0))
? phi_translate(set, ? phi_translate(
find_leader(set, BO->getOperand(0)), find_leader(anticipatedIn[succ], BO->getOperand(0)),
pred, succ) pred, succ)
: BO->getOperand(0); : BO->getOperand(0);
if (newOp1 == 0) if (newOp1 == 0)
return 0; return 0;
Value* newOp2 = isa<Instruction>(BO->getOperand(1)) Value* newOp2 = isa<Instruction>(BO->getOperand(1))
? phi_translate(set, ? phi_translate(
find_leader(set, BO->getOperand(1)), find_leader(anticipatedIn[succ], BO->getOperand(1)),
pred, succ) pred, succ)
: BO->getOperand(1); : BO->getOperand(1);
if (newOp2 == 0) if (newOp2 == 0)
return 0; return 0;
@ -200,7 +203,9 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
if (add(newVal, nextValueNumber)) if (add(newVal, nextValueNumber))
nextValueNumber++; nextValueNumber++;
if (!find_leader(set, newVal)) {
Value* leader = find_leader(availableOut[pred], newVal);
if (leader == 0) {
DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
createdExpressions.push_back(newVal); createdExpressions.push_back(newVal);
return newVal; return newVal;
@ -214,7 +219,7 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
MS.erase(newVal); MS.erase(newVal);
delete newVal; delete newVal;
return 0; return leader;
} }
} }
} else if (PHINode* P = dyn_cast<PHINode>(V)) { } else if (PHINode* P = dyn_cast<PHINode>(V)) {
@ -222,17 +227,17 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
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(
find_leader(set, C->getOperand(0)), find_leader(anticipatedIn[succ], C->getOperand(0)),
pred, succ) pred, succ)
: C->getOperand(0); : C->getOperand(0);
if (newOp1 == 0) if (newOp1 == 0)
return 0; return 0;
Value* newOp2 = isa<Instruction>(C->getOperand(1)) Value* newOp2 = isa<Instruction>(C->getOperand(1))
? phi_translate(set, ? phi_translate(
find_leader(set, C->getOperand(1)), find_leader(anticipatedIn[succ], C->getOperand(1)),
pred, succ) pred, succ)
: C->getOperand(1); : C->getOperand(1);
if (newOp2 == 0) if (newOp2 == 0)
return 0; return 0;
@ -245,7 +250,9 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
if (add(newVal, nextValueNumber)) if (add(newVal, nextValueNumber))
nextValueNumber++; nextValueNumber++;
if (!find_leader(set, newVal)) {
Value* leader = find_leader(availableOut[pred], newVal);
if (leader == 0) {
DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n"; DOUT << "Creating value: " << std::hex << newVal << std::dec << "\n";
createdExpressions.push_back(newVal); createdExpressions.push_back(newVal);
return newVal; return newVal;
@ -259,7 +266,7 @@ Value* GVNPRE::phi_translate(std::set<Value*, ExprLT>& set,
MS.erase(newVal); MS.erase(newVal);
delete newVal; delete newVal;
return 0; return leader;
} }
} }
} }
@ -272,7 +279,7 @@ void GVNPRE::phi_translate_set(std::set<Value*, ExprLT>& anticIn,
std::set<Value*, ExprLT>& out) { 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, pred, succ); Value* V = phi_translate(*I, pred, succ);
if (V != 0) if (V != 0)
out.insert(V); out.insert(V);
} }
@ -485,8 +492,7 @@ void GVNPRE::CalculateAvailOut(DomTreeNode* DI,
} }
} }
void GVNPRE::elimination(std::map<BasicBlock*, void GVNPRE::elimination() {
std::set<Value*, ExprLT> >& availableOut) {
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;
@ -544,12 +550,13 @@ bool GVNPRE::runOnFunction(Function &F) {
VN.clear(); VN.clear();
MS.clear(); MS.clear();
createdExpressions.clear(); createdExpressions.clear();
availableOut.clear();
anticipatedIn.clear();
std::map<BasicBlock*, std::set<Value*, ExprLT> > generatedExpressions; std::map<BasicBlock*, std::set<Value*, ExprLT> > generatedExpressions;
std::map<BasicBlock*, std::set<PHINode*> > generatedPhis; std::map<BasicBlock*, std::set<PHINode*> > generatedPhis;
std::map<BasicBlock*, std::set<Value*> > generatedTemporaries; std::map<BasicBlock*, std::set<Value*> > generatedTemporaries;
std::map<BasicBlock*, std::set<Value*, ExprLT> > availableOut;
std::map<BasicBlock*, std::set<Value*, ExprLT> > anticipatedIn;
DominatorTree &DT = getAnalysis<DominatorTree>(); DominatorTree &DT = getAnalysis<DominatorTree>();
@ -578,7 +585,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(availableOut); elimination();
cleanup(); cleanup();
return true; return true;
@ -761,7 +768,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, BB); Value *e2 = phi_translate(e, *PI, BB);
Value *e3 = find_leader(availableOut[*PI], e2); Value *e3 = find_leader(availableOut[*PI], e2);
if (e3 == 0) { if (e3 == 0) {
@ -795,20 +802,14 @@ 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], s1 = find_leader(availableOut[*PI],
phi_translate(availableOut[*PI], phi_translate(U->getOperand(0), *PI, BB));
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], s2 = find_leader(availableOut[*PI],
phi_translate(availableOut[*PI], phi_translate(U->getOperand(1), *PI, BB));
U->getOperand(1),
*PI, BB)
);
else else
s2 = U->getOperand(1); s2 = U->getOperand(1);
@ -891,7 +892,7 @@ bool GVNPRE::runOnFunction(Function &F) {
} }
// Phase 3: Eliminate // Phase 3: Eliminate
elimination(availableOut); elimination();
// Phase 4: Cleanup // Phase 4: Cleanup
cleanup(); cleanup();