diff --git a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp index 90065e053b62..7b93474e4dc7 100644 --- a/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp +++ b/llvm/lib/Analysis/IndirectCallPromotionAnalysis.cpp @@ -31,12 +31,18 @@ static cl::opt ICPRemainingPercentThreshold( // The percent threshold for the direct-call target (this call site vs the // total call count) for it to be considered as the promotion target. -static cl::opt +static cl::opt ICPTotalPercentThreshold("icp-total-percent-threshold", cl::init(5), cl::Hidden, 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 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 @@ -51,7 +57,8 @@ cl::opt 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 3b0e3250cd6d..ab8ebefd204d 100644 --- a/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll +++ b/llvm/test/Transforms/PGOProfile/indirect_call_promotion.ll @@ -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-15 +; 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-10 ; PASS-REMARK: remark: :0:0: Promote indirect call to func4 with count 1030 out of 1600 ; PASS-REMARK: remark: :0:0: Promote indirect call to func2 with count 410 out of 570 @@ -12,6 +16,16 @@ ; PASS2-REMARK-NOT: remark: :0:0: Promote indirect call to func3 ; PASS2-REMARK-NOT: remark: :0:0: Promote indirect call to func1 +; MIN-COUNT-15: remark: :0:0: Promote indirect call to func4 with count 1030 out of 1600 +; MIN-COUNT-15: remark: :0:0: Promote indirect call to func2 with count 410 out of 570 +; MIN-COUNT-15: remark: :0:0: Promote indirect call to func3 with count 150 out of 160 +; MIN-COUNT-15-NOT: remark: :0:0: Promote indirect call to func1 + +; MIN-COUNT-10: remark: :0:0: Promote indirect call to func4 with count 1030 out of 1600 +; MIN-COUNT-10: remark: :0:0: Promote indirect call to func2 with count 410 out of 570 +; MIN-COUNT-10: remark: :0:0: Promote indirect call to func3 with count 150 out of 160 +; MIN-COUNT-10: remark: :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"