[llvm] [SandboxIR] Boilerplate code (PR #95814)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 27 15:12:33 PDT 2024
https://github.com/vporpo updated https://github.com/llvm/llvm-project/pull/95814
>From d255835315153b6718b30b4bbd0bbc7f9a688af5 Mon Sep 17 00:00:00 2001
From: Vasileios Porpodas <vporpodas at google.com>
Date: Mon, 17 Jun 2024 10:06:29 -0700
Subject: [PATCH] [SandboxIR] Boilerplate code
This is the first patch in a series of patches for the Sandbox Vectorizer
project.
SandboxIR is not tightly coupled to the Sandbox Vectorizer and could be used
independently as a transactional layer on top of LLVM IR.
For a more detailed description of the project please refer to the RFC:
https://discourse.llvm.org/t/rfc-sandbox-vectorizer-an-experimental-modular-vectorizer/79059
This patch adds some basic boilerplate code for the SandboxIR which includes
parts of the SandboxIR `Value` class.
---
.../llvm/Transforms/SandboxIR/SandboxIR.h | 154 ++++++++++++++++++
.../Transforms/SandboxIR/SandboxIRValues.def | 29 ++++
llvm/lib/Transforms/CMakeLists.txt | 1 +
llvm/lib/Transforms/SandboxIR/CMakeLists.txt | 11 ++
llvm/lib/Transforms/SandboxIR/SandboxIR.cpp | 66 ++++++++
llvm/unittests/Transforms/CMakeLists.txt | 1 +
.../Transforms/SandboxIR/CMakeLists.txt | 10 ++
.../Transforms/SandboxIR/SandboxIRTest.cpp | 43 +++++
8 files changed, 315 insertions(+)
create mode 100644 llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h
create mode 100644 llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def
create mode 100644 llvm/lib/Transforms/SandboxIR/CMakeLists.txt
create mode 100644 llvm/lib/Transforms/SandboxIR/SandboxIR.cpp
create mode 100644 llvm/unittests/Transforms/SandboxIR/CMakeLists.txt
create mode 100644 llvm/unittests/Transforms/SandboxIR/SandboxIRTest.cpp
diff --git a/llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h b/llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h
new file mode 100644
index 0000000000000..47cd46ac492f3
--- /dev/null
+++ b/llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h
@@ -0,0 +1,154 @@
+//===- SandboxIR.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Sandbox IR is a lightweight overlay transactional IR on top of LLVM IR.
+// Features:
+// - You can save/rollback the state of the IR at any time.
+// - Any changes made to Sandbox IR will automatically update the underlying
+// LLVM IR so both IRs are always in sync.
+// - Feels like LLVM IR, similar API.
+//
+// SandboxIR forms a class hierarcy that resembles that of LLVM IR
+// but is in the `sandboxir` namespace:
+//
+// namespace sandboxir {
+//
+// +- Argument +- BinaryOperator
+// | |
+// Value -+- BasicBlock +- BranchInst
+// | |
+// +- Function +- Constant +- CastInst
+// | | |
+// +- User ------+- Instruction -+- CallInst
+// |
+// +- CmpInst
+// |
+// +- ExtractElementInst
+// |
+// +- GetElementPtrInst
+// |
+// +- InsertElementInst
+// |
+// +- LoadInst
+// |
+// +- OpaqueInst
+// |
+// +- PHINode
+// |
+// +- RetInst
+// |
+// +- SelectInst
+// |
+// +- ShuffleVectorInst
+// |
+// +- StoreInst
+// |
+// +- UnaryOperator
+//
+// Use
+//
+// } // namespace sandboxir
+//
+
+#ifndef LLVM_TRANSFORMS_SANDBOXIR_SANDBOXIR_H
+#define LLVM_TRANSFORMS_SANDBOXIR_SANDBOXIR_H
+
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+namespace sandboxir {
+
+class Context;
+
+/// A SandboxIR Value has users. This is the base class.
+class Value {
+public:
+ enum class ClassID : unsigned {
+#define DEF_VALUE(ID, CLASS) ID,
+#define DEF_USER(ID, CLASS) ID,
+#define DEF_INSTR(ID, OPC, CLASS) ID,
+#include "llvm/Transforms/SandboxIR/SandboxIRValues.def"
+ };
+
+protected:
+ static const char *getSubclassIDStr(ClassID ID) {
+ switch (ID) {
+ // clang-format off
+#define DEF_VALUE(ID, CLASS) case ClassID::ID: return #ID;
+#define DEF_USER(ID, CLASS) case ClassID::ID: return #ID;
+#define DEF_INSTR(ID, OPC, CLASS) case ClassID::ID: return #ID;
+ // clang-format on
+#include "llvm/Transforms/SandboxIR/SandboxIRValues.def"
+ }
+ llvm_unreachable("Unimplemented ID");
+ }
+
+ /// For isa/dyn_cast.
+ ClassID SubclassID;
+#ifndef NDEBUG
+ /// A unique ID used for forming the name (used for debugging).
+ unsigned UID;
+#endif
+ /// The LLVM Value that corresponds to this SandboxIR Value.
+ /// NOTE: Some SBInstructions, like Packs, may include more than one value.
+ llvm::Value *Val = nullptr;
+
+ /// All values point to the context.
+ Context &Ctxt;
+ // This is used by eraseFromParent().
+ void clearValue() { Val = nullptr; }
+ template <typename ItTy, typename SBTy> friend class LLVMOpUserItToSBTy;
+
+public:
+ Value(ClassID SubclassID, llvm::Value *Val, Context &Ctxt);
+ virtual ~Value() = default;
+ ClassID getSubclassID() const { return SubclassID; }
+
+ Type *getType() const { return Val->getType(); }
+
+ Context &getContext() const;
+#ifndef NDEBUG
+ /// Should crash if there is something wrong with the instruction.
+ virtual void verify() const = 0;
+ /// Returns the name in the form 'SB<number>.' like 'SB1.'
+ std::string getName() const;
+ virtual void dumpCommonHeader(raw_ostream &OS) const;
+ void dumpCommonFooter(raw_ostream &OS) const;
+ void dumpCommonPrefix(raw_ostream &OS) const;
+ void dumpCommonSuffix(raw_ostream &OS) const;
+ void printAsOperandCommon(raw_ostream &OS) const;
+#endif
+};
+
+class User : public Value {
+public:
+ User(ClassID ID, llvm::Value *V, Context &Ctxt) : Value(ID, V, Ctxt) {}
+ /// For isa/dyn_cast.
+ static bool classof(const Value *From);
+#ifndef NDEBUG
+ void verify() const override {
+ assert(isa<llvm::User>(Val) && "Expected User!");
+ }
+ void dumpCommonHeader(raw_ostream &OS) const final;
+#endif
+};
+
+class Context {
+protected:
+ LLVMContext &LLVMCtxt;
+
+public:
+ Context(LLVMContext &LLVMCtxt) : LLVMCtxt(LLVMCtxt) {}
+};
+} // namespace sandboxir
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SANDBOXIR_SANDBOXIR_H
diff --git a/llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def
new file mode 100644
index 0000000000000..25ec5f1259194
--- /dev/null
+++ b/llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def
@@ -0,0 +1,29 @@
+//===- SandboxIRValues.def --------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+// clang-format off
+
+// ClassID, Class
+DEF_USER(User, sandboxir::User)
+
+// clang-format on
+#ifdef DEF_VALUE
+#undef DEF_VALUE
+#endif
+#ifdef DEF_USER
+#undef DEF_USER
+#endif
+#ifdef DEF_INSTR
+#undef DEF_INSTR
+#endif
+#ifdef OPCODES
+#undef OPCODES
+#endif
+#ifdef OP
+#undef OP
+#endif
diff --git a/llvm/lib/Transforms/CMakeLists.txt b/llvm/lib/Transforms/CMakeLists.txt
index 84a7e34147d08..d9857034ba1a9 100644
--- a/llvm/lib/Transforms/CMakeLists.txt
+++ b/llvm/lib/Transforms/CMakeLists.txt
@@ -10,3 +10,4 @@ add_subdirectory(ObjCARC)
add_subdirectory(Coroutines)
add_subdirectory(CFGuard)
add_subdirectory(HipStdPar)
+add_subdirectory(SandboxIR)
diff --git a/llvm/lib/Transforms/SandboxIR/CMakeLists.txt b/llvm/lib/Transforms/SandboxIR/CMakeLists.txt
new file mode 100644
index 0000000000000..225eca0cadd1a
--- /dev/null
+++ b/llvm/lib/Transforms/SandboxIR/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_llvm_component_library(LLVMSandboxIR
+ SandboxIR.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/SandboxIR
+
+ LINK_COMPONENTS
+ Core
+ Support
+ )
+
diff --git a/llvm/lib/Transforms/SandboxIR/SandboxIR.cpp b/llvm/lib/Transforms/SandboxIR/SandboxIR.cpp
new file mode 100644
index 0000000000000..bc33d131af1f1
--- /dev/null
+++ b/llvm/lib/Transforms/SandboxIR/SandboxIR.cpp
@@ -0,0 +1,66 @@
+//===- SandboxIR.cpp - A transactional overlay IR on top of LLVM 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/Transforms/SandboxIR/SandboxIR.h"
+#include "llvm/Support/Debug.h"
+#include <sstream>
+
+using namespace llvm;
+using namespace sandboxir;
+
+sandboxir::Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctxt)
+ : SubclassID(SubclassID), Val(Val), Ctxt(Ctxt) {
+#ifndef NDEBUG
+ UID = 0; // FIXME: Once SBContext is available.
+#endif
+}
+
+#ifndef NDEBUG
+std::string sandboxir::Value::getName() const {
+ std::stringstream SS;
+ SS << "SB" << UID << ".";
+ return SS.str();
+}
+
+void sandboxir::Value::dumpCommonHeader(raw_ostream &OS) const {
+ OS << getName() << " " << getSubclassIDStr(SubclassID) << " ";
+}
+
+void sandboxir::Value::dumpCommonFooter(raw_ostream &OS) const {
+ OS.indent(2) << "Val: ";
+ if (Val)
+ OS << *Val;
+ else
+ OS << "NULL";
+ OS << "\n";
+}
+
+void sandboxir::Value::dumpCommonPrefix(raw_ostream &OS) const {
+ if (Val)
+ OS << *Val;
+ else
+ OS << "NULL ";
+}
+
+void sandboxir::Value::dumpCommonSuffix(raw_ostream &OS) const {
+ OS << " ; " << getName() << " (" << getSubclassIDStr(SubclassID) << ") "
+ << this;
+}
+
+void sandboxir::Value::printAsOperandCommon(raw_ostream &OS) const {
+ if (Val)
+ Val->printAsOperand(OS);
+ else
+ OS << "NULL ";
+}
+
+void sandboxir::User::dumpCommonHeader(raw_ostream &OS) const {
+ Value::dumpCommonHeader(OS);
+ // TODO: This is incomplete
+}
+#endif // NDEBUG
diff --git a/llvm/unittests/Transforms/CMakeLists.txt b/llvm/unittests/Transforms/CMakeLists.txt
index 320cdf5674149..e136430c549be 100644
--- a/llvm/unittests/Transforms/CMakeLists.txt
+++ b/llvm/unittests/Transforms/CMakeLists.txt
@@ -4,3 +4,4 @@ add_subdirectory(IPO)
add_subdirectory(Scalar)
add_subdirectory(Utils)
add_subdirectory(Vectorize)
+add_subdirectory(SandboxIR)
diff --git a/llvm/unittests/Transforms/SandboxIR/CMakeLists.txt b/llvm/unittests/Transforms/SandboxIR/CMakeLists.txt
new file mode 100644
index 0000000000000..1cce736b2d8b7
--- /dev/null
+++ b/llvm/unittests/Transforms/SandboxIR/CMakeLists.txt
@@ -0,0 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+ AsmParser
+ SandboxIR
+ )
+
+add_llvm_unittest(SandboxIRTests
+ SandboxIRTest.cpp
+ )
+
+set_property(TARGET SandboxIRTests PROPERTY FOLDER "Tests/UnitTests/TransformsTests")
diff --git a/llvm/unittests/Transforms/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/Transforms/SandboxIR/SandboxIRTest.cpp
new file mode 100644
index 0000000000000..3a2968c577be2
--- /dev/null
+++ b/llvm/unittests/Transforms/SandboxIR/SandboxIRTest.cpp
@@ -0,0 +1,43 @@
+//===- SandboxIRTest.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/Transforms/SandboxIR/SandboxIR.h"
+#include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/SourceMgr.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+struct SandboxIRTest : public testing::Test {
+ LLVMContext C;
+ std::unique_ptr<Module> M;
+
+ void parseIR(LLVMContext &C, const char *IR) {
+ SMDiagnostic Err;
+ M = parseAssemblyString(IR, Err, C);
+ if (!M)
+ Err.print("SandboxIRTest", errs());
+ }
+};
+
+TEST_F(SandboxIRTest, UserInstantiation) {
+ parseIR(C, R"IR(
+define void @foo(i32 %v1) {
+ ret void
+}
+)IR");
+ Function &F = *M->getFunction("foo");
+ auto *Ret = F.begin()->getTerminator();
+ sandboxir::Context Ctxt(C);
+ sandboxir::User U(sandboxir::Value::ClassID::User, Ret, Ctxt);
+ (void)U;
+}
More information about the llvm-commits
mailing list