Skip to content

Commit

Permalink
[SandboxVec] Implement Pass class (llvm#107617)
Browse files Browse the repository at this point in the history
This patch implements the Pass base class and the FunctionPass sub-class
that operate on Sandbox IR.
  • Loading branch information
vporpo authored Sep 9, 2024
1 parent bdf0224 commit f12e10b
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 0 deletions.
55 changes: 55 additions & 0 deletions llvm/include/llvm/SandboxIR/Pass.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//===- Pass.h ---------------------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_SANDBOXIR_PASS_H
#define LLVM_SANDBOXIR_PASS_H

#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"

namespace llvm::sandboxir {

class Function;

/// The base class of a Sandbox IR Pass.
class Pass {
protected:
/// The pass name. This is also used as a command-line flag and should not
/// contain whitespaces.
const std::string Name;

public:
Pass(StringRef Name) : Name(Name) {
assert(!Name.contains(' ') &&
"A pass name should not contain whitespaces!");
assert(!Name.starts_with('-') && "A pass name should not start with '-'!");
}
virtual ~Pass() {}
/// \Returns the name of the pass.
StringRef getName() const { return Name; }
#ifndef NDEBUG
friend raw_ostream &operator<<(raw_ostream &OS, const Pass &Pass) {
Pass.print(OS);
return OS;
}
void print(raw_ostream &OS) const { OS << Name; }
LLVM_DUMP_METHOD void dump() const;
#endif
};

/// A pass that runs on a sandbox::Function.
class FunctionPass : public Pass {
public:
FunctionPass(StringRef Name) : Pass(Name) {}
/// \Returns true if it modifies \p F.
virtual bool runOnFunction(Function &F) = 0;
};

} // namespace llvm::sandboxir

#endif // LLVM_SANDBOXIR_PASS_H
1 change: 1 addition & 0 deletions llvm/lib/SandboxIR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_llvm_component_library(LLVMSandboxIR
Pass.cpp
SandboxIR.cpp
Tracker.cpp
Type.cpp
Expand Down
19 changes: 19 additions & 0 deletions llvm/lib/SandboxIR/Pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===- Pass.cpp - Passes that operate on Sandbox IR -----------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/SandboxIR/Pass.h"
#include "llvm/Support/Debug.h"

using namespace llvm::sandboxir;

#ifndef NDEBUG
void Pass::dump() const {
print(dbgs());
dbgs() << "\n";
}
#endif // NDEBUG
1 change: 1 addition & 0 deletions llvm/unittests/SandboxIR/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS
)

add_llvm_unittest(SandboxIRTests
PassTest.cpp
SandboxIRTest.cpp
TrackerTest.cpp
TypesTest.cpp
Expand Down
84 changes: 84 additions & 0 deletions llvm/unittests/SandboxIR/PassTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//===- PassTest.cpp -------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/SandboxIR/Pass.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Module.h"
#include "llvm/SandboxIR/SandboxIR.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"

using namespace llvm::sandboxir;

struct PassTest : public testing::Test {
llvm::LLVMContext LLVMCtx;
std::unique_ptr<llvm::Module> LLVMM;
std::unique_ptr<Context> Ctx;

Function *parseFunction(const char *IR, const char *FuncName) {
llvm::SMDiagnostic Err;
LLVMM = parseAssemblyString(IR, Err, LLVMCtx);
if (!LLVMM)
Err.print("PassTest", llvm::errs());
Ctx = std::make_unique<Context>(LLVMCtx);
return Ctx->createFunction(LLVMM->getFunction(FuncName));
}
};

TEST_F(PassTest, FunctionPass) {
auto *F = parseFunction(R"IR(
define void @foo() {
ret void
}
)IR",
"foo");
class TestPass final : public FunctionPass {
unsigned &BBCnt;

public:
TestPass(unsigned &BBCnt) : FunctionPass("test-pass"), BBCnt(BBCnt) {}
bool runOnFunction(Function &F) final {
for ([[maybe_unused]] auto &BB : F)
++BBCnt;
return false;
}
};
unsigned BBCnt = 0;
TestPass TPass(BBCnt);
// Check getName(),
EXPECT_EQ(TPass.getName(), "test-pass");
// Check classof().
EXPECT_TRUE(llvm::isa<FunctionPass>(TPass));
// Check runOnFunction();
TPass.runOnFunction(*F);
EXPECT_EQ(BBCnt, 1u);
#ifndef NDEBUG
{
// Check print().
std::string Buff;
llvm::raw_string_ostream SS(Buff);
TPass.print(SS);
EXPECT_EQ(Buff, "test-pass");
}
{
// Check operator<<().
std::string Buff;
llvm::raw_string_ostream SS(Buff);
SS << TPass;
EXPECT_EQ(Buff, "test-pass");
}
// Check pass name assertions.
class TestNamePass final : public FunctionPass {
public:
TestNamePass(llvm::StringRef Name) : FunctionPass(Name) {}
bool runOnFunction(Function &F) { return false; }
};
EXPECT_DEATH(TestNamePass("white space"), ".*whitespace.*");
EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*");
#endif
}

0 comments on commit f12e10b

Please sign in to comment.