Skip to content

Add minimum count threshold for indirect call promotion #145282

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

snehasish
Copy link
Contributor

@snehasish snehasish commented Jun 23, 2025

Allow users to set the minimum absolute count for indirect call promotion. This is primarily meant to be control indirect call promotion for synthetic vp metadata introduced in #141164 for use by MemProf.

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

This adds a new command-line option -icp-minimum-count-threshold to prevent
promotion of indirect call candidates with very low absolute counts, even
if they meet the percentage-based profitability thresholds.

Currently, candidates with counts as low as 1-2 calls can be promoted if
they represent a significant percentage of the call site. This can lead to
unprofitable micro-optimizations that increase code size without meaningful
performance benefits.

The new threshold defaults to 0 to maintain backward compatibility but can
be set to values like 5-20 for production use to filter out statistically
insignificant candidates.

Added comprehensive test coverage for the new threshold including negative
tests (blocking low-count promotions), positive tests (allowing high-count
promotions), and edge cases (threshold exactly at count value).
@snehasish snehasish marked this pull request as ready for review June 26, 2025 16:27
@llvmbot llvmbot added PGO Profile Guided Optimizations llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms labels Jun 26, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 26, 2025

@llvm/pr-subscribers-pgo

@llvm/pr-subscribers-llvm-transforms

Author: Snehasish Kumar (snehasish)

Changes

Allow users to set the minimum absolute count for indirect call promotion. This is primarily meant to be control indirect call promotion for synthetic vp metadata introduced in #141164 for use by MemProf.


Full diff: https://github.com/llvm/llvm-project/pull/145282.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp (+8-1)
  • (modified) llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll (+21)
diff --git a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
index 90065e053b629..861dc0d364b84 100644
--- a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
+++ b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
@@ -37,6 +37,12 @@ static cl::opt<unsigned>
                              cl::desc("The percentage threshold against total "
                                       "count for the promotion"));
 
+// Set the minimum absolute count threshold for indirect call promotion.
+// Candidates with counts below this threshold will not be promoted.
+static cl::opt<unsigned> ICPMinimumCountThreshold(
+    "icp-minimum-count-threshold", cl::init(0), cl::Hidden,
+    cl::desc("Minimum absolute count for promotion candidate"));
+
 // Set the maximum number of targets to promote for a single indirect-call
 // callsite.
 static cl::opt<unsigned>
@@ -51,7 +57,8 @@ cl::opt<unsigned> MaxNumVTableAnnotations(
 bool ICallPromotionAnalysis::isPromotionProfitable(uint64_t Count,
                                                    uint64_t TotalCount,
                                                    uint64_t RemainingCount) {
-  return Count * 100 >= ICPRemainingPercentThreshold * RemainingCount &&
+  return Count >= ICPMinimumCountThreshold &&
+         Count * 100 >= ICPRemainingPercentThreshold * RemainingCount &&
          Count * 100 >= ICPTotalPercentThreshold * TotalCount;
 }
 
diff --git a/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll b/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll
index 3b0e3250cd6df..7f1fea9d1386a 100644
--- a/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll
+++ b/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll
@@ -1,6 +1,12 @@
 ; RUN: opt < %s -passes=pgo-icall-prom -S -icp-total-percent-threshold=50 | FileCheck %s --check-prefix=ICALL-PROM
 ; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=PASS-REMARK
 ; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=20 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=PASS2-REMARK
+; Test minimum count threshold - should prevent func1 promotion (count 10 < threshold 15)
+; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-minimum-count-threshold=15 -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=MIN-COUNT-BLOCK
+; Test minimum count threshold - should allow func4 promotion (count 1030 > threshold 15) 
+; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-minimum-count-threshold=15 -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=MIN-COUNT-ALLOW
+; Test edge case - threshold exactly at count value
+; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-minimum-count-threshold=10 -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=MIN-COUNT-EDGE
 
 ; PASS-REMARK: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
 ; PASS-REMARK: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
@@ -12,6 +18,21 @@
 ; PASS2-REMARK-NOT: remark: <unknown>:0:0: Promote indirect call to func3
 ; PASS2-REMARK-NOT: remark: <unknown>:0:0: Promote indirect call to func1
 
+; MIN-COUNT-BLOCK: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
+; MIN-COUNT-BLOCK: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
+; MIN-COUNT-BLOCK: remark: <unknown>:0:0: Promote indirect call to func3 with count 150 out of 160
+; MIN-COUNT-BLOCK-NOT: remark: <unknown>:0:0: Promote indirect call to func1
+
+; MIN-COUNT-ALLOW: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
+; MIN-COUNT-ALLOW: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
+; MIN-COUNT-ALLOW: remark: <unknown>:0:0: Promote indirect call to func3 with count 150 out of 160
+; MIN-COUNT-ALLOW-NOT: remark: <unknown>:0:0: Promote indirect call to func1
+
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func3 with count 150 out of 160
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func1 with count 10 out of 10
+
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 

@llvmbot
Copy link
Member

llvmbot commented Jun 26, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Snehasish Kumar (snehasish)

Changes

Allow users to set the minimum absolute count for indirect call promotion. This is primarily meant to be control indirect call promotion for synthetic vp metadata introduced in #141164 for use by MemProf.


Full diff: https://github.com/llvm/llvm-project/pull/145282.diff

2 Files Affected:

  • (modified) llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp (+8-1)
  • (modified) llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll (+21)
diff --git a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
index 90065e053b629..861dc0d364b84 100644
--- a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
+++ b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp
@@ -37,6 +37,12 @@ static cl::opt<unsigned>
                              cl::desc("The percentage threshold against total "
                                       "count for the promotion"));
 
