/// getCriticalExits - It may be necessary to partially break critical edges /// leaving the loop if an exit block has predecessors from outside the loop /// periphery. void SplitAnalysis::getCriticalExits(const SplitAnalysis::LoopBlocks &Blocks, BlockPtrSet &CriticalExits) { CriticalExits.clear(); // A critical exit block has curli live-in, and has a predecessor that is not // in the loop nor a loop predecessor. For such an exit block, the edges // carrying the new variable must be moved to a new pre-exit block. for (BlockPtrSet::iterator I = Blocks.Exits.begin(), E = Blocks.Exits.end(); I != E; ++I) { const MachineBasicBlock *Exit = *I; // A single-predecessor exit block is definitely not a critical edge. if (Exit->pred_size() == 1) continue; // This exit may not have curli live in at all. No need to split. if (!lis_.isLiveInToMBB(*curli_, Exit)) continue; // Does this exit block have a predecessor that is not a loop block or loop // predecessor? for (MachineBasicBlock::const_pred_iterator PI = Exit->pred_begin(), PE = Exit->pred_end(); PI != PE; ++PI) { const MachineBasicBlock *Pred = *PI; if (Blocks.Loop.count(Pred) || Blocks.Preds.count(Pred)) continue; // This is a critical exit block, and we need to split the exit edge. CriticalExits.insert(Exit); break; } } }
void SplitAnalysis::getCriticalPreds(const SplitAnalysis::LoopBlocks &Blocks, BlockPtrSet &CriticalPreds) { CriticalPreds.clear(); // A critical predecessor block has curli live-out, and has a successor that // has curli live-in and is not in the loop nor a loop exit block. For such a // predecessor block, we must carry the value in both the 'inside' and // 'outside' registers. for (BlockPtrSet::iterator I = Blocks.Preds.begin(), E = Blocks.Preds.end(); I != E; ++I) { const MachineBasicBlock *Pred = *I; // Definitely not a critical edge. if (Pred->succ_size() == 1) continue; // This block may not have curli live out at all if there is a PHI. if (!lis_.isLiveOutOfMBB(*curli_, Pred)) continue; // Does this block have a successor outside the loop? for (MachineBasicBlock::const_pred_iterator SI = Pred->succ_begin(), SE = Pred->succ_end(); SI != SE; ++SI) { const MachineBasicBlock *Succ = *SI; if (Blocks.Loop.count(Succ) || Blocks.Exits.count(Succ)) continue; if (!lis_.isLiveInToMBB(*curli_, Succ)) continue; // This is a critical predecessor block. CriticalPreds.insert(Pred); break; } } }
/// 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 /// blocks that need special treatment into CriticalExits. void SplitAnalysis::getCriticalExits(const SplitAnalysis::LoopBlocks &Blocks, BlockPtrSet &CriticalExits) { CriticalExits.clear(); // A critical exit block contains a phi def of curli, and has a predecessor // that is not in the loop nor a loop predecessor. // For such an exit block, the edges carrying the new variable must be moved // to a new pre-exit block. for (BlockPtrSet::iterator I = Blocks.Exits.begin(), E = Blocks.Exits.end(); I != E; ++I) { const MachineBasicBlock *Succ = *I; SlotIndex SuccIdx = lis_.getMBBStartIdx(Succ); VNInfo *SuccVNI = curli_->getVNInfoAt(SuccIdx); // This exit may not have curli live in at all. No need to split. if (!SuccVNI) continue; // If this is not a PHI def, it is either using a value from before the // loop, or a value defined inside the loop. Both are safe. if (!SuccVNI->isPHIDef() || SuccVNI->def.getBaseIndex() != SuccIdx) continue; // 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; if (Blocks.Loop.count(Pred) || Blocks.Preds.count(Pred)) continue; // This is a critical exit block, and we need to split the exit edge. CriticalExits.insert(Succ); break; } } }