void ShortestPathAnalysis::analyzeLoopsRecursively(SILLoop *Loop, int LoopDepth) { if (LoopDepth >= MaxNumLoopLevels) return; // First dive into the inner loops. for (SILLoop *SubLoop : Loop->getSubLoops()) { analyzeLoopsRecursively(SubLoop, LoopDepth + 1); } BlockInfo *HeaderInfo = getBlockInfo(Loop->getHeader()); Distances &HeaderDists = HeaderInfo->getDistances(LoopDepth); // Initial values for the entry (== header) and exit-predecessor (== header as // well). HeaderDists.DistFromEntry = 0; HeaderDists.DistToExit = 0; solveDataFlow(Loop->getBlocks(), LoopDepth); int LoopLength = getExitDistFromSuccs(Loop->getHeader(), LoopDepth) + HeaderInfo->getLength(LoopDepth); HeaderDists.DistToExit = LoopLength; // If there is a loop bypass edge, add the loop length to the loop pre-pre- // header instead to the header. This actually let us ignore the loop bypass // edge in the length calculation for the loop's parent scope. if (SILBasicBlock *Bypass = detectLoopBypassPreheader(Loop)) HeaderInfo = getBlockInfo(Bypass); // Add the full loop length (= assumed-iteration-count * length) to the loop // header so that it is considered in the parent scope. HeaderInfo->getDistances(LoopDepth - 1).LoopHeaderLength = LoopCount * LoopLength; }
void ShortestPathAnalysis::printBlockInfo(llvm::raw_ostream &OS, SILBasicBlock *BB, int LoopDepth) { BlockInfo *BBInfo = getBlockInfo(BB); Distances &D = BBInfo->getDistances(LoopDepth); OS << " bb" << BB->getDebugID() << ": length=" << BBInfo->Length << '+' << D.LoopHeaderLength << ", d-entry=" << D.DistFromEntry << ", d-exit=" << D.DistToExit << '\n'; }
int ShortestPathAnalysis::getExitDistFromSuccs(const SILBasicBlock *BB, int LoopDepth) { int MinDist = InitialDist; for (const SILSuccessor &Succ : BB->getSuccessors()) { BlockInfo *SuccInfo = getBlockInfo(Succ); Distances &SDists = SuccInfo->getDistances(LoopDepth); if (SDists.DistToExit < MinDist) MinDist = SDists.DistToExit; } return MinDist; }
int ShortestPathAnalysis::getEntryDistFromPreds(const SILBasicBlock *BB, int LoopDepth) { int MinDist = InitialDist; for (SILBasicBlock *Pred : BB->getPreds()) { BlockInfo *PredInfo = getBlockInfo(Pred); Distances &PDists = PredInfo->getDistances(LoopDepth); int DistFromEntry = PDists.DistFromEntry + PredInfo->Length + PDists.LoopHeaderLength; assert(DistFromEntry >= 0); if (DistFromEntry < MinDist) MinDist = DistFromEntry; } return MinDist; }