diff --git a/lib/Transforms/Scalar/GVNPRE.cpp b/lib/Transforms/Scalar/GVNPRE.cpp index 131976bb108..f672cbbbfa7 100644 --- a/lib/Transforms/Scalar/GVNPRE.cpp +++ b/lib/Transforms/Scalar/GVNPRE.cpp @@ -90,9 +90,9 @@ namespace { return true; } }; - + typedef std::map ValueTable; - + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); @@ -109,7 +109,7 @@ namespace { std::set::iterator find_leader(ValueTable VN, std::set& vals, uint32_t v); - void phi_translate(ValueTable& VN, + void phi_translate(ValueTable& VN, std::set& MS, std::set& anticIn, BasicBlock* B, std::set& out); @@ -232,7 +232,8 @@ std::set::iterator GVNPRE::find_leader(GVNPRE::ValueTable VN return vals.end(); } -void GVNPRE::phi_translate(GVNPRE::ValueTable& VN, +void GVNPRE::phi_translate(GVNPRE::ValueTable& VN, + std::set& MS, std::set& anticIn, BasicBlock* B, std::set& out) { BasicBlock* succ = B->getTerminator()->getSuccessor(0); @@ -241,13 +242,57 @@ void GVNPRE::phi_translate(GVNPRE::ValueTable& VN, I != E; ++I) { if (I->opcode == 0) { Value *v = I->value; - if (PHINode* p = dyn_cast(v)) - if (p->getParent() == succ) { + if (PHINode* p = dyn_cast(v)) { + if (p->getParent() == succ) out.insert(buildExpression(VN, p->getIncomingValueForBlock(B))); - continue; - } + } else { + out.insert(*I); + } + } else { + std::set::iterator lhs_it = find_leader(VN, anticIn, I->lhs); + if (lhs_it == anticIn.end()) + continue; + + Expression lhs = *lhs_it; + if (lhs.value != 0) + if (PHINode* p = dyn_cast(lhs.value)) + if (p->getParent() == succ) { + Expression t = buildExpression(VN, p->getIncomingValueForBlock(B)); + lhs.opcode = t.opcode; + lhs.value = t.value; + lhs.lhs = t.lhs; + lhs.rhs = t.rhs; + + out.insert(t); + } + + std::set::iterator rhs_it = find_leader(VN, anticIn, I->rhs); + if (rhs_it == anticIn.end()) + continue; + + Expression rhs = *rhs_it; + if (rhs.value != 0) + if (PHINode* p = dyn_cast(rhs.value)) + if (p->getParent() == succ) { + Expression t = buildExpression(VN, p->getIncomingValueForBlock(B)); + rhs.opcode = t.opcode; + rhs.value = t.value; + rhs.lhs = t.lhs; + rhs.rhs = t.rhs; + + out.insert(t); + } + + Expression e; + e.opcode = I->opcode; + e.value = 0; + e.lhs = VN[lhs]; + e.rhs = VN[rhs]; + + if (VN.insert(std::make_pair(e, nextValueNumber)).second) + nextValueNumber++; + MS.insert(e); } - //out.insert(*I); } } @@ -290,7 +335,9 @@ void GVNPRE::clean(GVNPRE::ValueTable VN, std::set& set) { void GVNPRE::dump(GVNPRE::ValueTable& VN, std::set& s) { DOUT << "{ "; for (std::set::iterator I = s.begin(), E = s.end(); I != E; ++I) { - DOUT << "( " << I->opcode << ", " + DOUT << "( "; + DOUT << I->opcode+48; + DOUT << ", " << (I->value == 0 ? "0" : I->value->getName().c_str()) << ", value." << I->lhs << ", value." << I->rhs << " ) "; } @@ -396,7 +443,10 @@ bool GVNPRE::runOnFunction(Function &F) { std::set old (anticIn.begin(), anticIn.end()); if (BB->getTerminator()->getNumSuccessors() == 1) { - phi_translate(VN, maximalSet, BB, anticOut); + if (visited.find(BB) == visited.end()) + phi_translate(VN, maximalSet, anticIn, BB, anticOut); + else + phi_translate(VN, anticIn, anticIn, BB, anticOut); } else if (BB->getTerminator()->getNumSuccessors() > 1) { for (unsigned i = 0; i < BB->getTerminator()->getNumSuccessors(); ++i) { BasicBlock* currSucc = BB->getTerminator()->getSuccessor(i);