Split *all* critical edges before isel. This resolves issues with spill code
being inserted on unsplit critical edges, which introduces (sometimes large amounts of) partially dead spill code. This also fixes PR925 + CodeGen/Generic/switch-crit-edge-constant.ll llvm-svn: 31260
This commit is contained in:
parent
5217111abe
commit
3e6b1c6157
|
@ -3490,64 +3490,28 @@ static bool OptimizeGEPExpression(GetElementPtrInst *GEPI,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// SplitCritEdgesForPHIConstants - If this block has any PHI nodes with
|
|
||||||
/// constant operands, and if any of the edges feeding the PHI node are
|
|
||||||
/// critical, split them so that the assignments of a constant to a register
|
|
||||||
/// will not be executed on a path that isn't relevant.
|
|
||||||
void SelectionDAGISel::SplitCritEdgesForPHIConstants(BasicBlock *BB) {
|
|
||||||
// The most common case is that this is a PHI node with two incoming
|
|
||||||
// successors handle this case efficiently, because it is simple.
|
|
||||||
PHINode *PN = cast<PHINode>(BB->begin());
|
|
||||||
if (PN->getNumIncomingValues() == 2) {
|
|
||||||
// If neither edge is critical, we never need to split.
|
|
||||||
if (PN->getIncomingBlock(0)->getTerminator()->getNumSuccessors() == 1 &&
|
|
||||||
PN->getIncomingBlock(1)->getTerminator()->getNumSuccessors() == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
BasicBlock::iterator BBI = BB->begin();
|
|
||||||
while ((PN = dyn_cast<PHINode>(BBI++))) {
|
|
||||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
|
||||||
if (isa<Constant>(PN->getIncomingValue(i)))
|
|
||||||
SplitCriticalEdge(PN->getIncomingBlock(i), BB);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, things are a bit trickier.
|
|
||||||
|
|
||||||
// BE SMART HERE.
|
|
||||||
|
|
||||||
BasicBlock::iterator BBI = BB->begin();
|
|
||||||
while ((PN = dyn_cast<PHINode>(BBI++))) {
|
|
||||||
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
|
|
||||||
if (isa<Constant>(PN->getIncomingValue(i)))
|
|
||||||
SplitCriticalEdge(PN->getIncomingBlock(i), BB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SelectionDAGISel::runOnFunction(Function &Fn) {
|
bool SelectionDAGISel::runOnFunction(Function &Fn) {
|
||||||
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
|
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
|
||||||
RegMap = MF.getSSARegMap();
|
RegMap = MF.getSSARegMap();
|
||||||
DEBUG(std::cerr << "\n\n\n=== " << Fn.getName() << "\n");
|
DEBUG(std::cerr << "\n\n\n=== " << Fn.getName() << "\n");
|
||||||
|
|
||||||
// First, split all critical edges for PHI nodes with incoming values that are
|
// First, split all critical edges.
|
||||||
// constants, this way the load of the constant into a vreg will not be placed
|
|
||||||
// into MBBs that are used some other way.
|
|
||||||
//
|
//
|
||||||
// In this pass we also look for GEP and cast instructions that are used
|
// In this pass we also look for GEP and cast instructions that are used
|
||||||
// across basic blocks and rewrite them to improve basic-block-at-a-time
|
// across basic blocks and rewrite them to improve basic-block-at-a-time
|
||||||
// selection.
|
// selection.
|
||||||
//
|
//
|
||||||
//
|
|
||||||
bool MadeChange = true;
|
bool MadeChange = true;
|
||||||
while (MadeChange) {
|
while (MadeChange) {
|
||||||
MadeChange = false;
|
MadeChange = false;
|
||||||
for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
|
for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
|
||||||
// If this block has any PHI nodes with constant operands, and if any of the
|
// Split all critical edges.
|
||||||
// edges feeding the PHI node are critical, split them.
|
TerminatorInst *BBTI = BB->getTerminator();
|
||||||
if (isa<PHINode>(BB->begin()))
|
if (BBTI->getNumSuccessors() > 1) {
|
||||||
SplitCritEdgesForPHIConstants(BB);
|
for (unsigned i = 0, e = BBTI->getNumSuccessors(); i != e; ++i)
|
||||||
|
SplitCriticalEdge(BBTI, i, this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
|
for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
|
||||||
Instruction *I = BBI++;
|
Instruction *I = BBI++;
|
||||||
|
|
Loading…
Reference in New Issue