[llvm] r351892 - [HotColdSplit] Calculate domtrees lazily to reduce compile-time, NFC

Vedant Kumar via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 22 14:49:08 PST 2019


Author: vedantk
Date: Tue Jan 22 14:49:08 2019
New Revision: 351892

URL: http://llvm.org/viewvc/llvm-project?rev=351892&view=rev
Log:
[HotColdSplit] Calculate domtrees lazily to reduce compile-time, NFC

The splitting pass does not need (post)domtrees until after it's found a
cold block. Defer domtree calculation until a cold block is found.

For the sqlite3 amalgamation, this reduces time spent in the splitting
pass from 0.8% of the total to 0.4%.

Modified:
    llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp

Modified: llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp?rev=351892&r1=351891&r2=351892&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/HotColdSplitting.cpp Tue Jan 22 14:49:08 2019
@@ -74,10 +74,6 @@ static cl::opt<int>
 
 namespace {
 
-struct PostDomTree : PostDomTreeBase<BasicBlock> {
-  PostDomTree(Function &F) { recalculate(F); }
-};
-
 /// A sequence of basic blocks.
 ///
 /// A 0-sized SmallVector is slightly cheaper to move than a std::vector.
@@ -180,10 +176,7 @@ public:
 private:
   bool isFunctionCold(const Function &F) const;
   bool shouldOutlineFrom(const Function &F) const;
-  bool outlineColdRegions(Function &F, ProfileSummaryInfo &PSI,
-                          BlockFrequencyInfo *BFI, TargetTransformInfo &TTI,
-                          DominatorTree &DT, PostDomTree &PDT,
-                          OptimizationRemarkEmitter &ORE);
+  bool outlineColdRegions(Function &F);
   Function *extractColdRegion(const BlockSequence &Region, DominatorTree &DT,
                               BlockFrequencyInfo *BFI, TargetTransformInfo &TTI,
                               OptimizationRemarkEmitter &ORE, unsigned Count);
@@ -327,7 +320,7 @@ public:
   OutliningRegion &operator=(OutliningRegion &&) = default;
 
   static OutliningRegion create(BasicBlock &SinkBB, const DominatorTree &DT,
-                                const PostDomTree &PDT) {
+                                const PostDominatorTree &PDT) {
     OutliningRegion ColdRegion;
 
     SmallPtrSet<BasicBlock *, 4> RegionBlocks;
@@ -455,11 +448,7 @@ public:
 };
 } // namespace
 
-bool HotColdSplitting::outlineColdRegions(Function &F, ProfileSummaryInfo &PSI,
-                                          BlockFrequencyInfo *BFI,
-                                          TargetTransformInfo &TTI,
-                                          DominatorTree &DT, PostDomTree &PDT,
-                                          OptimizationRemarkEmitter &ORE) {
+bool HotColdSplitting::outlineColdRegions(Function &F) {
   bool Changed = false;
 
   // The set of cold blocks.
@@ -473,13 +462,21 @@ bool HotColdSplitting::outlineColdRegion
   // the first region to contain a block.
   ReversePostOrderTraversal<Function *> RPOT(&F);
 
+  // Calculate domtrees lazily. This reduces compile-time significantly.
+  std::unique_ptr<DominatorTree> DT;
+  std::unique_ptr<PostDominatorTree> PDT;
+
+  BlockFrequencyInfo *BFI = GetBFI(F);
+  TargetTransformInfo &TTI = GetTTI(F);
+  OptimizationRemarkEmitter &ORE = (*GetORE)(F);
+
   // Find all cold regions.
   for (BasicBlock *BB : RPOT) {
     // This block is already part of some outlining region.
     if (ColdBlocks.count(BB))
       continue;
 
-    bool Cold = PSI.isColdBlock(BB, BFI) ||
+    bool Cold = PSI->isColdBlock(BB, BFI) ||
                 (EnableStaticAnalyis && unlikelyExecuted(*BB));
     if (!Cold)
       continue;
@@ -489,7 +486,12 @@ bool HotColdSplitting::outlineColdRegion
       BB->dump();
     });
 
-    auto Region = OutliningRegion::create(*BB, DT, PDT);
+    if (!DT)
+      DT = make_unique<DominatorTree>(F);
+    if (!PDT)
+      PDT = make_unique<PostDominatorTree>(F);
+
+    auto Region = OutliningRegion::create(*BB, *DT, *PDT);
     if (Region.empty())
       continue;
 
@@ -519,7 +521,7 @@ bool HotColdSplitting::outlineColdRegion
     OutliningRegion Region = OutliningWorklist.pop_back_val();
     assert(!Region.empty() && "Empty outlining region in worklist");
     do {
-      BlockSequence SubRegion = Region.takeSingleEntrySubRegion(DT);
+      BlockSequence SubRegion = Region.takeSingleEntrySubRegion(*DT);
       if (!isProfitableToOutline(SubRegion, TTI)) {
         LLVM_DEBUG({
           dbgs() << "Skipping outlining; not profitable to outline\n";
@@ -535,7 +537,7 @@ bool HotColdSplitting::outlineColdRegion
       });
 
       Function *Outlined =
-          extractColdRegion(SubRegion, DT, BFI, TTI, ORE, OutlinedFunctionID);
+          extractColdRegion(SubRegion, *DT, BFI, TTI, ORE, OutlinedFunctionID);
       if (Outlined) {
         ++OutlinedFunctionID;
         Changed = true;
@@ -571,13 +573,7 @@ bool HotColdSplitting::run(Module &M) {
     }
 
     LLVM_DEBUG(llvm::dbgs() << "Outlining in " << F.getName() << "\n");
-    DominatorTree DT(F);
-    PostDomTree PDT(F);
-    PDT.recalculate(F);
-    BlockFrequencyInfo *BFI = GetBFI(F);
-    TargetTransformInfo &TTI = GetTTI(F);
-    OptimizationRemarkEmitter &ORE = (*GetORE)(F);
-    Changed |= outlineColdRegions(F, *PSI, BFI, TTI, DT, PDT, ORE);
+    Changed |= outlineColdRegions(F);
   }
   return Changed;
 }




More information about the llvm-commits mailing list