[llvm] 3363760 - [SandboxIR] PassManager (#107932)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 10 13:17:30 PDT 2024
Author: vporpo
Date: 2024-09-10T13:17:26-07:00
New Revision: 3363760f9a00c5d4dac1e08d44f9d79b8e322511
URL: https://github.com/llvm/llvm-project/commit/3363760f9a00c5d4dac1e08d44f9d79b8e322511
DIFF: https://github.com/llvm/llvm-project/commit/3363760f9a00c5d4dac1e08d44f9d79b8e322511.diff
LOG: [SandboxIR] PassManager (#107932)
This patch implements a simple pass manager for Sandbox IR.
Added:
llvm/include/llvm/SandboxIR/PassManager.h
llvm/lib/SandboxIR/PassManager.cpp
Modified:
llvm/include/llvm/SandboxIR/Pass.h
llvm/lib/SandboxIR/CMakeLists.txt
llvm/unittests/SandboxIR/PassTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/Pass.h b/llvm/include/llvm/SandboxIR/Pass.h
index d659e968392132..caf1c70a841477 100644
--- a/llvm/include/llvm/SandboxIR/Pass.h
+++ b/llvm/include/llvm/SandboxIR/Pass.h
@@ -37,8 +37,8 @@ class Pass {
Pass.print(OS);
return OS;
}
- void print(raw_ostream &OS) const { OS << Name; }
- LLVM_DUMP_METHOD void dump() const;
+ virtual void print(raw_ostream &OS) const { OS << Name; }
+ LLVM_DUMP_METHOD virtual void dump() const;
#endif
};
diff --git a/llvm/include/llvm/SandboxIR/PassManager.h b/llvm/include/llvm/SandboxIR/PassManager.h
new file mode 100644
index 00000000000000..cb321fe699a562
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/PassManager.h
@@ -0,0 +1,70 @@
+//===- PassManager.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Registers and executes the Sandbox IR passes.
+//
+// The pass manager contains an ordered sequence of passes that it runs in
+// order. The passes are owned by the PassRegistry, not by the PassManager.
+//
+// Note that in this design a pass manager is also a pass. So a pass manager
+// runs when it is it's turn to run in its parent pass-manager pass pipeline.
+//
+
+#ifndef LLVM_SANDBOXIR_PASSMANAGER_H
+#define LLVM_SANDBOXIR_PASSMANAGER_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/SandboxIR/Pass.h"
+#include "llvm/Support/Debug.h"
+
+namespace llvm::sandboxir {
+
+class Value;
+
+/// Base class.
+template <typename ParentPass, typename ContainedPass>
+class PassManager : public ParentPass {
+protected:
+ /// The list of passes that this pass manager will run.
+ SmallVector<ContainedPass *> Passes;
+
+ PassManager(StringRef Name) : ParentPass(Name) {}
+ PassManager(const PassManager &) = delete;
+ virtual ~PassManager() = default;
+ PassManager &operator=(const PassManager &) = delete;
+
+public:
+ /// Adds \p Pass to the pass pipeline.
+ void addPass(ContainedPass *Pass) {
+ // TODO: Check that Pass's class type works with this PassManager type.
+ Passes.push_back(Pass);
+ }
+#ifndef NDEBUG
+ void print(raw_ostream &OS) const override {
+ OS << this->getName();
+ OS << "(";
+ interleave(Passes, OS, [&OS](auto *Pass) { OS << Pass->getName(); }, ",");
+ OS << ")";
+ }
+ LLVM_DUMP_METHOD void dump() const override {
+ print(dbgs());
+ dbgs() << "\n";
+ }
+#endif
+};
+
+class FunctionPassManager final
+ : public PassManager<FunctionPass, FunctionPass> {
+public:
+ FunctionPassManager(StringRef Name) : PassManager(Name) {}
+ bool runOnFunction(Function &F) final;
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_SANDBOXIR_PASSMANAGER_H
diff --git a/llvm/lib/SandboxIR/CMakeLists.txt b/llvm/lib/SandboxIR/CMakeLists.txt
index 2f047944e0335e..03474be0c7b80a 100644
--- a/llvm/lib/SandboxIR/CMakeLists.txt
+++ b/llvm/lib/SandboxIR/CMakeLists.txt
@@ -1,5 +1,6 @@
add_llvm_component_library(LLVMSandboxIR
Pass.cpp
+ PassManager.cpp
SandboxIR.cpp
Tracker.cpp
Type.cpp
diff --git a/llvm/lib/SandboxIR/PassManager.cpp b/llvm/lib/SandboxIR/PassManager.cpp
new file mode 100644
index 00000000000000..d10f3926f7bcdb
--- /dev/null
+++ b/llvm/lib/SandboxIR/PassManager.cpp
@@ -0,0 +1,22 @@
+//===- PassManager.cpp - Runs a pipeline of Sandbox IR passes -------------===//
+//
+// 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/PassManager.h"
+#include "llvm/SandboxIR/SandboxIR.h"
+
+using namespace llvm::sandboxir;
+
+bool FunctionPassManager::runOnFunction(Function &F) {
+ bool Change = false;
+ for (FunctionPass *Pass : Passes) {
+ Change |= Pass->runOnFunction(F);
+ // TODO: run the verifier.
+ }
+ // TODO: Check ChangeAll against hashes before/after.
+ return Change;
+}
diff --git a/llvm/unittests/SandboxIR/PassTest.cpp b/llvm/unittests/SandboxIR/PassTest.cpp
index 65992d8cb95ee1..8e080128b15b34 100644
--- a/llvm/unittests/SandboxIR/PassTest.cpp
+++ b/llvm/unittests/SandboxIR/PassTest.cpp
@@ -9,6 +9,7 @@
#include "llvm/SandboxIR/Pass.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/IR/Module.h"
+#include "llvm/SandboxIR/PassManager.h"
#include "llvm/SandboxIR/SandboxIR.h"
#include "llvm/Support/SourceMgr.h"
#include "gtest/gtest.h"
@@ -82,3 +83,53 @@ define void @foo() {
EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*");
#endif
}
+
+TEST_F(PassTest, FunctionPassManager) {
+ auto *F = parseFunction(R"IR(
+define void @foo() {
+ ret void
+}
+)IR",
+ "foo");
+ class TestPass1 final : public FunctionPass {
+ unsigned &BBCnt;
+
+ public:
+ TestPass1(unsigned &BBCnt) : FunctionPass("test-pass1"), BBCnt(BBCnt) {}
+ bool runOnFunction(Function &F) final {
+ for ([[maybe_unused]] auto &BB : F)
+ ++BBCnt;
+ return false;
+ }
+ };
+ class TestPass2 final : public FunctionPass {
+ unsigned &BBCnt;
+
+ public:
+ TestPass2(unsigned &BBCnt) : FunctionPass("test-pass2"), BBCnt(BBCnt) {}
+ bool runOnFunction(Function &F) final {
+ for ([[maybe_unused]] auto &BB : F)
+ ++BBCnt;
+ return false;
+ }
+ };
+ unsigned BBCnt1 = 0;
+ unsigned BBCnt2 = 0;
+ TestPass1 TPass1(BBCnt1);
+ TestPass2 TPass2(BBCnt2);
+
+ FunctionPassManager FPM("test-fpm");
+ FPM.addPass(&TPass1);
+ FPM.addPass(&TPass2);
+ // Check runOnFunction().
+ FPM.runOnFunction(*F);
+ EXPECT_EQ(BBCnt1, 1u);
+ EXPECT_EQ(BBCnt2, 1u);
+#ifndef NDEBUG
+ // Check dump().
+ std::string Buff;
+ llvm::raw_string_ostream SS(Buff);
+ FPM.print(SS);
+ EXPECT_EQ(Buff, "test-fpm(test-pass1,test-pass2)");
+#endif // NDEBUG
+}
More information about the llvm-commits
mailing list