Skip to content

Commit 3363760

Browse files
authored
[SandboxIR] PassManager (#107932)
This patch implements a simple pass manager for Sandbox IR.
1 parent 27a01f6 commit 3363760

File tree

5 files changed

+146
-2
lines changed

5 files changed

+146
-2
lines changed

llvm/include/llvm/SandboxIR/Pass.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class Pass {
3737
Pass.print(OS);
3838
return OS;
3939
}
40-
void print(raw_ostream &OS) const { OS << Name; }
41-
LLVM_DUMP_METHOD void dump() const;
40+
virtual void print(raw_ostream &OS) const { OS << Name; }
41+
LLVM_DUMP_METHOD virtual void dump() const;
4242
#endif
4343
};
4444

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===- PassManager.h --------------------------------------------*- C++ -*-===//
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+
// Registers and executes the Sandbox IR passes.
10+
//
11+
// The pass manager contains an ordered sequence of passes that it runs in
12+
// order. The passes are owned by the PassRegistry, not by the PassManager.
13+
//
14+
// Note that in this design a pass manager is also a pass. So a pass manager
15+
// runs when it is it's turn to run in its parent pass-manager pass pipeline.
16+
//
17+
18+
#ifndef LLVM_SANDBOXIR_PASSMANAGER_H
19+
#define LLVM_SANDBOXIR_PASSMANAGER_H
20+
21+
#include "llvm/ADT/STLExtras.h"
22+
#include "llvm/SandboxIR/Pass.h"
23+
#include "llvm/Support/Debug.h"
24+
25+
namespace llvm::sandboxir {
26+
27+
class Value;
28+
29+
/// Base class.
30+
template <typename ParentPass, typename ContainedPass>
31+
class PassManager : public ParentPass {
32+
protected:
33+
/// The list of passes that this pass manager will run.
34+
SmallVector<ContainedPass *> Passes;
35+
36+
PassManager(StringRef Name) : ParentPass(Name) {}
37+
PassManager(const PassManager &) = delete;
38+
virtual ~PassManager() = default;
39+
PassManager &operator=(const PassManager &) = delete;
40+
41+
public:
42+
/// Adds \p Pass to the pass pipeline.
43+
void addPass(ContainedPass *Pass) {
44+
// TODO: Check that Pass's class type works with this PassManager type.
45+
Passes.push_back(Pass);
46+
}
47+
#ifndef NDEBUG
48+
void print(raw_ostream &OS) const override {
49+
OS << this->getName();
50+
OS << "(";
51+
interleave(Passes, OS, [&OS](auto *Pass) { OS << Pass->getName(); }, ",");
52+
OS << ")";
53+
}
54+
LLVM_DUMP_METHOD void dump() const override {
55+
print(dbgs());
56+
dbgs() << "\n";
57+
}
58+
#endif
59+
};
60+
61+
class FunctionPassManager final
62+
: public PassManager<FunctionPass, FunctionPass> {
63+
public:
64+
FunctionPassManager(StringRef Name) : PassManager(Name) {}
65+
bool runOnFunction(Function &F) final;
66+
};
67+
68+
} // namespace llvm::sandboxir
69+
70+
#endif // LLVM_SANDBOXIR_PASSMANAGER_H

llvm/lib/SandboxIR/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_llvm_component_library(LLVMSandboxIR
22
Pass.cpp
3+
PassManager.cpp
34
SandboxIR.cpp
45
Tracker.cpp
56
Type.cpp

llvm/lib/SandboxIR/PassManager.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//===- PassManager.cpp - Runs a pipeline of Sandbox IR passes -------------===//
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/SandboxIR/PassManager.h"
10+
#include "llvm/SandboxIR/SandboxIR.h"
11+
12+
using namespace llvm::sandboxir;
13+
14+
bool FunctionPassManager::runOnFunction(Function &F) {
15+
bool Change = false;
16+
for (FunctionPass *Pass : Passes) {
17+
Change |= Pass->runOnFunction(F);
18+
// TODO: run the verifier.
19+
}
20+
// TODO: Check ChangeAll against hashes before/after.
21+
return Change;
22+
}

llvm/unittests/SandboxIR/PassTest.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "llvm/SandboxIR/Pass.h"
1010
#include "llvm/AsmParser/Parser.h"
1111
#include "llvm/IR/Module.h"
12+
#include "llvm/SandboxIR/PassManager.h"
1213
#include "llvm/SandboxIR/SandboxIR.h"
1314
#include "llvm/Support/SourceMgr.h"
1415
#include "gtest/gtest.h"
@@ -82,3 +83,53 @@ define void @foo() {
8283
EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*");
8384
#endif
8485
}
86+
87+
TEST_F(PassTest, FunctionPassManager) {
88+
auto *F = parseFunction(R"IR(
89+
define void @foo() {
90+
ret void
91+
}
92+
)IR",
93+
"foo");
94+
class TestPass1 final : public FunctionPass {
95+
unsigned &BBCnt;
96+
97+
public:
98+
TestPass1(unsigned &BBCnt) : FunctionPass("test-pass1"), BBCnt(BBCnt) {}
99+
bool runOnFunction(Function &F) final {
100+
for ([[maybe_unused]] auto &BB : F)
101+
++BBCnt;
102+
return false;
103+
}
104+
};
105+
class TestPass2 final : public FunctionPass {
106+
unsigned &BBCnt;
107+
108+
public:
109+
TestPass2(unsigned &BBCnt) : FunctionPass("test-pass2"), BBCnt(BBCnt) {}
110+
bool runOnFunction(Function &F) final {
111+
for ([[maybe_unused]] auto &BB : F)
112+
++BBCnt;
113+
return false;
114+
}
115+
};
116+
unsigned BBCnt1 = 0;
117+
unsigned BBCnt2 = 0;
118+
TestPass1 TPass1(BBCnt1);
119+
TestPass2 TPass2(BBCnt2);
120+
121+
FunctionPassManager FPM("test-fpm");
122+
FPM.addPass(&TPass1);
123+
FPM.addPass(&TPass2);
124+
// Check runOnFunction().
125+
FPM.runOnFunction(*F);
126+
EXPECT_EQ(BBCnt1, 1u);
127+
EXPECT_EQ(BBCnt2, 1u);
128+
#ifndef NDEBUG
129+
// Check dump().
130+
std::string Buff;
131+
llvm::raw_string_ostream SS(Buff);
132+
FPM.print(SS);
133+
EXPECT_EQ(Buff, "test-fpm(test-pass1,test-pass2)");
134+
#endif // NDEBUG
135+
}

0 commit comments

Comments
 (0)