mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-13 04:24:40 +00:00
Make phi_translate correct.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37418 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -78,7 +78,10 @@ namespace {
|
|||||||
void clean(ValueTable VN, std::set<Value*, ExprLT>& set);
|
void clean(ValueTable VN, std::set<Value*, ExprLT>& set);
|
||||||
bool add(ValueTable& VN, std::set<Value*, ExprLT>& MS, Value* V);
|
bool add(ValueTable& VN, std::set<Value*, ExprLT>& MS, Value* V);
|
||||||
Value* find_leader(ValueTable VN, std::set<Value*, ExprLT>& vals, uint32_t v);
|
Value* find_leader(ValueTable VN, std::set<Value*, ExprLT>& vals, uint32_t v);
|
||||||
void phi_translate(ValueTable& VN, std::set<Value*, ExprLT>& MS,
|
Value* phi_translate(ValueTable& VN, std::set<Value*, ExprLT>& MS,
|
||||||
|
std::set<Value*, ExprLT>& set,
|
||||||
|
Value* V, BasicBlock* pred);
|
||||||
|
void phi_translate_set(ValueTable& VN, std::set<Value*, ExprLT>& MS,
|
||||||
std::set<Value*, ExprLT>& anticIn, BasicBlock* B,
|
std::set<Value*, ExprLT>& anticIn, BasicBlock* B,
|
||||||
std::set<Value*, ExprLT>& out);
|
std::set<Value*, ExprLT>& out);
|
||||||
|
|
||||||
@ -128,53 +131,52 @@ Value* GVNPRE::find_leader(GVNPRE::ValueTable VN,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GVNPRE::phi_translate(GVNPRE::ValueTable& VN,
|
Value* GVNPRE::phi_translate(ValueTable& VN, std::set<Value*, ExprLT>& MS,
|
||||||
|
std::set<Value*, ExprLT>& set,
|
||||||
|
Value* V, BasicBlock* pred) {
|
||||||
|
if (V == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (BinaryOperator* BO = dyn_cast<BinaryOperator>(V)) {
|
||||||
|
Value* newOp1 = phi_translate(VN, MS, set,
|
||||||
|
find_leader(VN, set, VN[BO->getOperand(0)]),
|
||||||
|
pred);
|
||||||
|
if (newOp1 == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Value* newOp2 = phi_translate(VN, MS, set,
|
||||||
|
find_leader(VN, set, VN[BO->getOperand(1)]),
|
||||||
|
pred);
|
||||||
|
if (newOp2 == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (newOp1 != BO->getOperand(0) || newOp2 != BO->getOperand(1)) {
|
||||||
|
Value* newVal = BinaryOperator::create(BO->getOpcode(),
|
||||||
|
newOp1, newOp2,
|
||||||
|
BO->getName()+".gvnpre");
|
||||||
|
add(VN, MS, newVal);
|
||||||
|
if (!find_leader(VN, set, VN[newVal]))
|
||||||
|
return newVal;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else if (PHINode* P = dyn_cast<PHINode>(V)) {
|
||||||
|
if (P->getParent() == pred->getTerminator()->getSuccessor(0))
|
||||||
|
return P->getIncomingValueForBlock(pred);
|
||||||
|
}
|
||||||
|
|
||||||
|
return V;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GVNPRE::phi_translate_set(GVNPRE::ValueTable& VN,
|
||||||
std::set<Value*, ExprLT>& MS,
|
std::set<Value*, ExprLT>& MS,
|
||||||
std::set<Value*, ExprLT>& anticIn, BasicBlock* B,
|
std::set<Value*, ExprLT>& anticIn, BasicBlock* B,
|
||||||
std::set<Value*, ExprLT>& out) {
|
std::set<Value*, ExprLT>& out) {
|
||||||
BasicBlock* succ = B->getTerminator()->getSuccessor(0);
|
for (std::set<Value*, ExprLT>::iterator I = anticIn.begin(),
|
||||||
|
E = anticIn.end(); I != E; ++I) {
|
||||||
for (std::set<Value*, ExprLT>::iterator I = anticIn.begin(), E = anticIn.end();
|
Value* V = phi_translate(VN, MS, anticIn, *I, B);
|
||||||
I != E; ++I) {
|
if (V != 0)
|
||||||
if (!isa<BinaryOperator>(*I)) {
|
out.insert(V);
|
||||||
if (PHINode* p = dyn_cast<PHINode>(*I)) {
|
|
||||||
if (p->getParent() == succ)
|
|
||||||
out.insert(p);
|
|
||||||
} else {
|
|
||||||
out.insert(*I);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
BinaryOperator* BO = cast<BinaryOperator>(*I);
|
|
||||||
Value* lhs = find_leader(VN, anticIn, VN[BO->getOperand(0)]);
|
|
||||||
if (lhs == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (PHINode* p = dyn_cast<PHINode>(lhs))
|
|
||||||
if (p->getParent() == succ) {
|
|
||||||
lhs = p->getIncomingValueForBlock(B);
|
|
||||||
out.insert(lhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* rhs = find_leader(VN, anticIn, VN[BO->getOperand(1)]);
|
|
||||||
if (rhs == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (PHINode* p = dyn_cast<PHINode>(rhs))
|
|
||||||
if (p->getParent() == succ) {
|
|
||||||
rhs = p->getIncomingValueForBlock(B);
|
|
||||||
out.insert(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lhs != BO->getOperand(0) || rhs != BO->getOperand(1)) {
|
|
||||||
BO = BinaryOperator::create(BO->getOpcode(), lhs, rhs, BO->getName()+".gvnpre");
|
|
||||||
if (VN.insert(std::make_pair(BO, nextValueNumber)).second)
|
|
||||||
nextValueNumber++;
|
|
||||||
MS.insert(BO);
|
|
||||||
}
|
|
||||||
|
|
||||||
out.insert(BO);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,9 +373,9 @@ bool GVNPRE::runOnFunction(Function &F) {
|
|||||||
|
|
||||||
if (BB->getTerminator()->getNumSuccessors() == 1) {
|
if (BB->getTerminator()->getNumSuccessors() == 1) {
|
||||||
if (visited.find(BB) == visited.end())
|
if (visited.find(BB) == visited.end())
|
||||||
phi_translate(VN, maximalSet, anticIn, BB, anticOut);
|
phi_translate_set(VN, maximalSet, anticIn, BB, anticOut);
|
||||||
else
|
else
|
||||||
phi_translate(VN, anticIn, anticIn, BB, anticOut);
|
phi_translate_set(VN, anticIn, anticIn, BB, anticOut);
|
||||||
} else if (BB->getTerminator()->getNumSuccessors() > 1) {
|
} else if (BB->getTerminator()->getNumSuccessors() > 1) {
|
||||||
for (unsigned i = 0; i < BB->getTerminator()->getNumSuccessors(); ++i) {
|
for (unsigned i = 0; i < BB->getTerminator()->getNumSuccessors(); ++i) {
|
||||||
BasicBlock* currSucc = BB->getTerminator()->getSuccessor(i);
|
BasicBlock* currSucc = BB->getTerminator()->getSuccessor(i);
|
||||||
@ -419,6 +421,7 @@ bool GVNPRE::runOnFunction(Function &F) {
|
|||||||
|
|
||||||
anticOut.clear();
|
anticOut.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
iterations++;
|
iterations++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user