From 0f30f08b02e5fc426004dad9c379ad1a260797cb Mon Sep 17 00:00:00 2001 From: Sebastian Pop Date: Fri, 14 Sep 2018 20:36:19 +0000 Subject: HotColdSplit: fix invalid SSA due to outlining The test used to fail with an invalid phi node: the two predecessors were outlined and the SSA representation was left invalid. The patch adds the exit block to the cold region. llvm-svn: 342277 --- llvm/lib/Transforms/IPO/HotColdSplitting.cpp | 31 ++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'llvm/lib/Transforms') diff --git a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp index c4846f9c437..be64da5d808 100644 --- a/llvm/lib/Transforms/IPO/HotColdSplitting.cpp +++ b/llvm/lib/Transforms/IPO/HotColdSplitting.cpp @@ -219,9 +219,8 @@ public: private: bool shouldOutlineFrom(const Function &F) const; - Function *outlineColdBlocks(Function &F, - const DenseSetBB &ColdBlock, - DominatorTree *DT, PostDomTree *PDT); + const Function *outlineColdBlocks(Function &F, const DenseSetBB &ColdBlock, + DominatorTree *DT, PostDomTree *PDT); Function *extractColdRegion(const SmallVectorImpl &Region, DominatorTree *DT, BlockFrequencyInfo *BFI, OptimizationRemarkEmitter &ORE); @@ -264,9 +263,12 @@ public: } // end anonymous namespace // Returns false if the function should not be considered for hot-cold split -// optimization. Already outlined functions have coldcc so no need to check -// for them here. +// optimization. bool HotColdSplitting::shouldOutlineFrom(const Function &F) const { + // Do not try to outline again from an already outlined cold function. + if (OutlinedFunctions.count(&F)) + return false; + if (F.size() <= 2) return false; @@ -314,7 +316,7 @@ HotColdSplitting::extractColdRegion(const SmallVectorImpl &Region, CS.setCallingConv(CallingConv::Cold); } CI->setIsNoInline(); - LLVM_DEBUG(llvm::dbgs() << "Outlined Region at block: " << Region.front()); + LLVM_DEBUG(llvm::dbgs() << "Outlined Region: " << *OutF); return OutF; } @@ -328,10 +330,10 @@ HotColdSplitting::extractColdRegion(const SmallVectorImpl &Region, } // Return the function created after outlining, nullptr otherwise. -Function *HotColdSplitting::outlineColdBlocks(Function &F, - const DenseSetBB &HotBlocks, - DominatorTree *DT, - PostDomTree *PDT) { +const Function *HotColdSplitting::outlineColdBlocks(Function &F, + const DenseSetBB &HotBlocks, + DominatorTree *DT, + PostDomTree *PDT) { auto BFI = GetBFI(F); auto &ORE = (*GetORE)(F); // Walking the dominator tree allows us to find the largest @@ -342,12 +344,10 @@ Function *HotColdSplitting::outlineColdBlocks(Function &F, if (PSI->isColdBB(BB, BFI) || !HotBlocks.count(BB)) { SmallVector ValidColdRegion, Region; BasicBlock *Exit = (*PDT)[BB]->getIDom()->getBlock(); - // We might need a virtual exit which post-dominates all basic blocks. - if (!Exit) - continue; BasicBlock *ExitColdRegion = nullptr; + // Estimated cold region between a BB and its dom-frontier. - while (isSingleEntrySingleExit(BB, Exit, DT, PDT, Region) && + while (Exit && isSingleEntrySingleExit(BB, Exit, DT, PDT, Region) && isOutlineCandidate(Region, Exit)) { ExitColdRegion = Exit; ValidColdRegion = Region; @@ -361,6 +361,7 @@ Function *HotColdSplitting::outlineColdBlocks(Function &F, continue; ++NumColdSESEFound; + ValidColdRegion.push_back(ExitColdRegion); // Candidate for outlining. FIXME: Continue outlining. return extractColdRegion(ValidColdRegion, DT, BFI, ORE); } @@ -380,7 +381,7 @@ bool HotColdSplitting::run(Module &M) { if (EnableStaticAnalyis) // Static analysis of cold blocks. HotBlocks = getHotBlocks(F); - auto Outlined = outlineColdBlocks(F, HotBlocks, &DT, &PDT); + const Function *Outlined = outlineColdBlocks(F, HotBlocks, &DT, &PDT); if (Outlined) OutlinedFunctions.insert(Outlined); } -- cgit v1.2.3