/// canSplitCriticalExits - Return true if it is possible to insert new exit /// blocks before the blocks in CriticalExits. bool SplitAnalysis::canSplitCriticalExits(const SplitAnalysis::LoopBlocks &Blocks, BlockPtrSet &CriticalExits) { // If we don't allow critical edge splitting, require no critical exits. if (!AllowSplit) return CriticalExits.empty(); for (BlockPtrSet::iterator I = CriticalExits.begin(), E = CriticalExits.end(); I != E; ++I) { const MachineBasicBlock *Succ = *I; // We want to insert a new pre-exit MBB before Succ, and change all the // in-loop blocks to branch to the pre-exit instead of Succ. // Check that all the in-loop predecessors can be changed. for (MachineBasicBlock::const_pred_iterator PI = Succ->pred_begin(), PE = Succ->pred_end(); PI != PE; ++PI) { const MachineBasicBlock *Pred = *PI; // The external predecessors won't be altered. if (!Blocks.Loop.count(Pred) && !Blocks.Preds.count(Pred)) continue; if (!canAnalyzeBranch(Pred)) return false; } // If Succ's layout predecessor falls through, that too must be analyzable. // We need to insert the pre-exit block in the gap. MachineFunction::const_iterator MFI = Succ; if (MFI == mf_.begin()) continue; if (!canAnalyzeBranch(--MFI)) return false; } // No problems found. return true; }
/// getMultiUseBlocks - if curli has more than one use in a basic block, it /// may be an advantage to split curli for the duration of the block. bool SplitAnalysis::getMultiUseBlocks(BlockPtrSet &Blocks) { // If curli is local to one block, there is no point to splitting it. if (usingBlocks_.size() <= 1) return false; // Add blocks with multiple uses. for (BlockCountMap::iterator I = usingBlocks_.begin(), E = usingBlocks_.end(); I != E; ++I) switch (I->second) { case 0: case 1: continue; case 2: { // It doesn't pay to split a 2-instr block if it redefines curli. VNInfo *VN1 = curli_->getVNInfoAt(lis_.getMBBStartIdx(I->first)); VNInfo *VN2 = curli_->getVNInfoAt(lis_.getMBBEndIdx(I->first).getPrevIndex()); // live-in and live-out with a different value. if (VN1 && VN2 && VN1 != VN2) continue; } // Fall through. default: Blocks.insert(I->first); } return !Blocks.empty(); }