[llvm] c9b4dc3 - [FuncSpec][NFC] Avoid redundant computations of DominatorTree/LoopInfo

Momchil Velikov via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 28 08:22:17 PDT 2022


Author: Momchil Velikov
Date: 2022-10-28T16:08:41+01:00
New Revision: c9b4dc3a81091856584747010881a816a4901b69

URL: https://github.com/llvm/llvm-project/commit/c9b4dc3a81091856584747010881a816a4901b69
DIFF: https://github.com/llvm/llvm-project/commit/c9b4dc3a81091856584747010881a816a4901b69.diff

LOG: [FuncSpec][NFC] Avoid redundant computations of DominatorTree/LoopInfo

The `FunctionSpecialization` pass needs loop analysis results for its
cost function. For this purpose, it computes the `DominatorTree` and
`LoopInfo` for a function in `getSpecializationBonus`.  This function,
however, is called O(number of call sites x number of arguments), but
the DominatorTree/LoopInfo can be computed just once.

This patch plugs into the PassManager infrastructure to obtain
LoopInfo for a function and removes ad-hoc computation from
`getSpecializatioBonus`.

Reviewed By: ChuanqiXu, labrinea

Differential Revision: https://reviews.llvm.org/D136332

Added: 
    

Modified: 
    llvm/include/llvm/Transforms/Utils/SCCPSolver.h
    llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
    llvm/lib/Transforms/IPO/SCCP.cpp
    llvm/lib/Transforms/Utils/SCCPSolver.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/Utils/SCCPSolver.h b/llvm/include/llvm/Transforms/Utils/SCCPSolver.h
index 17bd072598ee..f37badb38db0 100644
--- a/llvm/include/llvm/Transforms/Utils/SCCPSolver.h
+++ b/llvm/include/llvm/Transforms/Utils/SCCPSolver.h
@@ -30,6 +30,7 @@ class Function;
 class GlobalVariable;
 class Instruction;
 class LLVMContext;
+class LoopInfo;
 class PostDominatorTree;
 class StructType;
 class TargetLibraryInfo;
@@ -41,6 +42,7 @@ struct AnalysisResultsForFn {
   std::unique_ptr<PredicateInfo> PredInfo;
   DominatorTree *DT;
   PostDominatorTree *PDT;
+  LoopInfo *LI;
 };
 
 /// Helper struct shared between Function Specialization and SCCP Solver.
@@ -77,6 +79,8 @@ class SCCPSolver {
 
   const PredicateBase *getPredicateInfoFor(Instruction *I);
 
+  const LoopInfo &getLoopInfo(Function &F);
+
   DomTreeUpdater getDTU(Function &F);
 
   /// trackValueOfGlobalVariable - Clients can use this method to

diff  --git a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
index 4483d67a7349..997e74855b88 100644
--- a/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionSpecialization.cpp
@@ -463,7 +463,7 @@ class FunctionSpecializer {
         }
 
         SpecializationInfo &S = Specializations.back().second;
-        S.Gain += getSpecializationBonus(A, C);
+        S.Gain += getSpecializationBonus(A, C, Solver.getLoopInfo(*F));
         S.Args.push_back({A, C});
       }
       Added = false;
