Skip to content

Commit 361eec6

Browse files
committed
[NewPM][CodeGen] Refactoring CodeGenPassBuilder
- Remove redundant `std::move`. - Use a unified function to add passes. - Support pass substitution.
1 parent 882814e commit 361eec6

File tree

8 files changed

+590
-379
lines changed

8 files changed

+590
-379
lines changed

llvm/include/llvm/Passes/CodeGenPassBuilder.h

Lines changed: 447 additions & 363 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: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
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(PassBuilder &PB)
55+
: CodeGenPassBuilder(createTargetMachine(), CGPassBuilderOption(), PB) {
56+
// Declare disabled passes in constructor.
57+
disablePass<NoOpModulePass>(3); // Disable the third NoOpModulePass.
58+
disablePass<DisabledMachineFunctionPass>();
59+
}
60+
61+
// Override substitutePass is also OK.
62+
// template <typename PassT> auto substitutePass() {
63+
// if constexpr (std::is_same_v<PassT, ReplacedMachineFunctionPass>)
64+
// return NoOpMachineFunctionPass();
65+
// else
66+
// return;
67+
// }
68+
69+
void buildTestPipeline(ModulePassManager &MPM) {
70+
addModulePass<NoOpModulePass, NoOpModulePass>();
71+
addFunctionPass<NoOpFunctionPass>();
72+
addModulePass<NoOpModulePass>();
73+
addMachineFunctionPass<DisabledMachineFunctionPass>();
74+
addFunctionPass(NoOpFunctionPass());
75+
addMachineFunctionPass<NoOpMachineFunctionPass,
76+
ReplacedMachineFunctionPass>();
77+
mergePassManager();
78+
MPM.addPass(std::move(getMPM()));
79+
getMPM() = ModulePassManager();
80+
}
81+
};
82+
83+
class CodeGenPassBuilderTest : public testing::Test {
84+
public:
85+
CodeGenPassBuilderTest() : PB(&createTargetMachine()) {
86+
PIC.addClassToPassName(NoOpModulePass::name(), "no-op-module");
87+
PIC.addClassToPassName(NoOpFunctionPass::name(), "no-op-function");
88+
PIC.addClassToPassName(NoOpMachineFunctionPass::name(),
89+
"no-op-machine-function");
90+
PIC.addClassToPassName(DisabledMachineFunctionPass::name(), "disabled");
91+
PIC.addClassToPassName(ReplacedMachineFunctionPass::name(), "replaced");
92+
}
93+
94+
void buildPipeline(ModulePassManager &MPM) {
95+
TestCodeGenPassBuilder CGPB(PB);
96+
CGPB.buildTestPipeline(MPM);
97+
}
98+
99+
std::string getPipelineText(ModulePassManager &MPM) {
100+
std::string PipelineText;
101+
raw_string_ostream OS(PipelineText);
102+
MPM.printPipeline(
103+
OS, [&](StringRef S) { return PIC.getPassNameForClassName(S); });
104+
return PipelineText;
105+
}
106+
PassInstrumentationCallbacks PIC;
107+
PassBuilder PB;
108+
};
109+
110+
} // namespace
111+
112+
using PassBuilderBase =
113+
CodeGenPassBuilder<TestCodeGenPassBuilder, TestTargetMachine>;
114+
115+
// Add a specialization to substitute a pass.
116+
template <>
117+
template <>
118+
auto PassBuilderBase::substitutePass<ReplacedMachineFunctionPass>() {
119+
return NoOpMachineFunctionPass();
120+
}
121+
122+
TEST_F(CodeGenPassBuilderTest, Basic) {
123+
ModulePassManager MPM;
124+
buildPipeline(MPM);
125+
EXPECT_EQ(getPipelineText(MPM),
126+
"no-op-module,no-op-module,function(no-op-function,no-op-function,"
127+
"machine-function(no-op-machine-function,no-op-machine-function))");
128+
}

0 commit comments

Comments
 (0)