[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