@@ -580,7 +580,7 @@ class FunctionSpecializer {
   }
 
   InstructionCost getUserBonus(User *U, llvm::TargetTransformInfo &TTI,
-                               LoopInfo &LI) {
+                               const LoopInfo &LI) {
     auto *I = dyn_cast_or_null<Instruction>(U);
     // If not an instruction we do not know how to evaluate.
     // Keep minimum possible cost for now so that it doesnt affect
@@ -605,10 +605,9 @@ class FunctionSpecializer {
   }
 
   /// Compute a bonus for replacing argument \p A with constant \p C.
-  InstructionCost getSpecializationBonus(Argument *A, Constant *C) {
+  InstructionCost getSpecializationBonus(Argument *A, Constant *C,
+                                         const LoopInfo &LI) {
     Function *F = A->getParent();
-    DominatorTree DT(*F);
-    LoopInfo LI(DT);
     auto &TTI = (GetTTI)(*F);
     LLVM_DEBUG(dbgs() << "FnSpecialization: Analysing bonus for constant: "
                       << C->getNameOrAsOperand() << "\n");

diff  --git a/llvm/lib/Transforms/IPO/SCCP.cpp b/llvm/lib/Transforms/IPO/SCCP.cpp
index 0453af184a72..673bb230834b 100644
--- a/llvm/lib/Transforms/IPO/SCCP.cpp
+++ b/llvm/lib/Transforms/IPO/SCCP.cpp
@@ -12,6 +12,7 @@
 
 #include "llvm/Transforms/IPO/SCCP.h"
 #include "llvm/Analysis/AssumptionCache.h"
+#include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/PostDominators.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
@@ -32,7 +33,8 @@ PreservedAnalyses IPSCCPPass::run(Module &M, ModuleAnalysisManager &AM) {
     DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
     return {
         std::make_unique<PredicateInfo>(F, DT, FAM.getResult<AssumptionAnalysis>(F)),
-        &DT, FAM.getCachedResult<PostDominatorTreeAnalysis>(F)};
+        &DT, FAM.getCachedResult<PostDominatorTreeAnalysis>(F),
+        nullptr};
   };
 
   if (!runIPSCCP(M, DL, GetTLI, getAnalysis))
@@ -75,8 +77,9 @@ class IPSCCPLegacyPass : public ModulePass {
               F, DT,
               this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
                   F)),
-          nullptr,  // We cannot preserve the DT or PDT with the legacy pass
-          nullptr}; // manager, so set them to nullptr.
+          nullptr,  // We cannot preserve the LI, DT or PDT with the legacy pass
+          nullptr,  // manager, so set them to nullptr.
+          nullptr};
     };
 
     return runIPSCCP(M, DL, GetTLI, getAnalysis);
@@ -123,7 +126,8 @@ PreservedAnalyses FunctionSpecializationPass::run(Module &M,
     DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
     return {std::make_unique<PredicateInfo>(
                 F, DT, FAM.getResult<AssumptionAnalysis>(F)),
-            &DT, FAM.getCachedResult<PostDominatorTreeAnalysis>(F)};
+            &DT, FAM.getCachedResult<PostDominatorTreeAnalysis>(F),
+            &FAM.getResult<LoopAnalysis>(F)};
   };
 
   if (!runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis))
@@ -171,8 +175,9 @@ struct FunctionSpecializationLegacyPass : public ModulePass {
               F, DT,
               this->getAnalysis<AssumptionCacheTracker>().getAssumptionCache(
                   F)),
-          nullptr,  // We cannot preserve the DT or PDT with the legacy pass
-          nullptr}; // manager, so set them to nullptr.
+          nullptr, // We cannot preserve the LI, DT, or PDT with the legacy pass
+          nullptr, // manager, so set them to nullptr.
+          nullptr};
     };
     return runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis);
   }

diff  --git a/llvm/lib/Transforms/Utils/SCCPSolver.cpp b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
index 044e46f09821..a3455577a35c 100644
--- a/llvm/lib/Transforms/Utils/SCCPSolver.cpp
+++ b/llvm/lib/Transforms/Utils/SCCPSolver.cpp
@@ -339,6 +339,13 @@ class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
     return A->second.PredInfo->getPredicateInfoFor(I);
   }
 
+  const LoopInfo &getLoopInfo(Function &F) {
+    auto A = AnalysisResults.find(&F);
+    assert(A != AnalysisResults.end() && A->second.LI &&
+           "Need LoopInfo analysis results for function.");
+    return *A->second.LI;
+  }
+
   DomTreeUpdater getDTU(Function &F) {
     auto A = AnalysisResults.find(&F);
     assert(A != AnalysisResults.end() && "Need analysis results for function.");
@@ -1527,6 +1534,10 @@ const PredicateBase *SCCPSolver::getPredicateInfoFor(Instruction *I) {
   return Visitor->getPredicateInfoFor(I);
 }
 
+const LoopInfo &SCCPSolver::getLoopInfo(Function &F) {
+  return Visitor->getLoopInfo(F);
+}
+
 DomTreeUpdater SCCPSolver::getDTU(Function &F) { return Visitor->getDTU(F); }
 
 void SCCPSolver::trackValueOfGlobalVariable(GlobalVariable *GV) {


        


More information about the llvm-commits mailing list