[llvm] f9efc29 - Reapply "[SandboxIR] Boilerplate code (#95814)"
Vasileios Porpodas via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 1 10:53:31 PDT 2024
Author: Vasileios Porpodas
Date: 2024-07-01T10:52:33-07:00
New Revision: f9efc295089217425d8220af892dcc5ede9eb9f7
URL: https://github.com/llvm/llvm-project/commit/f9efc295089217425d8220af892dcc5ede9eb9f7
DIFF: https://github.com/llvm/llvm-project/commit/f9efc295089217425d8220af892dcc5ede9eb9f7.diff
LOG: Reapply "[SandboxIR] Boilerplate code (#95814)"
This reverts commit 2f4f43c06b8e6d8488f217a3364c36409c348b83.
Added:
llvm/include/llvm/SandboxIR/SandboxIR.h
llvm/include/llvm/SandboxIR/SandboxIRValues.def
llvm/lib/SandboxIR/CMakeLists.txt
llvm/lib/SandboxIR/SandboxIR.cpp
llvm/unittests/SandboxIR/CMakeLists.txt
llvm/unittests/SandboxIR/SandboxIRTest.cpp
Modified:
llvm/lib/CMakeLists.txt
llvm/unittests/CMakeLists.txt
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
new file mode 100644
index 0000000000000..ec7ec1a268fa7
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -0,0 +1,158 @@
+//===- 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 hierarchy 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/SandboxIR/SandboxIRValues.def"
+ };
+
+protected:
+ static const char *getSubclassIDStr(ClassID ID) {
+ switch (ID) {
+#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;
+#include "llvm/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 &Ctx;
+ // 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 &Ctx);
+ 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 &Ctx) : Value(ID, V, Ctx) {}
+ /// 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 &LLVMCtx;
+
+public:
+ Context(LLVMContext &LLVMCtx) : LLVMCtx(LLVMCtx) {}
+};
+} // namespace sandboxir
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SANDBOXIR_SANDBOXIR_H
diff --git a/llvm/include/llvm/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
new file mode 100644
index 0000000000000..d41d8dce56e68
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/SandboxIRValues.def
@@ -0,0 +1,26 @@
+//===- 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
+//
+//===----------------------------------------------------------------------===//
+
+// ClassID, Class
+DEF_USER(User, sandboxir::User)
+
+#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/CMakeLists.txt b/llvm/lib/CMakeLists.txt
index 74e2d03c07953..08f198679551d 100644
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -33,6 +33,7 @@ add_subdirectory(DebugInfo)
add_subdirectory(DWP)
add_subdirectory(ExecutionEngine)
add_subdirectory(Target)
+add_subdirectory(SandboxIR)
add_subdirectory(AsmParser)
add_subdirectory(LineEditor)
add_subdirectory(ProfileData)
diff --git a/llvm/lib/SandboxIR/CMakeLists.txt b/llvm/lib/SandboxIR/CMakeLists.txt
new file mode 100644
index 0000000000000..225eca0cadd1a
--- /dev/null
+++ b/llvm/lib/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/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
new file mode 100644
index 0000000000000..70101ab10ff12
--- /dev/null
+++ b/llvm/lib/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/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 &Ctx)
+ : SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
+#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/CMakeLists.txt b/llvm/unittests/CMakeLists.txt
index b2f10b2185880..696926110df7a 100644
--- a/llvm/unittests/CMakeLists.txt
+++ b/llvm/unittests/CMakeLists.txt
@@ -43,6 +43,7 @@ add_subdirectory(Option)
add_subdirectory(Remarks)
add_subdirectory(Passes)
add_subdirectory(ProfileData)
+add_subdirectory(SandboxIR)
add_subdirectory(Support)
add_subdirectory(TableGen)
add_subdirectory(Target)
diff --git a/llvm/unittests/SandboxIR/CMakeLists.txt b/llvm/unittests/SandboxIR/CMakeLists.txt
new file mode 100644
index 0000000000000..362653bfff965
--- /dev/null
+++ b/llvm/unittests/SandboxIR/CMakeLists.txt
@@ -0,0 +1,9 @@
+set(LLVM_LINK_COMPONENTS
+ AsmParser
+ SandboxIR
+ Core
+ )
+
+add_llvm_unittest(SandboxIRTests
+ SandboxIRTest.cpp
+ )
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
new file mode 100644
index 0000000000000..14e6e745f757a
--- /dev/null
+++ b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
@@ -0,0 +1,42 @@
+//===- 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/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 Ctx(C);
+ [[maybe_unused]] sandboxir::User U(sandboxir::Value::ClassID::User, Ret, Ctx);
+}
More information about the llvm-commits
mailing list