Skip to content

Commit 3d62f95

Browse files
committed
[NewPM][CodeGen] Refactoring CodeGenPassBuilder
- Remove redundant `std::move`. - Use a unified function to add passes. - Support pass substitution.
1 parent 38067c5 commit 3d62f95

File tree

8 files changed

+453
-291
lines changed

8 files changed

+453
-291
lines changed

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 312 additions & 275 deletions
Large diffs are not rendered by default.

llvm/include/llvm/Target/TargetMachine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ class LLVMTargetMachine : public TargetMachine {
468468
virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
469469
raw_pwrite_stream *, CodeGenFileType,
470470
const CGPassBuilderOption &,
471-
PassInstrumentationCallbacks *) {
471+
PassBuilder &) {
472472
return make_error<StringError>("buildCodeGenPipeline is not overridden",
473473
inconvertibleErrorCode());
474474
}

llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,22 @@ class X86CodeGenPassBuilder
2424
public:
2525
explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
2626
const CGPassBuilderOption &Opts,
27-
PassInstrumentationCallbacks *PIC)
28-
: CodeGenPassBuilder(TM, Opts, PIC) {}
29-
void addPreISel(AddIRPass &addPass) const;
30-
void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const;
31-
Error addInstSelector(AddMachinePass &) const;
27+
PassBuilder &PB)
28+
: CodeGenPassBuilder(TM, Opts, PB) {}
29+
void addPreISel();
30+
void addAsmPrinter(CreateMCStreamer);
31+
Error addInstSelector();
3232
};
3333

34-
void X86CodeGenPassBuilder::addPreISel(AddIRPass &addPass) const {
34+
void X86CodeGenPassBuilder::addPreISel() {
3535
// TODO: Add passes pre instruction selection.
3636
}
3737

38-
void X86CodeGenPassBuilder::addAsmPrinter(AddMachinePass &addPass,
39-
CreateMCStreamer) const {
38+
void X86CodeGenPassBuilder::addAsmPrinter(CreateMCStreamer) {
4039
// TODO: Add AsmPrinter.
4140
}
4241

43-
Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &) const {
42+
Error X86CodeGenPassBuilder::addInstSelector() {
4443
// TODO: Add instruction selector.
4544
return Error::success();
4645
}
@@ -49,8 +48,7 @@ Error X86CodeGenPassBuilder::addInstSelector(AddMachinePass &) const {
4948

5049
Error X86TargetMachine::buildCodeGenPipeline(
5150
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
52-
CodeGenFileType FileType, const CGPassBuilderOption &Opt,
53-
PassInstrumentationCallbacks *PIC) {
54-
auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
51+
CodeGenFileType FileType, const CGPassBuilderOption &Opt, PassBuilder &PB) {
52+
auto CGPB = X86CodeGenPassBuilder(*this, Opt, PB);
5553
return CGPB.buildPipeline(MPM, Out, DwoOut, FileType);
5654
}

llvm/lib/Target/X86/X86TargetMachine.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class X86TargetMachine final : public LLVMTargetMachine {
6161
Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
6262
raw_pwrite_stream *, CodeGenFileType,
6363
const CGPassBuilderOption &,
64-
PassInstrumentationCallbacks *) override;
64+
PassBuilder &) override;
6565

6666
bool isJIT() const { return IsJIT; }
6767

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=mergeicmps -stop-after=gc-lowering -filetype=null %s | FileCheck --match-full-lines %s --check-prefix=NULL
22
; RUN: llc -mtriple=x86_64-pc-linux-gnu -enable-new-pm -print-pipeline-passes -start-before=mergeicmps -stop-after=gc-lowering -o /dev/null %s | FileCheck --match-full-lines %s --check-prefix=OBJ
33

4-
; NULL: function(mergeicmps,expand-memcmp,gc-lowering)
4+
; NULL: function(mergeicmps,expand-memcmp,gc-lowering,invalidate<machine-function-info>)
55
; OBJ: function(mergeicmps,expand-memcmp,gc-lowering),PrintMIRPreparePass,function(machine-function(print),invalidate<machine-function-info>)

llvm/tools/llc/NewPMDriver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ int llvm::compileModuleWithNewPM(
159159
return 1;
160160
} else {
161161
ExitOnErr(LLVMTM.buildCodeGenPipeline(
162-
MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));
162+
MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, PB));
163163
}
164164

