|
13 | 13 | #include "llvm/SandboxIR/Context.h"
|
14 | 14 | #include "llvm/SandboxIR/Function.h"
|
15 | 15 | #include "llvm/SandboxIR/PassManager.h"
|
| 16 | +#include "llvm/SandboxIR/Region.h" |
16 | 17 | #include "llvm/Support/SourceMgr.h"
|
17 | 18 | #include "gtest/gtest.h"
|
18 | 19 |
|
@@ -86,6 +87,68 @@ define void @foo() {
|
86 | 87 | #endif
|
87 | 88 | }
|
88 | 89 |
|
| 90 | +TEST_F(PassTest, RegionPass) { |
| 91 | + auto *F = parseFunction(R"IR( |
| 92 | +define i8 @foo(i8 %v0, i8 %v1) { |
| 93 | + %t0 = add i8 %v0, 1 |
| 94 | + %t1 = add i8 %t0, %v1, !sandboxvec !0 |
| 95 | + %t2 = add i8 %t1, %v1, !sandboxvec !0 |
| 96 | + ret i8 %t1 |
| 97 | +} |
| 98 | +
|
| 99 | +!0 = distinct !{!"sandboxregion"} |
| 100 | +)IR", |
| 101 | + "foo"); |
| 102 | + |
| 103 | + class TestPass final : public RegionPass { |
| 104 | + unsigned &InstCount; |
| 105 | + |
| 106 | + public: |
| 107 | + TestPass(unsigned &InstCount) |
| 108 | + : RegionPass("test-pass"), InstCount(InstCount) {} |
| 109 | + bool runOnRegion(Region &R) final { |
| 110 | + for ([[maybe_unused]] auto &Inst : R) { |
| 111 | + ++InstCount; |
| 112 | + } |
| 113 | + return false; |
| 114 | + } |
| 115 | + }; |
| 116 | + unsigned InstCount = 0; |
| 117 | + TestPass TPass(InstCount); |
| 118 | + // Check getName(), |
| 119 | + EXPECT_EQ(TPass.getName(), "test-pass"); |
| 120 | + // Check runOnRegion(); |
| 121 | + llvm::SmallVector<std::unique_ptr<Region>> Regions = |
| 122 | + Region::createRegionsFromMD(*F); |
| 123 | + ASSERT_EQ(Regions.size(), 1u); |
| 124 | + TPass.runOnRegion(*Regions[0]); |
| 125 | + EXPECT_EQ(InstCount, 2u); |
| 126 | +#ifndef NDEBUG |
| 127 | + { |
| 128 | + // Check print(). |
| 129 | + std::string Buff; |
| 130 | + llvm::raw_string_ostream SS(Buff); |
| 131 | + TPass.print(SS); |
| 132 | + EXPECT_EQ(Buff, "test-pass"); |
| 133 | + } |
| 134 | + { |
| 135 | + // Check operator<<(). |
| 136 | + std::string Buff; |
| 137 | + llvm::raw_string_ostream SS(Buff); |
| 138 | + SS << TPass; |
| 139 | + EXPECT_EQ(Buff, "test-pass"); |
| 140 | + } |
| 141 | + // Check pass name assertions. |
| 142 | + class TestNamePass final : public RegionPass { |
| 143 | + public: |
| 144 | + TestNamePass(llvm::StringRef Name) : RegionPass(Name) {} |
| 145 | + bool runOnRegion(Region &F) { return false; } |
| 146 | + }; |
| 147 | + EXPECT_DEATH(TestNamePass("white space"), ".*whitespace.*"); |
| 148 | + EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*"); |
| 149 | +#endif |
| 150 | +} |
| 151 | + |
89 | 152 | TEST_F(PassTest, FunctionPassManager) {
|
90 | 153 | auto *F = parseFunction(R"IR(
|
91 | 154 | define void @foo() {
|
@@ -136,6 +199,67 @@ define void @foo() {
|
136 | 199 | #endif // NDEBUG
|
137 | 200 | }
|
138 | 201 |
|
| 202 | +TEST_F(PassTest, RegionPassManager) { |
| 203 | + auto *F = parseFunction(R"IR( |
| 204 | +define i8 @foo(i8 %v0, i8 %v1) { |
| 205 | + %t0 = add i8 %v0, 1 |
| 206 | + %t1 = add i8 %t0, %v1, !sandboxvec !0 |
| 207 | + %t2 = add i8 %t1, %v1, !sandboxvec !0 |
| 208 | + ret i8 %t1 |
| 209 | +} |
| 210 | +
|
| 211 | +!0 = distinct !{!"sandboxregion"} |
| 212 | +)IR", |
| 213 | + "foo"); |
| 214 | + |
| 215 | + class TestPass1 final : public RegionPass { |
| 216 | + unsigned &InstCount; |
| 217 | + |
| 218 | + public: |
| 219 | + TestPass1(unsigned &InstCount) |
| 220 | + : RegionPass("test-pass1"), InstCount(InstCount) {} |
| 221 | + bool runOnRegion(Region &R) final { |
| 222 | + for ([[maybe_unused]] auto &Inst : R) |
| 223 | + ++InstCount; |
| 224 | + return false; |
| 225 | + } |
| 226 | + }; |
| 227 | + class TestPass2 final : public RegionPass { |
| 228 | + unsigned &InstCount; |
| 229 | + |
| 230 | + public: |
| 231 | + TestPass2(unsigned &InstCount) |
| 232 | + : RegionPass("test-pass2"), InstCount(InstCount) {} |
| 233 | + bool runOnRegion(Region &R) final { |
| 234 | + for ([[maybe_unused]] auto &Inst : R) |
| 235 | + ++InstCount; |
| 236 | + return false; |
| 237 | + } |
| 238 | + }; |
| 239 | + unsigned InstCount1 = 0; |
| 240 | + unsigned InstCount2 = 0; |
| 241 | + TestPass1 TPass1(InstCount1); |
| 242 | + TestPass2 TPass2(InstCount2); |
| 243 | + |
| 244 | + RegionPassManager RPM("test-rpm"); |
| 245 | + RPM.addPass(&TPass1); |
| 246 | + RPM.addPass(&TPass2); |
| 247 | + // Check runOnRegion(). |
| 248 | + llvm::SmallVector<std::unique_ptr<Region>> Regions = |
| 249 | + Region::createRegionsFromMD(*F); |
| 250 | + ASSERT_EQ(Regions.size(), 1u); |
| 251 | + RPM.runOnRegion(*Regions[0]); |
| 252 | + EXPECT_EQ(InstCount1, 2u); |
| 253 | + EXPECT_EQ(InstCount2, 2u); |
| 254 | +#ifndef NDEBUG |
| 255 | + // Check dump(). |
| 256 | + std::string Buff; |
| 257 | + llvm::raw_string_ostream SS(Buff); |
| 258 | + RPM.print(SS); |
| 259 | + EXPECT_EQ(Buff, "test-rpm(test-pass1,test-pass2)"); |
| 260 | +#endif // NDEBUG |
| 261 | +} |
| 262 | + |
139 | 263 | TEST_F(PassTest, PassRegistry) {
|
140 | 264 | class TestPass1 final : public FunctionPass {
|
141 | 265 | public:
|
|
0 commit comments