[llvm] [JumpThreading] Add a hook to override the duplication threshold (PR #111826)

Pengcheng Wang via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 11 00:19:41 PDT 2024


https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/111826

>From 34004f739dbabd17528347aecc66c870a6688740 Mon Sep 17 00:00:00 2001
From: Wang Pengcheng <wangpengcheng.pp at bytedance.com>
Date: Thu, 10 Oct 2024 20:15:11 +0800
Subject: [PATCH] [JumpThreading] Add a hook to override options

We can override the default duplication threshold via the constructor
of `JumpThreadingPass` but it is unused in current pass pipeline.

So we remove the constructor and add a target hook so that targets
can override the default value.

And we also make `ImplicationSearchThreshold`, `PhiDuplicateThreshold`
overridable.
---
 .../llvm/Analysis/TargetTransformInfo.h       | 20 ++++++++
 .../llvm/Analysis/TargetTransformInfoImpl.h   |  6 +++
 .../llvm/Transforms/Scalar/JumpThreading.h    |  5 +-
 llvm/lib/Analysis/TargetTransformInfo.cpp     |  5 ++
 llvm/lib/Transforms/Scalar/JumpThreading.cpp  | 46 +++++++++++--------
 5 files changed, 59 insertions(+), 23 deletions(-)

diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 5c5da5e06c1bff..69cc7807354226 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1810,6 +1810,21 @@ class TargetTransformInfo {
   /// \return The maximum number of function arguments the target supports.
   unsigned getMaxNumArgs() const;
 
+  /// Returns options for jump threading.
+  struct JumpThreadingOptions {
+    // Max block size to duplicate for jump threading.
+    unsigned BBDupThreshold = 6;
+
+    // The number of predecessors to search for a stronger condition to use to
+    // thread over a weaker condition.
+    unsigned PredecessorSearchThreshold = 3;
+
+    // Max PHIs in BB to duplicate for jump threading.
+    unsigned PhiDupThreshold = 76;
+  };
+
+  JumpThreadingOptions getJumpThreadingOptions(bool MinSize) const;
+
   /// @}
 
 private:
@@ -2211,6 +2226,7 @@ class TargetTransformInfo::Concept {
   getVPLegalizationStrategy(const VPIntrinsic &PI) const = 0;
   virtual bool hasArmWideBranch(bool Thumb) const = 0;
   virtual unsigned getMaxNumArgs() const = 0;
+  virtual JumpThreadingOptions getJumpThreadingOptions(bool MinSize) const = 0;
 };
 
 template <typename T>
@@ -3004,6 +3020,10 @@ class TargetTransformInfo::Model final : public TargetTransformInfo::Concept {
   unsigned getMaxNumArgs() const override {
     return Impl.getMaxNumArgs();
   }
+
+  JumpThreadingOptions getJumpThreadingOptions(bool MinSize) const override {
+    return Impl.getJumpThreadingOptions(MinSize);
+  }
 };
 
 template <typename T>
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 6d3ce93acbe451..c7acc64707250d 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -995,6 +995,12 @@ class TargetTransformInfoImplBase {
 
   unsigned getMaxNumArgs() const { return UINT_MAX; }
 
+  TTI::JumpThreadingOptions getJumpThreadingOptions(bool MinSize) const {
+    // Reduce the number of instructions duplicated when optimizing strictly for
+    // size.
+    return {MinSize ? 3U : 6U};
+  }
+
 protected:
   // Obtain the minimum required size to hold the value (without the sign)
   // In case of a vector it returns the min required size for one element.
diff --git a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
index 7d11fc0ad69384..c94c9a38e7b9b6 100644
--- a/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
+++ b/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
@@ -95,11 +95,10 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
 #endif
 
   unsigned BBDupThreshold;
-  unsigned DefaultBBDupThreshold;
+  unsigned PredecessorSearchThreshold;
+  unsigned PhiDupThreshold;
 
 public:
-  JumpThreadingPass(int T = -1);
-
   // Glue for old PM.
   bool runImpl(Function &F, FunctionAnalysisManager *FAM,
                TargetLibraryInfo *TLI, TargetTransformInfo *TTI,
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 3dc29fc7cd77b1..f13aecd1a6486f 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -1328,6 +1328,11 @@ unsigned TargetTransformInfo::getMaxNumArgs() const {
   return TTIImpl->getMaxNumArgs();
 }
 
+TargetTransformInfo::JumpThreadingOptions
+TargetTransformInfo::getJumpThreadingOptions(bool MinSize) const {
+  return TTIImpl->getJumpThreadingOptions(MinSize);
+}
+
 bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const {
   return TTIImpl->shouldExpandReduction(II);
 }
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 7a0b661a07799a..c844c41d79f1af 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -107,10 +107,6 @@ static cl::opt<bool> ThreadAcrossLoopHeaders(
     cl::desc("Allow JumpThreading to thread across loop headers, for testing"),
     cl::init(false), cl::Hidden);
 
-JumpThreadingPass::JumpThreadingPass(int T) {
-  DefaultBBDupThreshold = (T == -1) ? BBDuplicateThreshold : unsigned(T);
-}
-
 // Update branch probability information according to conditional
 // branch probability. This is usually made possible for cloned branches
 // in inline instances by the context specific profile in the caller.
@@ -300,14 +296,23 @@ bool JumpThreadingPass::runImpl(Function &F_, FunctionAnalysisManager *FAM_,
       Intrinsic::getName(Intrinsic::experimental_guard));
   HasGuards = GuardDecl && !GuardDecl->use_empty();
 
-  // Reduce the number of instructions duplicated when optimizing strictly for
-  // size.
+  TargetTransformInfo::JumpThreadingOptions Options =
+      TTI->getJumpThreadingOptions(F->hasFnAttribute(Attribute::MinSize));
+
   if (BBDuplicateThreshold.getNumOccurrences())
     BBDupThreshold = BBDuplicateThreshold;
-  else if (F->hasFnAttribute(Attribute::MinSize))
-    BBDupThreshold = 3;
   else
-    BBDupThreshold = DefaultBBDupThreshold;
+    BBDupThreshold = Options.BBDupThreshold;
+
+  if (ImplicationSearchThreshold.getNumOccurrences())
+    PredecessorSearchThreshold = ImplicationSearchThreshold;
+  else
+    PredecessorSearchThreshold = Options.PredecessorSearchThreshold;
+
+  if (PhiDuplicateThreshold.getNumOccurrences())
+    PhiDupThreshold = PhiDuplicateThreshold;
+  else
+    PhiDupThreshold = Options.PhiDupThreshold;
 
   // JumpThreading must not processes blocks unreachable from entry. It's a
   // waste of compute time and can potentially lead to hangs.
@@ -427,7 +432,8 @@ static bool replaceFoldableUses(Instruction *Cond, Value *ToVal,
 static unsigned getJumpThreadDuplicationCost(const TargetTransformInfo *TTI,
                                              BasicBlock *BB,
                                              Instruction *StopAt,
-                                             unsigned Threshold) {
+                                             unsigned BBDupThreshold,
+                                             unsigned PhiDupThreshold) {
   assert(StopAt->getParent() == BB && "Not an instruction from proper BB?");
 
   // Do not duplicate the BB if it has a lot of PHI nodes.
@@ -440,7 +446,7 @@ static unsigned getJumpThreadDuplicationCost(const TargetTransformInfo *TTI,
       FirstNonPHI = &I;
       break;
     }
-    if (++PhiCount > PhiDuplicateThreshold)
+    if (++PhiCount > PhiDupThreshold)
       return ~0U;
   }
 
@@ -465,7 +471,7 @@ static unsigned getJumpThreadDuplicationCost(const TargetTransformInfo *TTI,
 
   // Bump the threshold up so the early exit from the loop doesn't skip the
   // terminator-based Size adjustment at the end.
-  Threshold += Bonus;
+  BBDupThreshold += Bonus;
 
   // Sum up the cost of each instruction until we get to the terminator.  Don't
   // include the terminator because the copy won't include it.
@@ -473,7 +479,7 @@ static unsigned getJumpThreadDuplicationCost(const TargetTransformInfo *TTI,
   for (; &*I != StopAt; ++I) {
 
     // Stop scanning the block if we've reached the threshold.
-    if (Size > Threshold)
+    if (Size > BBDupThreshold)
       return Size;
 
     // Bail out if this instruction gives back a token type, it is not possible
@@ -1166,7 +1172,7 @@ bool JumpThreadingPass::processImpliedCondition(BasicBlock *BB) {
 
   auto &DL = BB->getDataLayout();
 
-  while (CurrentPred && Iter++ < ImplicationSearchThreshold) {
+  while (CurrentPred && Iter++ < PredecessorSearchThreshold) {
     auto *PBI = dyn_cast<BranchInst>(CurrentPred->getTerminator());
     if (!PBI || !PBI->isConditional())
       return false;
@@ -2237,9 +2243,9 @@ bool JumpThreadingPass::maybethreadThroughTwoBasicBlocks(BasicBlock *BB,
 
   // Compute the cost of duplicating BB and PredBB.
   unsigned BBCost = getJumpThreadDuplicationCost(
-      TTI, BB, BB->getTerminator(), BBDupThreshold);
+      TTI, BB, BB->getTerminator(), BBDupThreshold, PhiDupThreshold);
   unsigned PredBBCost = getJumpThreadDuplicationCost(
-      TTI, PredBB, PredBB->getTerminator(), BBDupThreshold);
+      TTI, PredBB, PredBB->getTerminator(), BBDupThreshold, PhiDupThreshold);
 
   // Give up if costs are too high.  We need to check BBCost and PredBBCost
   // individually before checking their sum because getJumpThreadDuplicationCost
@@ -2355,7 +2361,7 @@ bool JumpThreadingPass::tryThreadEdge(
   }
 
   unsigned JumpThreadCost = getJumpThreadDuplicationCost(
-      TTI, BB, BB->getTerminator(), BBDupThreshold);
+      TTI, BB, BB->getTerminator(), BBDupThreshold, PhiDupThreshold);
   if (JumpThreadCost > BBDupThreshold) {
     LLVM_DEBUG(dbgs() << "  Not threading BB '" << BB->getName()
                       << "' - Cost is too high: " << JumpThreadCost << "\n");
@@ -2629,7 +2635,7 @@ bool JumpThreadingPass::duplicateCondBranchOnPHIIntoPred(
   }
 
   unsigned DuplicationCost = getJumpThreadDuplicationCost(
-      TTI, BB, BB->getTerminator(), BBDupThreshold);
+      TTI, BB, BB->getTerminator(), BBDupThreshold, PhiDupThreshold);
   if (DuplicationCost > BBDupThreshold) {
     LLVM_DEBUG(dbgs() << "  Not duplicating BB '" << BB->getName()
                       << "' - Cost is too high: " << DuplicationCost << "\n");
@@ -3079,8 +3085,8 @@ bool JumpThreadingPass::threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
 
   ValueToValueMapTy UnguardedMapping, GuardedMapping;
   Instruction *AfterGuard = Guard->getNextNode();
-  unsigned Cost =
-      getJumpThreadDuplicationCost(TTI, BB, AfterGuard, BBDupThreshold);
+  unsigned Cost = getJumpThreadDuplicationCost(TTI, BB, AfterGuard,
+                                               BBDupThreshold, PhiDupThreshold);
   if (Cost > BBDupThreshold)
     return false;
   // Duplicate all instructions before the guard and the guard itself to the



More information about the llvm-commits mailing list