mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-15 00:38:42 +00:00
Do not mark obviously unreachable blocks live when processing PHI nodes,
and handle incomplete control dependences correctly. This fixes: Regression/Transforms/ADCE/dead-phi-edge.ll -> a missed optimization Regression/Transforms/ADCE/dead-phi-edge.ll -> a compiler crash distilled from QT4 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20227 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ae02b723bf
commit
1a84bd38ef
@ -253,7 +253,7 @@ bool ADCE::doADCE() {
|
|||||||
// function which unwinds, exits or has side-effects, we don't want to delete
|
// function which unwinds, exits or has side-effects, we don't want to delete
|
||||||
// the infinite loop or those blocks leading up to it.
|
// the infinite loop or those blocks leading up to it.
|
||||||
for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
|
for (Function::iterator I = Func->begin(), E = Func->end(); I != E; ++I)
|
||||||
if (DT[I] == 0)
|
if (DT[I] == 0 && ReachableBBs.count(I))
|
||||||
for (pred_iterator PI = pred_begin(I), E = pred_end(I); PI != E; ++PI)
|
for (pred_iterator PI = pred_begin(I), E = pred_end(I); PI != E; ++PI)
|
||||||
markInstructionLive((*PI)->getTerminator());
|
markInstructionLive((*PI)->getTerminator());
|
||||||
|
|
||||||
@ -281,11 +281,21 @@ bool ADCE::doADCE() {
|
|||||||
// defined in the predecessor nodes of this block, meaning that the PHI
|
// defined in the predecessor nodes of this block, meaning that the PHI
|
||||||
// makes the predecessors alive.
|
// makes the predecessors alive.
|
||||||
//
|
//
|
||||||
if (PHINode *PN = dyn_cast<PHINode>(I))
|
if (PHINode *PN = dyn_cast<PHINode>(I)) {
|
||||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
|
||||||
if (AliveBlocks.insert(PN->getIncomingBlock(i)).second)
|
// If the incoming edge is clearly dead, it won't have control
|
||||||
|
// dependence information. Do not mark it live.
|
||||||
|
BasicBlock *PredBB = PN->getIncomingBlock(i);
|
||||||
|
if (ReachableBBs.count(PredBB)) {
|
||||||
|
// FIXME: This should mark the control dependent edge as live, not
|
||||||
|
// necessarily the predecessor itself!
|
||||||
|
if (AliveBlocks.insert(PredBB).second)
|
||||||
markBlockAlive(PN->getIncomingBlock(i)); // Block is newly ALIVE!
|
markBlockAlive(PN->getIncomingBlock(i)); // Block is newly ALIVE!
|
||||||
|
if (Instruction *Op = dyn_cast<Instruction>(PN->getIncomingValue(i)))
|
||||||
|
markInstructionLive(Op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Loop over all of the operands of the live instruction, making sure that
|
// Loop over all of the operands of the live instruction, making sure that
|
||||||
// they are known to be alive as well.
|
// they are known to be alive as well.
|
||||||
//
|
//
|
||||||
@ -293,6 +303,7 @@ bool ADCE::doADCE() {
|
|||||||
if (Instruction *Operand = dyn_cast<Instruction>(I->getOperand(op)))
|
if (Instruction *Operand = dyn_cast<Instruction>(I->getOperand(op)))
|
||||||
markInstructionLive(Operand);
|
markInstructionLive(Operand);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG(
|
DEBUG(
|
||||||
std::cerr << "Current Function: X = Live\n";
|
std::cerr << "Current Function: X = Live\n";
|
||||||
@ -359,7 +370,7 @@ bool ADCE::doADCE() {
|
|||||||
|
|
||||||
// Loop over all of the successors, looking for ones that are not alive.
|
// Loop over all of the successors, looking for ones that are not alive.
|
||||||
// We cannot save the number of successors in the terminator instruction
|
// We cannot save the number of successors in the terminator instruction
|
||||||
// here because we may remove them if we don't have a postdominator...
|
// here because we may remove them if we don't have a postdominator.
|
||||||
//
|
//
|
||||||
for (unsigned i = 0; i != TI->getNumSuccessors(); ++i)
|
for (unsigned i = 0; i != TI->getNumSuccessors(); ++i)
|
||||||
if (!AliveBlocks.count(TI->getSuccessor(i))) {
|
if (!AliveBlocks.count(TI->getSuccessor(i))) {
|
||||||
@ -368,39 +379,49 @@ bool ADCE::doADCE() {
|
|||||||
// dead...
|
// dead...
|
||||||
//
|
//
|
||||||
PostDominatorTree::Node *LastNode = DT[TI->getSuccessor(i)];
|
PostDominatorTree::Node *LastNode = DT[TI->getSuccessor(i)];
|
||||||
|
PostDominatorTree::Node *NextNode = 0;
|
||||||
|
|
||||||
|
if (LastNode) {
|
||||||
|
NextNode = LastNode->getIDom();
|
||||||
|
while (!AliveBlocks.count(NextNode->getBlock())) {
|
||||||
|
LastNode = NextNode;
|
||||||
|
NextNode = NextNode->getIDom();
|
||||||
|
if (NextNode == 0) {
|
||||||
|
LastNode = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// There is a special case here... if there IS no post-dominator for
|
// There is a special case here... if there IS no post-dominator for
|
||||||
// the block we have no owhere to point our branch to. Instead,
|
// the block we have nowhere to point our branch to. Instead, convert
|
||||||
// convert it to a return. This can only happen if the code branched
|
// it to a return. This can only happen if the code branched into an
|
||||||
// into an infinite loop. Note that this may not be desirable,
|
// infinite loop. Note that this may not be desirable, because we
|
||||||
// because we _are_ altering the behavior of the code. This is a well
|
// _are_ altering the behavior of the code. This is a well known
|
||||||
// known drawback of ADCE, so in the future if we choose to revisit
|
// drawback of ADCE, so in the future if we choose to revisit the
|
||||||
// the decision, this is where it should be.
|
// decision, this is where it should be.
|
||||||
//
|
//
|
||||||
if (LastNode == 0) { // No postdominator!
|
if (LastNode == 0) { // No postdominator!
|
||||||
|
if (!isa<InvokeInst>(TI)) {
|
||||||
// Call RemoveSuccessor to transmogrify the terminator instruction
|
// Call RemoveSuccessor to transmogrify the terminator instruction
|
||||||
// to not contain the outgoing branch, or to create a new terminator
|
// to not contain the outgoing branch, or to create a new
|
||||||
// if the form fundamentally changes (i.e., unconditional branch to
|
// terminator if the form fundamentally changes (i.e.,
|
||||||
// return). Note that this will change a branch into an infinite
|
// unconditional branch to return). Note that this will change a
|
||||||
// loop into a return instruction!
|
// branch into an infinite loop into a return instruction!
|
||||||
//
|
//
|
||||||
RemoveSuccessor(TI, i);
|
RemoveSuccessor(TI, i);
|
||||||
|
|
||||||
// RemoveSuccessor may replace TI... make sure we have a fresh
|
// RemoveSuccessor may replace TI... make sure we have a fresh
|
||||||
// pointer... and e variable.
|
// pointer.
|
||||||
//
|
//
|
||||||
TI = BB->getTerminator();
|
TI = BB->getTerminator();
|
||||||
|
|
||||||
// Rescan this successor...
|
// Rescan this successor...
|
||||||
--i;
|
--i;
|
||||||
} else {
|
} else {
|
||||||
PostDominatorTree::Node *NextNode = LastNode->getIDom();
|
|
||||||
|
|
||||||
while (!AliveBlocks.count(NextNode->getBlock())) {
|
|
||||||
LastNode = NextNode;
|
|
||||||
NextNode = NextNode->getIDom();
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// Get the basic blocks that we need...
|
// Get the basic blocks that we need...
|
||||||
BasicBlock *LastDead = LastNode->getBlock();
|
BasicBlock *LastDead = LastNode->getBlock();
|
||||||
BasicBlock *NextAlive = NextNode->getBlock();
|
BasicBlock *NextAlive = NextNode->getBlock();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user