const MachineLoop *SplitAnalysis::getBestSplitLoop() { assert(curli_ && "Call analyze() before getBestSplitLoop"); if (usingLoops_.empty()) return 0; LoopPtrSet Loops; LoopBlocks Blocks; BlockPtrSet CriticalExits; // We split around loops where curli is used outside the periphery. for (LoopCountMap::const_iterator I = usingLoops_.begin(), E = usingLoops_.end(); I != E; ++I) { const MachineLoop *Loop = I->first; getLoopBlocks(Loop, Blocks); DEBUG({ dbgs() << " "; print(Blocks, dbgs()); }); switch(analyzeLoopPeripheralUse(Blocks)) { case OutsideLoop: break; case MultiPeripheral: // FIXME: We could split a live range with multiple uses in a peripheral // block and still make progress. However, it is possible that splitting // another live range will insert copies into a peripheral block, and // there is a small chance we can enter an infinity loop, inserting copies // forever. // For safety, stick to splitting live ranges with uses outside the // periphery. DEBUG(dbgs() << ": multiple peripheral uses\n"); break; case ContainedInLoop: DEBUG(dbgs() << ": fully contained\n"); continue; case SinglePeripheral: DEBUG(dbgs() << ": single peripheral use\n"); continue; } // Will it be possible to split around this loop? getCriticalExits(Blocks, CriticalExits); DEBUG(dbgs() << ": " << CriticalExits.size() << " critical exits\n"); if (!canSplitCriticalExits(Blocks, CriticalExits)) continue; // This is a possible split. Loops.insert(Loop); }
const MachineLoop *SplitAnalysis::getBestSplitLoop() { assert(curli_ && "Call analyze() before getBestSplitLoop"); if (usingLoops_.empty()) return 0; LoopPtrSet Loops, SecondLoops; LoopBlocks Blocks; BlockPtrSet CriticalExits; // Find first-class and second class candidate loops. // We prefer to split around loops where curli is used outside the periphery. for (LoopPtrSet::const_iterator I = usingLoops_.begin(), E = usingLoops_.end(); I != E; ++I) { getLoopBlocks(*I, Blocks); LoopPtrSet *LPS = 0; switch(analyzeLoopPeripheralUse(Blocks)) { case OutsideLoop: LPS = &Loops; break; case MultiPeripheral: LPS = &SecondLoops; break; case ContainedInLoop: DEBUG(dbgs() << "ContainedInLoop: " << **I); continue; case SinglePeripheral: DEBUG(dbgs() << "SinglePeripheral: " << **I); continue; } // Will it be possible to split around this loop? getCriticalExits(Blocks, CriticalExits); DEBUG(dbgs() << CriticalExits.size() << " critical exits: " << **I); if (!canSplitCriticalExits(Blocks, CriticalExits)) continue; // This is a possible split. assert(LPS); LPS->insert(*I); } DEBUG(dbgs() << "Got " << Loops.size() << " + " << SecondLoops.size() << " candidate loops\n"); // If there are no first class loops available, look at second class loops. if (Loops.empty()) Loops = SecondLoops; if (Loops.empty()) return 0; // Pick the earliest loop. // FIXME: Are there other heuristics to consider? const MachineLoop *Best = 0; SlotIndex BestIdx; for (LoopPtrSet::const_iterator I = Loops.begin(), E = Loops.end(); I != E; ++I) { SlotIndex Idx = lis_.getMBBStartIdx((*I)->getHeader()); if (!Best || Idx < BestIdx) Best = *I, BestIdx = Idx; } DEBUG(dbgs() << "Best: " << *Best); return Best; }