165165
if (PrintPipelinePasses) {

llvm/unittests/CodeGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ add_llvm_unittest(CodeGenTests
2525
AMDGPUMetadataTest.cpp
2626
AsmPrinterDwarfTest.cpp
2727
CCStateTest.cpp
28+
CodeGenPassBuilderTest.cpp
2829
DIEHashTest.cpp
2930
DIETest.cpp
3031
DwarfStringPoolEntryRefTest.cpp
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//===- llvm/unittest/CodeGen/CodeGenPassBuilderTest.cpp -------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/Passes/CodeGenPassBuilder.h"
10+
#include "llvm/CodeGen/MachinePassManager.h"
11+
#include "llvm/CodeGen/TargetInstrInfo.h"
12+
#include "llvm/CodeGen/TargetLowering.h"
13+
#include "llvm/MC/TargetRegistry.h"
14+
#include "llvm/Passes/PassBuilder.h"
15+
#include "llvm/Target/TargetMachine.h"
16+
17+
#include "gtest/gtest.h"
18+
19+
using namespace llvm;
20+
21+
namespace {
22+
23+
class TestTargetMachine : public LLVMTargetMachine {
24+
public:
25+
TestTargetMachine()
26+
: LLVMTargetMachine(Target(), "", Triple(""), "", "", TargetOptions(),
27+
Reloc::Static, CodeModel::Small,
28+
CodeGenOptLevel::Default) {}
29+
};
30+
31+
TestTargetMachine &createTargetMachine() {
32+
static TestTargetMachine TM;
33+
return TM;
34+
}
35+
36+
struct DisabledMachineFunctionPass
37+
: public PassInfoMixin<DisabledMachineFunctionPass> {
38+
PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
39+
return PreservedAnalyses::all();
40+
}
41+
};
42+
43+
struct ReplacedMachineFunctionPass
44+
: public PassInfoMixin<ReplacedMachineFunctionPass> {
45+
PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
46+
return PreservedAnalyses::all();
47+
}
48+
};
49+
50+
class TestCodeGenPassBuilder
51+
: public CodeGenPassBuilder<TestCodeGenPassBuilder, TestTargetMachine> {
52+
53+
public:
54+
explicit TestCodeGenPassBuilder()
55+
: CodeGenPassBuilder(createTargetMachine(), CGPassBuilderOption(),
56+
nullptr) {
57+
// Declare disabled passes in constructor.
58+
disablePass<NoOpModulePass>(3); // Disable the third NoOpModulePass.
59+
disablePass<DisabledMachineFunctionPass>();
60+
}
61+
62+
// Override substitutePass is also OK.
63+
// template <typename PassT> auto substitutePass() {
64+
// if constexpr (std::is_same_v<PassT, ReplacedMachineFunctionPass>)
65+
// return NoOpMachineFunctionPass();
66+
// else
67+
// return;
68+
// }
69+
70+
void buildTestPipeline(ModulePassManager &MPM) {
71+
addPass(NoOpModulePass());
72+
addPass<NoOpModulePass, NoOpFunctionPass, NoOpModulePass,
73+
DisabledMachineFunctionPass, NoOpFunctionPass,
74+
NoOpMachineFunctionPass, ReplacedMachineFunctionPass>();
75+
mergePassManager();
76+
MPM.addPass(std::move(getMPM()));
77+
getMPM() = ModulePassManager();
78+
}
79+
};
80+
81+
class CodeGenPassBuilderTest : public testing::Test {
82+
public:
83+
CodeGenPassBuilderTest() {
84+
PIC.addClassToPassName(NoOpModulePass::name(), "no-op-module");
85+
PIC.addClassToPassName(NoOpFunctionPass::name(), "no-op-function");
86+
PIC.addClassToPassName(NoOpMachineFunctionPass::name(),
87+
"no-op-machine-function");
88+
PIC.addClassToPassName(DisabledMachineFunctionPass::name(), "disabled");
89+
PIC.addClassToPassName(ReplacedMachineFunctionPass::name(), "replaced");
90+
}
91+
92+
void buildPipeline(ModulePassManager &MPM) {
93+
TestCodeGenPassBuilder PB;
94+
PB.buildTestPipeline(MPM);
95+
}
96+
97+
std::string getPipelineText(ModulePassManager &MPM) {
98+
std::string PipelineText;
99+
raw_string_ostream OS(PipelineText);
100+
MPM.printPipeline(
101+
OS, [&](StringRef S) { return PIC.getPassNameForClassName(S); });
102+
return PipelineText;
103+
}
104+
105+
PassInstrumentationCallbacks PIC;
106+
};
107+
108+
} // namespace
109+
110+
using PassBuilderBase =
111+
CodeGenPassBuilder<TestCodeGenPassBuilder, TestTargetMachine>;
112+
113+
// Add a specialization to substitute a pass.
114+
template <>
115+
template <>
116+
auto PassBuilderBase::substitutePass<ReplacedMachineFunctionPass>() {
117+
return NoOpMachineFunctionPass();
118+
}
119+
120+
TEST_F(CodeGenPassBuilderTest, Basic) {
121+
ModulePassManager MPM;
122+
buildPipeline(MPM);
123+
EXPECT_EQ(getPipelineText(MPM),
124+
"no-op-module,no-op-module,function(no-op-function,no-op-function,"
125+
"machine-function(no-op-machine-function,no-op-machine-function))");
126+
}

0 commit comments

Comments
 (0)