[llvm] [CodeGen] Port break-false-deps to new pass manager (PR #194262)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 27 00:34:29 PDT 2026
https://github.com/juanvazquez updated https://github.com/llvm/llvm-project/pull/194262
>From cfed85682ce59bea12067d70a13ce37be3dd3f6d Mon Sep 17 00:00:00 2001
From: Juan Vazquez <juvazq at google.com>
Date: Sun, 26 Apr 2026 17:18:03 +0200
Subject: [PATCH] [CodeGen] Port break-false-deps to new pass manager
---
llvm/include/llvm/CodeGen/BreakFalseDeps.h | 40 +++++++++
llvm/include/llvm/CodeGen/Passes.h | 2 +-
llvm/include/llvm/InitializePasses.h | 2 +-
.../llvm/Passes/MachinePassRegistry.def | 2 +-
llvm/lib/CodeGen/BreakFalseDeps.cpp | 81 ++++++++++++-------
llvm/lib/CodeGen/CodeGen.cpp | 2 +-
llvm/lib/Passes/PassBuilder.cpp | 1 +
llvm/lib/Target/ARM/ARMTargetMachine.cpp | 2 +-
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 1 +
llvm/lib/Target/X86/X86TargetMachine.cpp | 2 +-
llvm/test/CodeGen/X86/apx/ndd-false-deps.mir | 3 +
.../CodeGen/X86/break-false-dep-crash.mir | 2 +
llvm/test/CodeGen/X86/llc-pipeline-npm.ll | 4 +-
13 files changed, 109 insertions(+), 35 deletions(-)
create mode 100644 llvm/include/llvm/CodeGen/BreakFalseDeps.h
diff --git a/llvm/include/llvm/CodeGen/BreakFalseDeps.h b/llvm/include/llvm/CodeGen/BreakFalseDeps.h
new file mode 100644
index 0000000000000..378aeeefaed7b
--- /dev/null
+++ b/llvm/include/llvm/CodeGen/BreakFalseDeps.h
@@ -0,0 +1,40 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Some instructions have false dependencies which cause unnecessary stalls.
+// For example, instructions may write part of a register and implicitly
+// need to read the other parts of the register. This may cause unwanted
+// stalls preventing otherwise unrelated instructions from executing in
+// parallel in an out-of-order CPU.
+// This pass is aimed at identifying and avoiding these dependencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_BREAKFALSEDEPS_H
+#define LLVM_CODEGEN_BREAKFALSEDEPS_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFunctionAnalysisManager.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Compiler.h"
+
+namespace llvm {
+
+class BreakFalseDepsPass : public PassInfoMixin<BreakFalseDepsPass> {
+public:
+ LLVM_ABI PreservedAnalyses run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM);
+
+ MachineFunctionProperties getRequiredProperties() const {
+ return MachineFunctionProperties().setNoVRegs();
+ }
+};
+
+} // namespace llvm
+
+#endif // LLVM_CODEGEN_BREAKFALSEDEPS_H
diff --git a/llvm/include/llvm/CodeGen/Passes.h b/llvm/include/llvm/CodeGen/Passes.h
index be344c6aaf40e..2fdf792512ec9 100644
--- a/llvm/include/llvm/CodeGen/Passes.h
+++ b/llvm/include/llvm/CodeGen/Passes.h
@@ -556,7 +556,7 @@ LLVM_ABI FunctionPass *createReplaceWithVeclibLegacyPass();
LLVM_ABI FunctionPass *createExpandIRInstsPass(CodeGenOptLevel);
/// Creates Break False Dependencies pass. \see BreakFalseDeps.cpp
-LLVM_ABI FunctionPass *createBreakFalseDeps();
+LLVM_ABI FunctionPass *createBreakFalseDepsLegacyPass();
// This pass expands indirectbr instructions.
LLVM_ABI FunctionPass *createIndirectBrExpandPass();
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 012f1fb0ebd90..4e2324774b641 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -69,7 +69,7 @@ LLVM_ABI void initializeBranchFolderLegacyPass(PassRegistry &);
LLVM_ABI void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeBranchRelaxationLegacyPass(PassRegistry &);
LLVM_ABI void initializeBreakCriticalEdgesPass(PassRegistry &);
-LLVM_ABI void initializeBreakFalseDepsPass(PassRegistry &);
+LLVM_ABI void initializeBreakFalseDepsLegacyPass(PassRegistry &);
LLVM_ABI void initializeCanonicalizeFreezeInLoopsPass(PassRegistry &);
LLVM_ABI void initializeCFGSimplifyPassPass(PassRegistry &);
LLVM_ABI void initializeCFGuardPass(PassRegistry &);
diff --git a/llvm/include/llvm/Passes/MachinePassRegistry.def b/llvm/include/llvm/Passes/MachinePassRegistry.def
index fd5d4a39a5915..539f9c901de1c 100644
--- a/llvm/include/llvm/Passes/MachinePassRegistry.def
+++ b/llvm/include/llvm/Passes/MachinePassRegistry.def
@@ -108,6 +108,7 @@ MACHINE_FUNCTION_ANALYSIS("virtregmap", VirtRegMapAnalysis())
#endif
MACHINE_FUNCTION_PASS("block-placement-stats", MachineBlockPlacementStatsPass())
MACHINE_FUNCTION_PASS("branch-relaxation", BranchRelaxationPass())
+MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass())
MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass())
MACHINE_FUNCTION_PASS("detect-dead-lanes", DetectDeadLanesPass())
MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass())
@@ -272,7 +273,6 @@ DUMMY_MACHINE_MODULE_PASS("mir-check-debugify", CheckDebugMachineModulePass)
#endif
DUMMY_MACHINE_FUNCTION_PASS("bbsections-prepare", BasicBlockSectionsPass)
DUMMY_MACHINE_FUNCTION_PASS("bbsections-profile-reader", BasicBlockSectionsProfileReaderPass)
-DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass)
DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass)
DUMMY_MACHINE_FUNCTION_PASS("cfi-fixup", CFIFixupPass)
DUMMY_MACHINE_FUNCTION_PASS("cfi-instr-inserter", CFIInstrInserterPass)
diff --git a/llvm/lib/CodeGen/BreakFalseDeps.cpp b/llvm/lib/CodeGen/BreakFalseDeps.cpp
index 9e16897fe7768..be6166fd3c411 100644
--- a/llvm/lib/CodeGen/BreakFalseDeps.cpp
+++ b/llvm/lib/CodeGen/BreakFalseDeps.cpp
@@ -17,6 +17,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/CodeGen/BreakFalseDeps.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/CodeGen/LivePhysRegs.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -33,7 +34,7 @@ using namespace llvm;
namespace {
-class BreakFalseDeps : public MachineFunctionPass {
+class BreakFalseDeps {
private:
MachineFunction *MF = nullptr;
const TargetInstrInfo *TII = nullptr;
@@ -49,21 +50,9 @@ class BreakFalseDeps : public MachineFunctionPass {
ReachingDefInfo *RDI = nullptr;
public:
- static char ID; // Pass identification, replacement for typeid
-
- BreakFalseDeps() : MachineFunctionPass(ID) {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- AU.addRequired<ReachingDefInfoWrapperPass>();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
+ BreakFalseDeps(ReachingDefInfo *RDI) : RDI(RDI) {}
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- MachineFunctionProperties getRequiredProperties() const override {
- return MachineFunctionProperties().setNoVRegs();
- }
+ bool run(MachineFunction &MF);
private:
/// Process he given basic block.
@@ -93,16 +82,39 @@ class BreakFalseDeps : public MachineFunctionPass {
void processUndefReads(MachineBasicBlock *);
};
+class BreakFalseDepsLegacy : public MachineFunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ BreakFalseDepsLegacy() : MachineFunctionPass(ID) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ AU.addRequired<ReachingDefInfoWrapperPass>();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) override;
+
+ MachineFunctionProperties getRequiredProperties() const override {
+ return MachineFunctionProperties().setNoVRegs();
+ }
+};
+
} // namespace
#define DEBUG_TYPE "break-false-deps"
-char BreakFalseDeps::ID = 0;
-INITIALIZE_PASS_BEGIN(BreakFalseDeps, DEBUG_TYPE, "BreakFalseDeps", false, false)
+char BreakFalseDepsLegacy::ID = 0;
+INITIALIZE_PASS_BEGIN(BreakFalseDepsLegacy, DEBUG_TYPE, "BreakFalseDeps", false,
+ false)
INITIALIZE_PASS_DEPENDENCY(ReachingDefInfoWrapperPass)
-INITIALIZE_PASS_END(BreakFalseDeps, DEBUG_TYPE, "BreakFalseDeps", false, false)
+INITIALIZE_PASS_END(BreakFalseDepsLegacy, DEBUG_TYPE, "BreakFalseDeps", false,
+ false)
-FunctionPass *llvm::createBreakFalseDeps() { return new BreakFalseDeps(); }
+FunctionPass *llvm::createBreakFalseDepsLegacyPass() {
+ return new BreakFalseDepsLegacy();
+}
bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
unsigned Pref) {
@@ -274,28 +286,43 @@ void BreakFalseDeps::processBasicBlock(MachineBasicBlock *MBB) {
processUndefReads(MBB);
}
-bool BreakFalseDeps::runOnMachineFunction(MachineFunction &mf) {
- if (skipFunction(mf.getFunction()))
- return false;
- MF = &mf;
+bool BreakFalseDeps::run(MachineFunction &CurMF) {
+ MF = &CurMF;
TII = MF->getSubtarget().getInstrInfo();
TRI = MF->getSubtarget().getRegisterInfo();
- RDI = &getAnalysis<ReachingDefInfoWrapperPass>().getRDI();
- RegClassInfo.runOnMachineFunction(mf, /*Rev=*/true);
+ RegClassInfo.runOnMachineFunction(CurMF, /*Rev=*/true);
LLVM_DEBUG(dbgs() << "********** BREAK FALSE DEPENDENCIES **********\n");
// Skip Dead blocks due to ReachingDefAnalysis has no idea about instructions
// in them.
df_iterator_default_set<MachineBasicBlock *> Reachable;
- for (MachineBasicBlock *MBB : depth_first_ext(&mf, Reachable))
+ for (MachineBasicBlock *MBB : depth_first_ext(&CurMF, Reachable))
(void)MBB /* Mark all reachable blocks */;
// Traverse the basic blocks.
- for (MachineBasicBlock &MBB : mf)
+ for (MachineBasicBlock &MBB : CurMF)
if (Reachable.count(&MBB))
processBasicBlock(&MBB);
return false;
}
+
+bool BreakFalseDepsLegacy::runOnMachineFunction(MachineFunction &MF) {
+ if (skipFunction(MF.getFunction()))
+ return false;
+
+ ReachingDefInfo *RDI = &getAnalysis<ReachingDefInfoWrapperPass>().getRDI();
+ BreakFalseDeps Impl(RDI);
+ return Impl.run(MF);
+}
+
+PreservedAnalyses
+BreakFalseDepsPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ MFPropsModifier _(*this, MF);
+ ReachingDefInfo *RDI = &MFAM.getResult<ReachingDefAnalysis>(MF);
+ BreakFalseDeps(RDI).run(MF);
+ return PreservedAnalyses::all();
+}
diff --git a/llvm/lib/CodeGen/CodeGen.cpp b/llvm/lib/CodeGen/CodeGen.cpp
index bb8bbc4f44eed..00e0bec380402 100644
--- a/llvm/lib/CodeGen/CodeGen.cpp
+++ b/llvm/lib/CodeGen/CodeGen.cpp
@@ -26,7 +26,7 @@ void llvm::initializeCodeGen(PassRegistry &Registry) {
initializeBasicBlockSectionsProfileReaderWrapperPassPass(Registry);
initializeBranchFolderLegacyPass(Registry);
initializeBranchRelaxationLegacyPass(Registry);
- initializeBreakFalseDepsPass(Registry);
+ initializeBreakFalseDepsLegacyPass(Registry);
initializeCFGuardLongjmpPass(Registry);
initializeCFIFixupPass(Registry);
initializeCFIInstrInserterPass(Registry);
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f412e9e68307f..4ce03c6bd264d 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -83,6 +83,7 @@
#include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
#include "llvm/CodeGen/BranchFoldingPass.h"
#include "llvm/CodeGen/BranchRelaxation.h"
+#include "llvm/CodeGen/BreakFalseDeps.h"
#include "llvm/CodeGen/CodeGenPrepare.h"
#include "llvm/CodeGen/ComplexDeinterleavingPass.h"
#include "llvm/CodeGen/DeadMachineInstructionElim.h"
diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
index 9e8c3cdd29fe8..efb87d1e750f2 100644
--- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp
@@ -487,7 +487,7 @@ void ARMPassConfig::addPreSched2() {
addPass(createARMLoadStoreOptLegacyPass());
addPass(new ARMExecutionDomainFix());
- addPass(createBreakFalseDeps());
+ addPass(createBreakFalseDepsLegacyPass());
}
// Expand some pseudo instructions into multiple instructions to allow
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 524cde4a8d4df..aadf423b98d88 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -16,6 +16,7 @@
#include "X86TargetMachine.h"
#include "llvm/CodeGen/AtomicExpand.h"
+#include "llvm/CodeGen/BreakFalseDeps.h"
#include "llvm/CodeGen/EarlyIfConversion.h"
#include "llvm/CodeGen/IndirectBrExpand.h"
#include "llvm/CodeGen/InterleavedAccess.h"
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 4ddadbec5a174..0c641d57a8f1e 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -560,7 +560,7 @@ void X86PassConfig::addPreSched2() {
void X86PassConfig::addPreEmitPass() {
if (getOptLevel() != CodeGenOptLevel::None) {
addPass(new X86ExecutionDomainFix());
- addPass(createBreakFalseDeps());
+ addPass(createBreakFalseDepsLegacyPass());
}
addPass(createX86IndirectBranchTrackingLegacyPass());
diff --git a/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir b/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir
index d1c2c40bed494..dad61b4f4b29a 100644
--- a/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir
+++ b/llvm/test/CodeGen/X86/apx/ndd-false-deps.mir
@@ -1,6 +1,9 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
# RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -run-pass=break-false-deps -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RCDEFAULT %s
# RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -run-pass=break-false-deps -partial-reg-update-clearance=1 -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RC1 %s
+
+# RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -passes=break-false-deps -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RCDEFAULT %s
+# RUN: llc %s -mtriple=x86_64-unknown -mattr=+ndd,+egpr -passes=break-false-deps -partial-reg-update-clearance=1 -verify-machineinstrs -o - | FileCheck --check-prefixes=CHECK,RC1 %s
#
# Check that BreakFalseDeps detects cases where an ND instruction would cause a partial register write
# if compressed to a legacy op. MIR has been modified to force different register assignments.
diff --git a/llvm/test/CodeGen/X86/break-false-dep-crash.mir b/llvm/test/CodeGen/X86/break-false-dep-crash.mir
index febc49da1f832..61e47add34165 100644
--- a/llvm/test/CodeGen/X86/break-false-dep-crash.mir
+++ b/llvm/test/CodeGen/X86/break-false-dep-crash.mir
@@ -1,5 +1,7 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 2
# RUN: llc -run-pass=break-false-deps -verify-machineinstrs %s -o - | FileCheck %s
+
+# RUN: llc -passes=break-false-deps -verify-machineinstrs %s -o - | FileCheck %s
#
# Check that BreakFalseDeps pass does not crash in presense of dead blocks.
--- |
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index 90b0978e3eb5c..b7728892b0b96 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -171,7 +171,7 @@
; O2-NEXT: fentry-insert
; O2-NEXT: xray-instrumentation
; O2-NEXT: patchable-function
-; O2-NEXT: BreakFalseDepsPass
+; O2-NEXT: break-false-deps
; O2-NEXT: x86-indirect-branch-tracking
; O2-NEXT: x86-insert-vzeroupper
; O2-NEXT: x86-fixup-bw-insts
@@ -360,7 +360,7 @@
; O3-WINDOWS-NEXT: fentry-insert
; O3-WINDOWS-NEXT: xray-instrumentation
; O3-WINDOWS-NEXT: patchable-function
-; O3-WINDOWS-NEXT: BreakFalseDepsPass
+; O3-WINDOWS-NEXT: break-false-deps
; O3-WINDOWS-NEXT: x86-indirect-branch-tracking
; O3-WINDOWS-NEXT: x86-insert-vzeroupper
; O3-WINDOWS-NEXT: x86-fixup-bw-insts
More information about the llvm-commits
mailing list