mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-09 13:21:30 +00:00
Be more strict when detecting critical edges before loop splitting.
An exit block with a critical edge must only have predecessors in the loop, or just before the loop. This guarantees that the inserted copies in the loop predecessors dominate the exit block. llvm-svn: 117144
This commit is contained in:
parent
967bcbf445
commit
de1439ce2b
@ -149,37 +149,33 @@ analyzeLoopPeripheralUse(const SplitAnalysis::LoopBlocks &Blocks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// getCriticalExits - It may be necessary to partially break critical edges
|
/// getCriticalExits - It may be necessary to partially break critical edges
|
||||||
/// leaving the loop if an exit block has phi uses of curli. Collect the exit
|
/// leaving the loop if an exit block has predecessors from outside the loop
|
||||||
/// blocks that need special treatment into CriticalExits.
|
/// periphery.
|
||||||
void SplitAnalysis::getCriticalExits(const SplitAnalysis::LoopBlocks &Blocks,
|
void SplitAnalysis::getCriticalExits(const SplitAnalysis::LoopBlocks &Blocks,
|
||||||
BlockPtrSet &CriticalExits) {
|
BlockPtrSet &CriticalExits) {
|
||||||
CriticalExits.clear();
|
CriticalExits.clear();
|
||||||
|
|
||||||
// A critical exit block contains a phi def of curli, and has a predecessor
|
// A critical exit block has curli line-in, and has a predecessor that is not
|
||||||
// that is not in the loop nor a loop predecessor.
|
// in the loop nor a loop predecessor. For such an exit block, the edges
|
||||||
// For such an exit block, the edges carrying the new variable must be moved
|
// carrying the new variable must be moved to a new pre-exit block.
|
||||||
// to a new pre-exit block.
|
|
||||||
for (BlockPtrSet::iterator I = Blocks.Exits.begin(), E = Blocks.Exits.end();
|
for (BlockPtrSet::iterator I = Blocks.Exits.begin(), E = Blocks.Exits.end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
const MachineBasicBlock *Succ = *I;
|
const MachineBasicBlock *Exit = *I;
|
||||||
SlotIndex SuccIdx = lis_.getMBBStartIdx(Succ);
|
// A single-predecessor exit block is definitely not a critical edge.
|
||||||
VNInfo *SuccVNI = curli_->getVNInfoAt(SuccIdx);
|
if (Exit->pred_size() == 1)
|
||||||
|
continue;
|
||||||
// This exit may not have curli live in at all. No need to split.
|
// This exit may not have curli live in at all. No need to split.
|
||||||
if (!SuccVNI)
|
if (!lis_.isLiveInToMBB(*curli_, Exit))
|
||||||
continue;
|
continue;
|
||||||
// If this is not a PHI def, it is either using a value from before the
|
// Does this exit block have a predecessor that is not a loop block or loop
|
||||||
// loop, or a value defined inside the loop. Both are safe.
|
// predecessor?
|
||||||
if (!SuccVNI->isPHIDef() || SuccVNI->def.getBaseIndex() != SuccIdx)
|
for (MachineBasicBlock::const_pred_iterator PI = Exit->pred_begin(),
|
||||||
continue;
|
PE = Exit->pred_end(); PI != PE; ++PI) {
|
||||||
// This exit block does have a PHI. Does it also have a predecessor that is
|
|
||||||
// not a loop block or loop predecessor?
|
|
||||||
for (MachineBasicBlock::const_pred_iterator PI = Succ->pred_begin(),
|
|
||||||
PE = Succ->pred_end(); PI != PE; ++PI) {
|
|
||||||
const MachineBasicBlock *Pred = *PI;
|
const MachineBasicBlock *Pred = *PI;
|
||||||
if (Blocks.Loop.count(Pred) || Blocks.Preds.count(Pred))
|
if (Blocks.Loop.count(Pred) || Blocks.Preds.count(Pred))
|
||||||
continue;
|
continue;
|
||||||
// This is a critical exit block, and we need to split the exit edge.
|
// This is a critical exit block, and we need to split the exit edge.
|
||||||
CriticalExits.insert(Succ);
|
CriticalExits.insert(Exit);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user