Index: include/llvm/Analysis/BranchProbabilityInfo.h =================================================================== --- include/llvm/Analysis/BranchProbabilityInfo.h +++ include/llvm/Analysis/BranchProbabilityInfo.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/CFG.h" #include "llvm/IR/PassManager.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" @@ -116,13 +117,16 @@ void calculate(const Function &F, const LoopInfo &LI); + /// \brief Forget analysis results for the given basic block. + void eraseBlock(const BasicBlock *BB); + private: void operator=(const BranchProbabilityInfo &) = delete; BranchProbabilityInfo(const BranchProbabilityInfo &) = delete; // Since we allow duplicate edges from one basic block to another, we use // a pair (PredBlock and an index in the successors) to specify an edge. - typedef std::pair Edge; + typedef std::pair, unsigned> Edge; // Default weight value. Used when we don't have information about the edge. // TODO: DEFAULT_WEIGHT makes sense during static predication, when none of Index: include/llvm/Transforms/Utils/Local.h =================================================================== --- include/llvm/Transforms/Utils/Local.h +++ include/llvm/Transforms/Utils/Local.h @@ -44,6 +44,7 @@ class DIBuilder; class DominatorTree; class LazyValueInfo; +class BranchProbabilityInfo; template class SmallVectorImpl; @@ -300,7 +301,8 @@ /// Remove all blocks that can not be reached from the function's entry. /// /// Returns true if any basic block was removed. -bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr); +bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr, + BranchProbabilityInfo *BPI = nullptr); /// Combine the metadata of two instructions so that K can replace J /// Index: lib/Analysis/BranchProbabilityInfo.cpp =================================================================== --- lib/Analysis/BranchProbabilityInfo.cpp +++ lib/Analysis/BranchProbabilityInfo.cpp @@ -639,6 +639,14 @@ return OS; } +void BranchProbabilityInfo::eraseBlock(const BasicBlock *BB) { + for (auto I = Probs.begin(), E = Probs.end(); I != E; ++I) { + auto Key = I->first; + if (Key.first == BB) + Probs.erase(Key); + } +} + void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LI) { DEBUG(dbgs() << "---- Branch Probability Info : " << F.getName() << " ----\n\n"); Index: lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- lib/Transforms/Scalar/JumpThreading.cpp +++ lib/Transforms/Scalar/JumpThreading.cpp @@ -212,7 +212,7 @@ // back edges. This works for normal cases but not for unreachable blocks as // they may have cycle with no back edge. bool EverChanged = false; - EverChanged |= removeUnreachableBlocks(F, LVI); + EverChanged |= removeUnreachableBlocks(F, LVI, BPI.get()); FindLoopHeaders(F); @@ -235,6 +235,8 @@ << "' with terminator: " << *BB->getTerminator() << '\n'); LoopHeaders.erase(BB); LVI->eraseBlock(BB); + if (HasProfileData) + BPI->eraseBlock(BB); DeleteDeadBlock(BB); Changed = true; continue; @@ -263,6 +265,8 @@ // awesome, but it allows us to use AssertingVH to prevent nasty // dangling pointer issues within LazyValueInfo. LVI->eraseBlock(BB); + if (HasProfileData) + BPI->eraseBlock(BB); if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) { Changed = true; // If we deleted BB and BB was the header of a loop, then the @@ -747,6 +751,8 @@ LoopHeaders.insert(BB); LVI->eraseBlock(SinglePred); + if (HasProfileData) + BPI->eraseBlock(SinglePred); MergeBasicBlockIntoOnlyPred(BB); return true; Index: lib/Transforms/Utils/Local.cpp =================================================================== --- lib/Transforms/Utils/Local.cpp +++ lib/Transforms/Utils/Local.cpp @@ -20,6 +20,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/MemoryBuiltins.h" @@ -1486,7 +1487,8 @@ /// removeUnreachableBlocksFromFn - Remove blocks that are not reachable, even /// if they are in a dead cycle. Return true if a change was made, false /// otherwise. -bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI) { +bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI, + BranchProbabilityInfo *BPI) { SmallPtrSet Reachable; bool Changed = markAliveBlocks(F, Reachable); @@ -1509,6 +1511,8 @@ (*SI)->removePredecessor(&*BB); if (LVI) LVI->eraseBlock(&*BB); + if (BPI) + BPI->eraseBlock(&*BB); BB->dropAllReferences(); } Index: unittests/Analysis/BlockFrequencyInfoTest.cpp =================================================================== --- unittests/Analysis/BlockFrequencyInfoTest.cpp +++ unittests/Analysis/BlockFrequencyInfoTest.cpp @@ -54,6 +54,11 @@ SMDiagnostic Err; return parseAssemblyString(ModuleStrig, Err, C); } + + void releaseBFI() { + // Prevent AssetingVH from failing + BPI->releaseMemory(); + } }; TEST_F(BlockFrequencyInfoTest, Basic) { @@ -80,6 +85,8 @@ EXPECT_EQ(BFI.getBlockProfileCount(BB3).getValue(), UINT64_C(100)); EXPECT_EQ(BFI.getBlockProfileCount(BB1).getValue(), 100 * BB1Freq / BB0Freq); EXPECT_EQ(BFI.getBlockProfileCount(BB2).getValue(), 100 * BB2Freq / BB0Freq); + + releaseBFI(); } } // end anonymous namespace