[llvm] [CodeGen] Preserve branch weights from PGO profile during instruction selection at -O0 (PR #161620)
Grigory Pastukhov via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 9 10:34:22 PDT 2025
https://github.com/grigorypas updated https://github.com/llvm/llvm-project/pull/161620
>From c55f594bdb1c22cb1cc6e9214b5a62f5d9426402 Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <gpastukhov at meta.com>
Date: Wed, 1 Oct 2025 15:39:11 -0700
Subject: [PATCH 1/7] Calculate edge weights in MIR if PGO is available in O0
---
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 15 +++---
llvm/test/CodeGen/AArch64/O0-pipeline.ll | 6 +++
llvm/test/CodeGen/AMDGPU/llc-pipeline.ll | 5 ++
llvm/test/CodeGen/LoongArch/O0-pipeline.ll | 6 +++
llvm/test/CodeGen/PowerPC/O0-pipeline.ll | 6 +++
llvm/test/CodeGen/RISCV/O0-pipeline.ll | 6 +++
llvm/test/CodeGen/X86/O0-pipeline.ll | 6 +++
llvm/test/CodeGen/X86/pgo-profile-o0.ll | 49 +++++++++++++++++++
8 files changed, 91 insertions(+), 8 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/pgo-profile-o0.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index e61558c59bf0d..c7728ef1d28ec 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -398,15 +398,14 @@ void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
- if (UseMBPI && OptLevel != CodeGenOptLevel::None)
- AU.addRequired<BranchProbabilityInfoWrapperPass>();
+ if (UseMBPI)
+ AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.addRequired<ProfileSummaryInfoWrapperPass>();
// AssignmentTrackingAnalysis only runs if assignment tracking is enabled for
// the module.
AU.addRequired<AssignmentTrackingAnalysis>();
AU.addPreserved<AssignmentTrackingAnalysis>();
- if (OptLevel != CodeGenOptLevel::None)
- LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
+ LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -469,7 +468,7 @@ void SelectionDAGISel::initializeAnalysisResults(
auto *PSI = MAMP.getCachedResult<ProfileSummaryAnalysis>(*Fn.getParent());
BlockFrequencyInfo *BFI = nullptr;
FAM.getResult<BlockFrequencyAnalysis>(Fn);
- if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None)
+ if (PSI && PSI->hasProfileSummary())
BFI = &FAM.getResult<BlockFrequencyAnalysis>(Fn);
FunctionVarLocs const *FnVarLocs = nullptr;
@@ -487,7 +486,7 @@ void SelectionDAGISel::initializeAnalysisResults(
// into account). That's unfortunate but OK because it just means we won't
// ask for passes that have been required anyway.
- if (UseMBPI && OptLevel != CodeGenOptLevel::None)
+ if (UseMBPI && (Fn.hasProfileData() || OptLevel != CodeGenOptLevel::None))
FuncInfo->BPI = &FAM.getResult<BranchProbabilityAnalysis>(Fn);
else
FuncInfo->BPI = nullptr;
@@ -523,7 +522,7 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
AC = &MFP.getAnalysis<AssumptionCacheTracker>().getAssumptionCache(Fn);
auto *PSI = &MFP.getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
BlockFrequencyInfo *BFI = nullptr;
- if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOptLevel::None)
+ if (PSI && PSI->hasProfileSummary())
BFI = &MFP.getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
FunctionVarLocs const *FnVarLocs = nullptr;
@@ -544,7 +543,7 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
// into account). That's unfortunate but OK because it just means we won't
// ask for passes that have been required anyway.
- if (UseMBPI && OptLevel != CodeGenOptLevel::None)
+ if (UseMBPI && (Fn.hasProfileData() || OptLevel != CodeGenOptLevel::None))
FuncInfo->BPI =
&MFP.getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
else
diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll
index abc67eec32391..6029d3d4927ca 100644
--- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll
+++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll
@@ -50,7 +50,13 @@
; CHECK-NEXT: Analysis for ComputingKnownBits
; CHECK-NEXT: InstructionSelect
; CHECK-NEXT: ResetMachineFunction
+; CHECK-NEXT: Dominator Tree Construction
+; CHECK-NEXT: Natural Loop Information
+; CHECK-NEXT: Post-Dominator Tree Construction
+; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
+; CHECK-NEXT: Lazy Branch Probability Analysis
+; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: AArch64 Instruction Selection
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
; CHECK-NEXT: Local Stack Slot Allocation
diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
index 65d0102a9d0dc..471c90ec73012 100644
--- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
+++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
@@ -94,7 +94,12 @@
; GCN-O0-NEXT: Dominator Tree Construction
; GCN-O0-NEXT: Cycle Info Analysis
; GCN-O0-NEXT: Uniformity Analysis
+; GCN-O0-NEXT: Natural Loop Information
+; GCN-O0-NEXT: Post-Dominator Tree Construction
+; GCN-O0-NEXT: Branch Probability Analysis
; GCN-O0-NEXT: Assignment Tracking Analysis
+; GCN-O0-NEXT: Lazy Branch Probability Analysis
+; GCN-O0-NEXT: Lazy Block Frequency Analysis
; GCN-O0-NEXT: AMDGPU DAG->DAG Pattern Instruction Selection
; GCN-O0-NEXT: MachineDominator Tree Construction
; GCN-O0-NEXT: SI Fix SGPR copies
diff --git a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
index 9006b5c8d6fe1..7f368e59133a0 100644
--- a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
+++ b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
@@ -34,7 +34,13 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
+; CHECK-NEXT: Dominator Tree Construction
+; CHECK-NEXT: Natural Loop Information
+; CHECK-NEXT: Post-Dominator Tree Construction
+; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
+; CHECK-NEXT: Lazy Branch Probability Analysis
+; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: LoongArch DAG->DAG Pattern Instruction Selection
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
; CHECK-NEXT: Local Stack Slot Allocation
diff --git a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
index 38b1074e55d22..a4a6d831d64fc 100644
--- a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
+++ b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
@@ -33,7 +33,13 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
+; CHECK-NEXT: Dominator Tree Construction
+; CHECK-NEXT: Natural Loop Information
+; CHECK-NEXT: Post-Dominator Tree Construction
+; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
+; CHECK-NEXT: Lazy Branch Probability Analysis
+; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: PowerPC DAG->DAG Pattern Instruction Selection
; CHECK-NEXT: PowerPC VSX Copy Legalization
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
index 8714b286374a5..83379754a7507 100644
--- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
@@ -35,7 +35,13 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
+; CHECK-NEXT: Dominator Tree Construction
+; CHECK-NEXT: Natural Loop Information
+; CHECK-NEXT: Post-Dominator Tree Construction
+; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
+; CHECK-NEXT: Lazy Branch Probability Analysis
+; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: RISC-V DAG->DAG Pattern Instruction Selection
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
; CHECK-NEXT: Local Stack Slot Allocation
diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll
index 0fbfb42d2a4dd..6aea51d8e87dc 100644
--- a/llvm/test/CodeGen/X86/O0-pipeline.ll
+++ b/llvm/test/CodeGen/X86/O0-pipeline.ll
@@ -35,7 +35,13 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
+; CHECK-NEXT: Dominator Tree Construction
+; CHECK-NEXT: Natural Loop Information
+; CHECK-NEXT: Post-Dominator Tree Construction
+; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
+; CHECK-NEXT: Lazy Branch Probability Analysis
+; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: X86 DAG->DAG Instruction Selection
; CHECK-NEXT: X86 PIC Global Base Reg Initialization
; CHECK-NEXT: Argument Stack Rebase
diff --git a/llvm/test/CodeGen/X86/pgo-profile-o0.ll b/llvm/test/CodeGen/X86/pgo-profile-o0.ll
new file mode 100644
index 0000000000000..009721fcbba78
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pgo-profile-o0.ll
@@ -0,0 +1,49 @@
+; RUN: llc -mtriple=x86_64-- -O0 -debug-pass=Structure %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=PASSES
+; RUN: llc -mtriple=x86_64-- -O0 -debug-only=branch-prob %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=BRANCH_PROB
+; RUN: llc -mtriple=x86_64-- -O0 -stop-after=finalize-isel %s -o - | FileCheck %s --check-prefix=MIR
+
+; REQUIRES: asserts
+
+; This test verifies that PGO profile information (branch weights) is preserved
+; during instruction selection at -O0.
+
+; Test function with explicit branch weights from PGO.
+define i32 @test_pgo_preservation(i32 %x) !prof !15 {
+entry:
+ %cmp = icmp sgt i32 %x, 10
+ ; This branch has bias: 97 taken vs 3 not taken
+ br i1 %cmp, label %if.then, label %if.else, !prof !16
+
+if.then:
+ ; Hot path - should have high frequency
+ %add = add nsw i32 %x, 100
+ br label %if.end
+
+if.else:
+ ; Cold path - should have low frequency
+ %sub = sub nsw i32 %x, 50
+ br label %if.end
+
+if.end:
+ %result = phi i32 [ %add, %if.then ], [ %sub, %if.else ]
+ ret i32 %result
+}
+
+; Profile metadata with branch weights 97:3.
+!15 = !{!"function_entry_count", i64 100}
+!16 = !{!"branch_weights", i32 97, i32 3}
+
+; Verify that Branch Probability Analysis runs at O0.
+; PASSES: Branch Probability Analysis
+
+; Verify that the branch probabilities reflect the exact profile data.
+; BRANCH_PROB: ---- Branch Probability Info : test_pgo_preservation ----
+; BRANCH_PROB: set edge entry -> 0 successor probability to {{.*}} = 97.00%
+; BRANCH_PROB: set edge entry -> 1 successor probability to {{.*}} = 3.00%
+
+; Verify that machine IR preserves the branch probabilities from profile data
+; MIR: bb.0.entry:
+; MIR-NEXT: successors: %bb.{{[0-9]+}}({{0x03d70a3d|0x7c28f5c3}}), %bb.{{[0-9]+}}({{0x7c28f5c3|0x03d70a3d}})
+; The two successor probability values should be:
+; - 0x7c28f5c3: approximately 97% (high probability successor)
+; - 0x03d70a3d: approximately 3% (low probability successor)
>From 6e4ebda9189867a3c076bcf1f7b4ffce6328a8a7 Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <gpastukhov at meta.com>
Date: Thu, 2 Oct 2025 16:06:53 -0700
Subject: [PATCH 2/7] Register analysis only if PGO is present
---
.../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 28 +++-
llvm/test/CodeGen/AArch64/O0-pipeline.ll | 6 -
llvm/test/CodeGen/AMDGPU/llc-pipeline.ll | 5 -
llvm/test/CodeGen/LoongArch/O0-pipeline.ll | 6 -
llvm/test/CodeGen/PowerPC/O0-pipeline.ll | 6 -
llvm/test/CodeGen/RISCV/O0-pipeline.ll | 6 -
llvm/test/CodeGen/X86/O0-pipeline.ll | 6 -
llvm/test/CodeGen/X86/pgo-profile-o0.ll | 6 +-
llvm/tools/llc/llc.cpp | 146 ++++++++++++++++++
9 files changed, 171 insertions(+), 44 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index c7728ef1d28ec..1b5e2d987dcb5 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -229,6 +229,17 @@ static bool dontUseFastISelFor(const Function &Fn) {
});
}
+static bool shouldRegisterPGOPasses(const TargetMachine &TM,
+ CodeGenOptLevel OptLevel) {
+ bool RegisterPGOPasses = OptLevel != CodeGenOptLevel::None;
+ if (!RegisterPGOPasses && TM.getPGOOption()) {
+ const PGOOptions &Options = *TM.getPGOOption();
+ RegisterPGOPasses = Options.Action != PGOOptions::PGOAction::NoAction ||
+ Options.CSAction != PGOOptions::CSPGOAction::NoCSAction;
+ }
+ return RegisterPGOPasses;
+}
+
namespace llvm {
//===--------------------------------------------------------------------===//
@@ -390,6 +401,8 @@ SelectionDAGISel::~SelectionDAGISel() { delete CurDAG; }
void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
CodeGenOptLevel OptLevel = Selector->OptLevel;
+ bool RegisterPGOPasses =
+ shouldRegisterPGOPasses(Selector->TM, Selector->OptLevel);
if (OptLevel != CodeGenOptLevel::None)
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<GCModuleInfo>();
@@ -398,14 +411,15 @@ void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetLibraryInfoWrapperPass>();
AU.addRequired<TargetTransformInfoWrapperPass>();
AU.addRequired<AssumptionCacheTracker>();
- if (UseMBPI)
+ if (UseMBPI && RegisterPGOPasses)
AU.addRequired<BranchProbabilityInfoWrapperPass>();
AU.addRequired<ProfileSummaryInfoWrapperPass>();
// AssignmentTrackingAnalysis only runs if assignment tracking is enabled for
// the module.
AU.addRequired<AssignmentTrackingAnalysis>();
AU.addPreserved<AssignmentTrackingAnalysis>();
- LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
+ if (RegisterPGOPasses)
+ LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU);
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -458,6 +472,7 @@ void SelectionDAGISel::initializeAnalysisResults(
(void)MatchFilterFuncName;
#endif
+ bool RegisterPGOPasses = shouldRegisterPGOPasses(TM, OptLevel);
TII = MF->getSubtarget().getInstrInfo();
TLI = MF->getSubtarget().getTargetLowering();
RegInfo = &MF->getRegInfo();
@@ -468,7 +483,7 @@ void SelectionDAGISel::initializeAnalysisResults(
auto *PSI = MAMP.getCachedResult<ProfileSummaryAnalysis>(*Fn.getParent());
BlockFrequencyInfo *BFI = nullptr;
FAM.getResult<BlockFrequencyAnalysis>(Fn);
- if (PSI && PSI->hasProfileSummary())
+ if (PSI && PSI->hasProfileSummary() && RegisterPGOPasses)
BFI = &FAM.getResult<BlockFrequencyAnalysis>(Fn);
FunctionVarLocs const *FnVarLocs = nullptr;
@@ -486,7 +501,7 @@ void SelectionDAGISel::initializeAnalysisResults(
// into account). That's unfortunate but OK because it just means we won't
// ask for passes that have been required anyway.
- if (UseMBPI && (Fn.hasProfileData() || OptLevel != CodeGenOptLevel::None))
+ if (UseMBPI && RegisterPGOPasses)
FuncInfo->BPI = &FAM.getResult<BranchProbabilityAnalysis>(Fn);
else
FuncInfo->BPI = nullptr;
@@ -512,6 +527,7 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
(void)MatchFilterFuncName;
#endif
+ bool RegisterPGOPasses = shouldRegisterPGOPasses(TM, OptLevel);
TII = MF->getSubtarget().getInstrInfo();
TLI = MF->getSubtarget().getTargetLowering();
RegInfo = &MF->getRegInfo();
@@ -522,7 +538,7 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
AC = &MFP.getAnalysis<AssumptionCacheTracker>().getAssumptionCache(Fn);
auto *PSI = &MFP.getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
BlockFrequencyInfo *BFI = nullptr;
- if (PSI && PSI->hasProfileSummary())
+ if (PSI && PSI->hasProfileSummary() && RegisterPGOPasses)
BFI = &MFP.getAnalysis<LazyBlockFrequencyInfoPass>().getBFI();
FunctionVarLocs const *FnVarLocs = nullptr;
@@ -543,7 +559,7 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
// into account). That's unfortunate but OK because it just means we won't
// ask for passes that have been required anyway.
- if (UseMBPI && (Fn.hasProfileData() || OptLevel != CodeGenOptLevel::None))
+ if (UseMBPI && RegisterPGOPasses)
FuncInfo->BPI =
&MFP.getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
else
diff --git a/llvm/test/CodeGen/AArch64/O0-pipeline.ll b/llvm/test/CodeGen/AArch64/O0-pipeline.ll
index 6029d3d4927ca..abc67eec32391 100644
--- a/llvm/test/CodeGen/AArch64/O0-pipeline.ll
+++ b/llvm/test/CodeGen/AArch64/O0-pipeline.ll
@@ -50,13 +50,7 @@
; CHECK-NEXT: Analysis for ComputingKnownBits
; CHECK-NEXT: InstructionSelect
; CHECK-NEXT: ResetMachineFunction
-; CHECK-NEXT: Dominator Tree Construction
-; CHECK-NEXT: Natural Loop Information
-; CHECK-NEXT: Post-Dominator Tree Construction
-; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
-; CHECK-NEXT: Lazy Branch Probability Analysis
-; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: AArch64 Instruction Selection
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
; CHECK-NEXT: Local Stack Slot Allocation
diff --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
index 471c90ec73012..65d0102a9d0dc 100644
--- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
+++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
@@ -94,12 +94,7 @@
; GCN-O0-NEXT: Dominator Tree Construction
; GCN-O0-NEXT: Cycle Info Analysis
; GCN-O0-NEXT: Uniformity Analysis
-; GCN-O0-NEXT: Natural Loop Information
-; GCN-O0-NEXT: Post-Dominator Tree Construction
-; GCN-O0-NEXT: Branch Probability Analysis
; GCN-O0-NEXT: Assignment Tracking Analysis
-; GCN-O0-NEXT: Lazy Branch Probability Analysis
-; GCN-O0-NEXT: Lazy Block Frequency Analysis
; GCN-O0-NEXT: AMDGPU DAG->DAG Pattern Instruction Selection
; GCN-O0-NEXT: MachineDominator Tree Construction
; GCN-O0-NEXT: SI Fix SGPR copies
diff --git a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
index 7f368e59133a0..9006b5c8d6fe1 100644
--- a/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
+++ b/llvm/test/CodeGen/LoongArch/O0-pipeline.ll
@@ -34,13 +34,7 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
-; CHECK-NEXT: Dominator Tree Construction
-; CHECK-NEXT: Natural Loop Information
-; CHECK-NEXT: Post-Dominator Tree Construction
-; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
-; CHECK-NEXT: Lazy Branch Probability Analysis
-; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: LoongArch DAG->DAG Pattern Instruction Selection
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
; CHECK-NEXT: Local Stack Slot Allocation
diff --git a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
index a4a6d831d64fc..38b1074e55d22 100644
--- a/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
+++ b/llvm/test/CodeGen/PowerPC/O0-pipeline.ll
@@ -33,13 +33,7 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
-; CHECK-NEXT: Dominator Tree Construction
-; CHECK-NEXT: Natural Loop Information
-; CHECK-NEXT: Post-Dominator Tree Construction
-; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
-; CHECK-NEXT: Lazy Branch Probability Analysis
-; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: PowerPC DAG->DAG Pattern Instruction Selection
; CHECK-NEXT: PowerPC VSX Copy Legalization
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
diff --git a/llvm/test/CodeGen/RISCV/O0-pipeline.ll b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
index 83379754a7507..8714b286374a5 100644
--- a/llvm/test/CodeGen/RISCV/O0-pipeline.ll
+++ b/llvm/test/CodeGen/RISCV/O0-pipeline.ll
@@ -35,13 +35,7 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
-; CHECK-NEXT: Dominator Tree Construction
-; CHECK-NEXT: Natural Loop Information
-; CHECK-NEXT: Post-Dominator Tree Construction
-; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
-; CHECK-NEXT: Lazy Branch Probability Analysis
-; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: RISC-V DAG->DAG Pattern Instruction Selection
; CHECK-NEXT: Finalize ISel and expand pseudo-instructions
; CHECK-NEXT: Local Stack Slot Allocation
diff --git a/llvm/test/CodeGen/X86/O0-pipeline.ll b/llvm/test/CodeGen/X86/O0-pipeline.ll
index 6aea51d8e87dc..0fbfb42d2a4dd 100644
--- a/llvm/test/CodeGen/X86/O0-pipeline.ll
+++ b/llvm/test/CodeGen/X86/O0-pipeline.ll
@@ -35,13 +35,7 @@
; CHECK-NEXT: Safe Stack instrumentation pass
; CHECK-NEXT: Insert stack protectors
; CHECK-NEXT: Module Verifier
-; CHECK-NEXT: Dominator Tree Construction
-; CHECK-NEXT: Natural Loop Information
-; CHECK-NEXT: Post-Dominator Tree Construction
-; CHECK-NEXT: Branch Probability Analysis
; CHECK-NEXT: Assignment Tracking Analysis
-; CHECK-NEXT: Lazy Branch Probability Analysis
-; CHECK-NEXT: Lazy Block Frequency Analysis
; CHECK-NEXT: X86 DAG->DAG Instruction Selection
; CHECK-NEXT: X86 PIC Global Base Reg Initialization
; CHECK-NEXT: Argument Stack Rebase
diff --git a/llvm/test/CodeGen/X86/pgo-profile-o0.ll b/llvm/test/CodeGen/X86/pgo-profile-o0.ll
index 009721fcbba78..f9704fcf0ec3a 100644
--- a/llvm/test/CodeGen/X86/pgo-profile-o0.ll
+++ b/llvm/test/CodeGen/X86/pgo-profile-o0.ll
@@ -1,6 +1,6 @@
-; RUN: llc -mtriple=x86_64-- -O0 -debug-pass=Structure %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=PASSES
-; RUN: llc -mtriple=x86_64-- -O0 -debug-only=branch-prob %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=BRANCH_PROB
-; RUN: llc -mtriple=x86_64-- -O0 -stop-after=finalize-isel %s -o - | FileCheck %s --check-prefix=MIR
+; RUN: llc -mtriple=x86_64-- -O0 -pgo-kind=pgo-sample-use-pipeline -debug-pass=Structure %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=PASSES
+; RUN: llc -mtriple=x86_64-- -O0 -pgo-kind=pgo-sample-use-pipeline -debug-only=branch-prob %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=BRANCH_PROB
+; RUN: llc -mtriple=x86_64-- -O0 -pgo-kind=pgo-sample-use-pipeline -stop-after=finalize-isel %s -o - | FileCheck %s --check-prefix=MIR
; REQUIRES: asserts
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index a2327fbc3b66a..c117b71ba0a47 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -44,6 +44,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/PGOOptions.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
@@ -239,6 +240,145 @@ static cl::opt<RunPassOption, true, cl::parser<std::string>> RunPass(
cl::desc("Run compiler only for specified passes (comma separated list)"),
cl::value_desc("pass-name"), cl::location(RunPassOpt));
+// PGO command line options
+enum PGOKind {
+ NoPGO,
+ InstrGen,
+ InstrUse,
+ SampleUse,
+};
+
+enum CSPGOKind {
+ NoCSPGO,
+ CSInstrGen,
+ CSInstrUse,
+};
+
+static cl::opt<PGOKind>
+ PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
+ cl::desc("The kind of profile guided optimization"),
+ cl::values(clEnumValN(NoPGO, "nopgo", "Do not use PGO."),
+ clEnumValN(InstrGen, "pgo-instr-gen-pipeline",
+ "Instrument the IR to generate profile."),
+ clEnumValN(InstrUse, "pgo-instr-use-pipeline",
+ "Use instrumented profile to guide PGO."),
+ clEnumValN(SampleUse, "pgo-sample-use-pipeline",
+ "Use sampled profile to guide PGO.")));
+
+static cl::opt<std::string>
+ ProfileFile("profile-file", cl::desc("Path to the profile."), cl::Hidden);
+
+static cl::opt<std::string>
+ MemoryProfileFile("memory-profile-file",
+ cl::desc("Path to the memory profile."), cl::Hidden);
+
+static cl::opt<CSPGOKind> CSPGOKindFlag(
+ "cspgo-kind", cl::init(NoCSPGO), cl::Hidden,
+ cl::desc("The kind of context sensitive profile guided optimization"),
+ cl::values(
+ clEnumValN(NoCSPGO, "nocspgo", "Do not use CSPGO."),
+ clEnumValN(
+ CSInstrGen, "cspgo-instr-gen-pipeline",
+ "Instrument (context sensitive) the IR to generate profile."),
+ clEnumValN(
+ CSInstrUse, "cspgo-instr-use-pipeline",
+ "Use instrumented (context sensitive) profile to guide PGO.")));
+
+static cl::opt<std::string> CSProfileGenFile(
+ "cs-profilegen-file",
+ cl::desc("Path to the instrumented context sensitive profile."),
+ cl::Hidden);
+
+static cl::opt<std::string>
+ ProfileRemappingFile("profile-remapping-file",
+ cl::desc("Path to the profile remapping file."),
+ cl::Hidden);
+
+static cl::opt<PGOOptions::ColdFuncOpt> PGOColdFuncAttr(
+ "pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden,
+ cl::desc(
+ "Function attribute to apply to cold functions as determined by PGO"),
+ cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default",
+ "Default (no attribute)"),
+ clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize",
+ "Mark cold functions with optsize."),
+ clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize",
+ "Mark cold functions with minsize."),
+ clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone",
+ "Mark cold functions with optnone.")));
+
+static cl::opt<bool> DebugInfoForProfiling(
+ "debug-info-for-profiling", cl::init(false), cl::Hidden,
+ cl::desc("Emit special debug info to enable PGO profile generation."));
+
+static cl::opt<bool> PseudoProbeForProfiling(
+ "pseudo-probe-for-profiling", cl::init(false), cl::Hidden,
+ cl::desc("Emit pseudo probes to enable PGO profile generation."));
+
+// Function to set PGO options on TargetMachine based on command line flags
+static void setPGOOptions(TargetMachine &TM) {
+ std::optional<PGOOptions> PGOOpt;
+
+ switch (PGOKindFlag) {
+ case InstrGen:
+ PGOOpt =
+ PGOOptions(ProfileFile, "", "", MemoryProfileFile, PGOOptions::IRInstr,
+ PGOOptions::NoCSAction, PGOColdFuncAttr);
+ break;
+ case InstrUse:
+ PGOOpt =
+ PGOOptions(ProfileFile, "", ProfileRemappingFile, MemoryProfileFile,
+ PGOOptions::IRUse, PGOOptions::NoCSAction, PGOColdFuncAttr);
+ break;
+ case SampleUse:
+ PGOOpt = PGOOptions(ProfileFile, "", ProfileRemappingFile,
+ MemoryProfileFile, PGOOptions::SampleUse,
+ PGOOptions::NoCSAction, PGOColdFuncAttr);
+ break;
+ case NoPGO:
+ if (DebugInfoForProfiling || PseudoProbeForProfiling ||
+ !MemoryProfileFile.empty())
+ PGOOpt = PGOOptions("", "", "", MemoryProfileFile, PGOOptions::NoAction,
+ PGOOptions::NoCSAction, PGOColdFuncAttr,
+ DebugInfoForProfiling, PseudoProbeForProfiling);
+ else
+ PGOOpt = std::nullopt;
+ break;
+ }
+
+ // Handle context-sensitive PGO options
+ if (CSPGOKindFlag != NoCSPGO) {
+ if (PGOOpt && (PGOOpt->Action == PGOOptions::IRInstr ||
+ PGOOpt->Action == PGOOptions::SampleUse)) {
+ errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
+ exit(1);
+ }
+ if (CSPGOKindFlag == CSInstrGen) {
+ if (CSProfileGenFile.empty()) {
+ errs() << "CSInstrGen needs to specify CSProfileGenFile";
+ exit(1);
+ }
+ if (PGOOpt) {
+ PGOOpt->CSAction = PGOOptions::CSIRInstr;
+ PGOOpt->CSProfileGenFile = CSProfileGenFile;
+ } else {
+ PGOOpt = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
+ /*MemoryProfile=*/"", PGOOptions::NoAction,
+ PGOOptions::CSIRInstr);
+ }
+ } else /* CSPGOKindFlag == CSInstrUse */ {
+ if (!PGOOpt) {
+ errs() << "CSInstrUse needs to be together with InstrUse";
+ exit(1);
+ }
+ PGOOpt->CSAction = PGOOptions::CSIRUse;
+ }
+ }
+
+ if (PGOOpt)
+ TM.setPGOOption(PGOOpt);
+}
+
static int compileModule(char **, LLVMContext &);
[[noreturn]] static void reportError(Twine Msg, StringRef Filename = "") {
@@ -554,6 +694,9 @@ static int compileModule(char **argv, LLVMContext &Context) {
TheTriple, CPUStr, FeaturesStr, Options, RM, CM, OLvl));
assert(Target && "Could not allocate target machine!");
+ // Set PGO options based on command line flags
+ setPGOOptions(*Target);
+
return Target->createDataLayout().getStringRepresentation();
};
if (InputLanguage == "mir" ||
@@ -597,6 +740,9 @@ static int compileModule(char **argv, LLVMContext &Context) {
TheTriple, CPUStr, FeaturesStr, Options, RM, CM, OLvl));
assert(Target && "Could not allocate target machine!");
+ // Set PGO options based on command line flags
+ setPGOOptions(*Target);
+
// If we don't have a module then just exit now. We do this down
// here since the CPU/Feature help is underneath the target machine
// creation.
>From 0af0751d2293f9247fd1e240e4a0fd402c231460 Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <gpastukhov at meta.com>
Date: Mon, 6 Oct 2025 10:26:16 -0700
Subject: [PATCH 3/7] Keep only pgo-kind option
---
llvm/tools/llc/llc.cpp | 115 ++---------------------------------------
1 file changed, 4 insertions(+), 111 deletions(-)
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index c117b71ba0a47..2a89933c1dfe3 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -243,138 +243,31 @@ static cl::opt<RunPassOption, true, cl::parser<std::string>> RunPass(
// PGO command line options
enum PGOKind {
NoPGO,
- InstrGen,
- InstrUse,
SampleUse,
};
-enum CSPGOKind {
- NoCSPGO,
- CSInstrGen,
- CSInstrUse,
-};
-
static cl::opt<PGOKind>
PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden,
cl::desc("The kind of profile guided optimization"),
cl::values(clEnumValN(NoPGO, "nopgo", "Do not use PGO."),
- clEnumValN(InstrGen, "pgo-instr-gen-pipeline",
- "Instrument the IR to generate profile."),
- clEnumValN(InstrUse, "pgo-instr-use-pipeline",
- "Use instrumented profile to guide PGO."),
clEnumValN(SampleUse, "pgo-sample-use-pipeline",
"Use sampled profile to guide PGO.")));
-static cl::opt<std::string>
- ProfileFile("profile-file", cl::desc("Path to the profile."), cl::Hidden);
-
-static cl::opt<std::string>
- MemoryProfileFile("memory-profile-file",
- cl::desc("Path to the memory profile."), cl::Hidden);
-
-static cl::opt<CSPGOKind> CSPGOKindFlag(
- "cspgo-kind", cl::init(NoCSPGO), cl::Hidden,
- cl::desc("The kind of context sensitive profile guided optimization"),
- cl::values(
- clEnumValN(NoCSPGO, "nocspgo", "Do not use CSPGO."),
- clEnumValN(
- CSInstrGen, "cspgo-instr-gen-pipeline",
- "Instrument (context sensitive) the IR to generate profile."),
- clEnumValN(
- CSInstrUse, "cspgo-instr-use-pipeline",
- "Use instrumented (context sensitive) profile to guide PGO.")));
-
-static cl::opt<std::string> CSProfileGenFile(
- "cs-profilegen-file",
- cl::desc("Path to the instrumented context sensitive profile."),
- cl::Hidden);
-
-static cl::opt<std::string>
- ProfileRemappingFile("profile-remapping-file",
- cl::desc("Path to the profile remapping file."),
- cl::Hidden);
-
-static cl::opt<PGOOptions::ColdFuncOpt> PGOColdFuncAttr(
- "pgo-cold-func-opt", cl::init(PGOOptions::ColdFuncOpt::Default), cl::Hidden,
- cl::desc(
- "Function attribute to apply to cold functions as determined by PGO"),
- cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default",
- "Default (no attribute)"),
- clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize",
- "Mark cold functions with optsize."),
- clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize",
- "Mark cold functions with minsize."),
- clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone",
- "Mark cold functions with optnone.")));
-
-static cl::opt<bool> DebugInfoForProfiling(
- "debug-info-for-profiling", cl::init(false), cl::Hidden,
- cl::desc("Emit special debug info to enable PGO profile generation."));
-
-static cl::opt<bool> PseudoProbeForProfiling(
- "pseudo-probe-for-profiling", cl::init(false), cl::Hidden,
- cl::desc("Emit pseudo probes to enable PGO profile generation."));
-
// Function to set PGO options on TargetMachine based on command line flags
static void setPGOOptions(TargetMachine &TM) {
std::optional<PGOOptions> PGOOpt;
switch (PGOKindFlag) {
- case InstrGen:
- PGOOpt =
- PGOOptions(ProfileFile, "", "", MemoryProfileFile, PGOOptions::IRInstr,
- PGOOptions::NoCSAction, PGOColdFuncAttr);
- break;
- case InstrUse:
- PGOOpt =
- PGOOptions(ProfileFile, "", ProfileRemappingFile, MemoryProfileFile,
- PGOOptions::IRUse, PGOOptions::NoCSAction, PGOColdFuncAttr);
- break;
case SampleUse:
- PGOOpt = PGOOptions(ProfileFile, "", ProfileRemappingFile,
- MemoryProfileFile, PGOOptions::SampleUse,
- PGOOptions::NoCSAction, PGOColdFuncAttr);
+ // Use default values for other PGOOptions parameters
+ PGOOpt = PGOOptions("", "", "", "", PGOOptions::SampleUse,
+ PGOOptions::NoCSAction);
break;
case NoPGO:
- if (DebugInfoForProfiling || PseudoProbeForProfiling ||
- !MemoryProfileFile.empty())
- PGOOpt = PGOOptions("", "", "", MemoryProfileFile, PGOOptions::NoAction,
- PGOOptions::NoCSAction, PGOColdFuncAttr,
- DebugInfoForProfiling, PseudoProbeForProfiling);
- else
- PGOOpt = std::nullopt;
+ PGOOpt = std::nullopt;
break;
}
- // Handle context-sensitive PGO options
- if (CSPGOKindFlag != NoCSPGO) {
- if (PGOOpt && (PGOOpt->Action == PGOOptions::IRInstr ||
- PGOOpt->Action == PGOOptions::SampleUse)) {
- errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
- exit(1);
- }
- if (CSPGOKindFlag == CSInstrGen) {
- if (CSProfileGenFile.empty()) {
- errs() << "CSInstrGen needs to specify CSProfileGenFile";
- exit(1);
- }
- if (PGOOpt) {
- PGOOpt->CSAction = PGOOptions::CSIRInstr;
- PGOOpt->CSProfileGenFile = CSProfileGenFile;
- } else {
- PGOOpt = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
- /*MemoryProfile=*/"", PGOOptions::NoAction,
- PGOOptions::CSIRInstr);
- }
- } else /* CSPGOKindFlag == CSInstrUse */ {
- if (!PGOOpt) {
- errs() << "CSInstrUse needs to be together with InstrUse";
- exit(1);
- }
- PGOOpt->CSAction = PGOOptions::CSIRUse;
- }
- }
-
if (PGOOpt)
TM.setPGOOption(PGOOpt);
}
>From 67050dd124f5d89ee41b4d3e09053064a9f68238 Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <gpastukhov at meta.com>
Date: Mon, 6 Oct 2025 10:58:55 -0700
Subject: [PATCH 4/7] Turn on PGO passes only if PGO enums are set to use
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1b5e2d987dcb5..931c57e84d176 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -231,13 +231,15 @@ static bool dontUseFastISelFor(const Function &Fn) {
static bool shouldRegisterPGOPasses(const TargetMachine &TM,
CodeGenOptLevel OptLevel) {
- bool RegisterPGOPasses = OptLevel != CodeGenOptLevel::None;
- if (!RegisterPGOPasses && TM.getPGOOption()) {
+ if (OptLevel != CodeGenOptLevel::None)
+ return true;
+ if (TM.getPGOOption()) {
const PGOOptions &Options = *TM.getPGOOption();
- RegisterPGOPasses = Options.Action != PGOOptions::PGOAction::NoAction ||
- Options.CSAction != PGOOptions::CSPGOAction::NoCSAction;
+ return Options.Action == PGOOptions::PGOAction::IRUse ||
+ Options.Action == PGOOptions::PGOAction::SampleUse ||
+ Options.CSAction != PGOOptions::CSPGOAction::CSIRUse;
}
- return RegisterPGOPasses;
+ return false;
}
namespace llvm {
>From 293b0959aad36b967984c7810e75b598566e5895 Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <gpastukhov at meta.com>
Date: Mon, 6 Oct 2025 17:09:42 -0700
Subject: [PATCH 5/7] Addressed comments
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +-
llvm/tools/llc/llc.cpp | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 931c57e84d176..f28dbd784d86a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -237,7 +237,7 @@ static bool shouldRegisterPGOPasses(const TargetMachine &TM,
const PGOOptions &Options = *TM.getPGOOption();
return Options.Action == PGOOptions::PGOAction::IRUse ||
Options.Action == PGOOptions::PGOAction::SampleUse ||
- Options.CSAction != PGOOptions::CSPGOAction::CSIRUse;
+ Options.CSAction != PGOOptions::CSPGOAction::NoCSAction;
}
return false;
}
diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp
index 2a89933c1dfe3..9d51e952fa341 100644
--- a/llvm/tools/llc/llc.cpp
+++ b/llvm/tools/llc/llc.cpp
@@ -253,13 +253,14 @@ static cl::opt<PGOKind>
clEnumValN(SampleUse, "pgo-sample-use-pipeline",
"Use sampled profile to guide PGO.")));
-// Function to set PGO options on TargetMachine based on command line flags
+// Function to set PGO options on TargetMachine based on command line flags.
static void setPGOOptions(TargetMachine &TM) {
std::optional<PGOOptions> PGOOpt;
switch (PGOKindFlag) {
case SampleUse:
- // Use default values for other PGOOptions parameters
+ // Use default values for other PGOOptions parameters. This parameter
+ // is used to test that PGO data is preserved at -O0.
PGOOpt = PGOOptions("", "", "", "", PGOOptions::SampleUse,
PGOOptions::NoCSAction);
break;
>From a4773d92e41f59210031aec951aee52a19f4161e Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <gpastukhov at meta.com>
Date: Tue, 7 Oct 2025 12:58:20 -0700
Subject: [PATCH 6/7] Changed PGOOptions check for CSPGO
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index f28dbd784d86a..de01fdde27ae7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -237,7 +237,7 @@ static bool shouldRegisterPGOPasses(const TargetMachine &TM,
const PGOOptions &Options = *TM.getPGOOption();
return Options.Action == PGOOptions::PGOAction::IRUse ||
Options.Action == PGOOptions::PGOAction::SampleUse ||
- Options.CSAction != PGOOptions::CSPGOAction::NoCSAction;
+ Options.CSAction == PGOOptions::CSPGOAction::CSIRUse;
}
return false;
}
>From b870ddd907780708a9274849e69cde247d5b55c9 Mon Sep 17 00:00:00 2001
From: Grigory Pastukhov <gpastukhov at meta.com>
Date: Thu, 9 Oct 2025 10:33:53 -0700
Subject: [PATCH 7/7] Changed function name
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index de01fdde27ae7..c1f570d688793 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -229,8 +229,8 @@ static bool dontUseFastISelFor(const Function &Fn) {
});
}
-static bool shouldRegisterPGOPasses(const TargetMachine &TM,
- CodeGenOptLevel OptLevel) {
+static bool maintainPGOProfile(const TargetMachine &TM,
+ CodeGenOptLevel OptLevel) {
if (OptLevel != CodeGenOptLevel::None)
return true;
if (TM.getPGOOption()) {
@@ -403,8 +403,7 @@ SelectionDAGISel::~SelectionDAGISel() { delete CurDAG; }
void SelectionDAGISelLegacy::getAnalysisUsage(AnalysisUsage &AU) const {
CodeGenOptLevel OptLevel = Selector->OptLevel;
- bool RegisterPGOPasses =
- shouldRegisterPGOPasses(Selector->TM, Selector->OptLevel);
+ bool RegisterPGOPasses = maintainPGOProfile(Selector->TM, Selector->OptLevel);
if (OptLevel != CodeGenOptLevel::None)
AU.addRequired<AAResultsWrapperPass>();
AU.addRequired<GCModuleInfo>();
@@ -474,7 +473,7 @@ void SelectionDAGISel::initializeAnalysisResults(
(void)MatchFilterFuncName;
#endif
- bool RegisterPGOPasses = shouldRegisterPGOPasses(TM, OptLevel);
+ bool RegisterPGOPasses = maintainPGOProfile(TM, OptLevel);
TII = MF->getSubtarget().getInstrInfo();
TLI = MF->getSubtarget().getTargetLowering();
RegInfo = &MF->getRegInfo();
@@ -529,7 +528,7 @@ void SelectionDAGISel::initializeAnalysisResults(MachineFunctionPass &MFP) {
(void)MatchFilterFuncName;
#endif
- bool RegisterPGOPasses = shouldRegisterPGOPasses(TM, OptLevel);
+ bool RegisterPGOPasses = maintainPGOProfile(TM, OptLevel);
TII = MF->getSubtarget().getInstrInfo();
TLI = MF->getSubtarget().getTargetLowering();
RegInfo = &MF->getRegInfo();
More information about the llvm-commits
mailing list