+// Set the minimum absolute count threshold for indirect call promotion.
+// Candidates with counts below this threshold will not be promoted.
+static cl::opt<unsigned> ICPMinimumCountThreshold(
+    "icp-minimum-count-threshold", cl::init(0), cl::Hidden,
+    cl::desc("Minimum absolute count for promotion candidate"));
+
 // Set the maximum number of targets to promote for a single indirect-call
 // callsite.
 static cl::opt<unsigned>
@@ -51,7 +57,8 @@ cl::opt<unsigned> MaxNumVTableAnnotations(
 bool ICallPromotionAnalysis::isPromotionProfitable(uint64_t Count,
                                                    uint64_t TotalCount,
                                                    uint64_t RemainingCount) {
-  return Count * 100 >= ICPRemainingPercentThreshold * RemainingCount &&
+  return Count >= ICPMinimumCountThreshold &&
+         Count * 100 >= ICPRemainingPercentThreshold * RemainingCount &&
          Count * 100 >= ICPTotalPercentThreshold * TotalCount;
 }
 
diff --git a/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll b/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll
index 3b0e3250cd6df..7f1fea9d1386a 100644
--- a/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll
+++ b/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll
@@ -1,6 +1,12 @@
 ; RUN: opt < %s -passes=pgo-icall-prom -S -icp-total-percent-threshold=50 | FileCheck %s --check-prefix=ICALL-PROM
 ; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=PASS-REMARK
 ; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=20 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=PASS2-REMARK
+; Test minimum count threshold - should prevent func1 promotion (count 10 < threshold 15)
+; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-minimum-count-threshold=15 -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=MIN-COUNT-BLOCK
+; Test minimum count threshold - should allow func4 promotion (count 1030 > threshold 15) 
+; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-minimum-count-threshold=15 -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=MIN-COUNT-ALLOW
+; Test edge case - threshold exactly at count value
+; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-minimum-count-threshold=10 -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=MIN-COUNT-EDGE
 
 ; PASS-REMARK: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
 ; PASS-REMARK: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
@@ -12,6 +18,21 @@
 ; PASS2-REMARK-NOT: remark: <unknown>:0:0: Promote indirect call to func3
 ; PASS2-REMARK-NOT: remark: <unknown>:0:0: Promote indirect call to func1
 
+; MIN-COUNT-BLOCK: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
+; MIN-COUNT-BLOCK: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
+; MIN-COUNT-BLOCK: remark: <unknown>:0:0: Promote indirect call to func3 with count 150 out of 160
+; MIN-COUNT-BLOCK-NOT: remark: <unknown>:0:0: Promote indirect call to func1
+
+; MIN-COUNT-ALLOW: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
+; MIN-COUNT-ALLOW: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
+; MIN-COUNT-ALLOW: remark: <unknown>:0:0: Promote indirect call to func3 with count 150 out of 160
+; MIN-COUNT-ALLOW-NOT: remark: <unknown>:0:0: Promote indirect call to func1
+
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func4 with count 1030 out of 1600
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func2 with count 410 out of 570
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func3 with count 150 out of 160
+; MIN-COUNT-EDGE: remark: <unknown>:0:0: Promote indirect call to func1 with count 10 out of 10
+
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 

@snehasish snehasish force-pushed the users/snehasish/06-22-add_minimum_count_threshold_for_indirect_call_promotion branch from cb1d8ec to 5b0b5ff Compare June 26, 2025 17:25
Copy link
Contributor

@teresajohnson teresajohnson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with a couple of nits

@@ -37,6 +37,12 @@ static cl::opt<unsigned>
cl::desc("The percentage threshold against total "
"count for the promotion"));

// Set the minimum absolute count threshold for indirect call promotion.
// Candidates with counts below this threshold will not be promoted.
static cl::opt<unsigned> ICPMinimumCountThreshold(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be uint64_t to match the type of the Count it is being compared against?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -1,6 +1,10 @@
; RUN: opt < %s -passes=pgo-icall-prom -S -icp-total-percent-threshold=50 | FileCheck %s --check-prefix=ICALL-PROM
; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=PASS-REMARK
; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=20 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=PASS2-REMARK
; Test minimum count threshold - should prevent func1 promotion (count 10 < threshold 15)
; RUN: opt < %s -passes=pgo-icall-prom -S -pass-remarks=pgo-icall-prom -icp-minimum-count-threshold=15 -icp-remaining-percent-threshold=0 -icp-total-percent-threshold=0 -icp-max-prom=4 2>&1 | FileCheck %s --check-prefix=MIN-COUNT-ALLOW
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: The check prefix names for the new invocations are unclear (e.g. ALLOW means allow what?). Maybe just explicitly make them "MIN-COUNT-15" and "MIN-COUNT-10".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, updated the suffix.

Copy link
Contributor Author

snehasish commented Jun 26, 2025

Merge activity

  • Jun 26, 7:09 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 26, 7:11 PM UTC: @snehasish merged this pull request with Graphite.

@snehasish snehasish merged commit 70233c6 into main Jun 26, 2025
5 of 7 checks passed
@snehasish snehasish deleted the users/snehasish/06-22-add_minimum_count_threshold_for_indirect_call_promotion branch June 26, 2025 19:11
anthonyhatran pushed a commit to anthonyhatran/llvm-project that referenced this pull request Jun 26, 2025
Allow users to set the minimum absolute count for indirect call promotion. This is primarily meant to be control indirect call promotion for synthetic vp metadata introduced in llvm#141164 for use by MemProf.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding llvm:transforms PGO Profile Guided Optimizations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants