From 7732ae4a4f1c9b57c8b99e664790a6b8788fd1d4 Mon Sep 17 00:00:00 2001 From: Diego Novillo Date: Wed, 26 Aug 2015 20:00:27 +0000 Subject: [PATCH] Fix memory leak in sample profile pass. The problem here were the function analyses invoked by the function pass manager from the new IPO pass. I looked at other IPO passes needing dominance information and the only one that requires it (partial inliner) does not use the standard dependency mechanism. This patch mimics what the partial inliner does to compute dominance, post-dominance and loop info. One thing I like about this approach is that I can delay the computation of all this until I actually need it. This should bring the ASAN buildbot back to green. If there's a better way to fix this, I'll do it in a follow-up patch. llvm-svn: 246066 --- llvm/lib/Transforms/IPO/SampleProfile.cpp | 51 ++++++++++------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp index f6602fda4305..f99cc23c918e 100644 --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -80,9 +80,8 @@ public: static char ID; SampleProfileLoader(StringRef Name = SampleProfileFile) - : ModulePass(ID), DT(nullptr), PDT(nullptr), LI(nullptr), - Ctx(nullptr), Reader(), Samples(nullptr), Filename(Name), - ProfileIsValid(false) { + : ModulePass(ID), DT(nullptr), PDT(nullptr), LI(nullptr), Reader(), + Samples(nullptr), Filename(Name), ProfileIsValid(false) { initializeSampleProfileLoaderPass(*PassRegistry::getPassRegistry()); } @@ -96,15 +95,6 @@ public: void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); - - AU.addRequired(); - AU.addPreserved(); - - AU.addRequired(); - AU.addPreserved(); - - AU.addRequired(); - AU.addPreserved(); } protected: @@ -125,6 +115,7 @@ protected: unsigned visitEdge(Edge E, unsigned *NumUnknownEdges, Edge *UnknownEdge); void buildEdges(Function &F); bool propagateThroughEdges(Function &F); + void computeDominanceAndLoopInfo(Function &F); /// \brief Line number for the function header. Used to compute absolute /// line numbers from the relative line numbers found in the profile. @@ -157,9 +148,9 @@ protected: EquivalenceClassMap EquivalenceClass; /// \brief Dominance, post-dominance and loop information. - DominatorTree *DT; - PostDominatorTree *PDT; - LoopInfo *LI; + std::unique_ptr DT; + std::unique_ptr> PDT; + std::unique_ptr LI; /// \brief Predecessors for each basic block in the CFG. BlockEdgeMap Predecessors; @@ -167,9 +158,6 @@ protected: /// \brief Successors for each basic block in the CFG. BlockEdgeMap Successors; - /// \brief LLVM context holding the debug data we need. - LLVMContext *Ctx; - /// \brief Profile reader object. std::unique_ptr Reader; @@ -372,7 +360,7 @@ void SampleProfileLoader::findEquivalenceClasses(Function &F) { // class by making BB2's equivalence class be BB1. DominatedBBs.clear(); DT->getDescendants(BB1, DominatedBBs); - findEquivalencesFor(BB1, DominatedBBs, PDT->DT); + findEquivalencesFor(BB1, DominatedBBs, PDT.get()); // Repeat the same logic for all the blocks post-dominated by BB1. // We are looking for every basic block BB2 such that: @@ -384,7 +372,7 @@ void SampleProfileLoader::findEquivalenceClasses(Function &F) { // If all those conditions hold, BB2's equivalence class is BB1. DominatedBBs.clear(); PDT->getDescendants(BB1, DominatedBBs); - findEquivalencesFor(BB1, DominatedBBs, DT); + findEquivalencesFor(BB1, DominatedBBs, DT.get()); DEBUG(printBlockEquivalence(dbgs(), BB1)); } @@ -666,6 +654,17 @@ unsigned SampleProfileLoader::getFunctionLoc(Function &F) { return 0; } +void SampleProfileLoader::computeDominanceAndLoopInfo(Function &F) { + DT.reset(new DominatorTree); + DT->recalculate(F); + + PDT.reset(new DominatorTreeBase(true)); + PDT->recalculate(F); + + LI.reset(new LoopInfo); + LI->analyze(*DT); +} + /// \brief Generate branch weight metadata for all branches in \p F. /// /// Branch weights are computed out of instruction samples using a @@ -730,6 +729,9 @@ bool SampleProfileLoader::emitAnnotations(Function &F) { Changed |= computeBlockWeights(F); if (Changed) { + // Compute dominance and loop info needed for propagation. + computeDominanceAndLoopInfo(F); + // Find equivalence classes. findEquivalenceClasses(F); @@ -743,15 +745,12 @@ bool SampleProfileLoader::emitAnnotations(Function &F) { char SampleProfileLoader::ID = 0; INITIALIZE_PASS_BEGIN(SampleProfileLoader, "sample-profile", "Sample Profile loader", false, false) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(AddDiscriminators) INITIALIZE_PASS_END(SampleProfileLoader, "sample-profile", "Sample Profile loader", false, false) bool SampleProfileLoader::doInitialization(Module &M) { - auto& Ctx = M.getContext(); + auto &Ctx = M.getContext(); auto ReaderOrErr = SampleProfileReader::create(Filename, Ctx); if (std::error_code EC = ReaderOrErr.getError()) { std::string Msg = "Could not open profile: " + EC.message(); @@ -783,10 +782,6 @@ bool SampleProfileLoader::runOnFunction(Function &F) { if (!ProfileIsValid) return false; - DT = &getAnalysis(F).getDomTree(); - PDT = &getAnalysis(F); - LI = &getAnalysis(F).getLoopInfo(); - Ctx = &F.getParent()->getContext(); Samples = Reader->getSamplesFor(F); if (!Samples->empty()) return emitAnnotations(F);