diff options
| author | Vasileios Porpodas <vporpodas@google.com> | 2024-07-01 09:05:50 -0700 |
|---|---|---|
| committer | Vasileios Porpodas <vporpodas@google.com> | 2024-07-01 10:52:33 -0700 |
| commit | f9efc295089217425d8220af892dcc5ede9eb9f7 (patch) | |
| tree | 4be81f0837d0c4daf8b98c2a9a9e3417e3667e33 | |
| parent | 6b707a8cc143f094b02393f4faf89025c64520bb (diff) | |
Reapply "[SandboxIR] Boilerplate code (#95814)"
This reverts commit 2f4f43c06b8e6d8488f217a3364c36409c348b83.
| -rw-r--r-- | llvm/include/llvm/SandboxIR/SandboxIR.h | 158 | ||||
| -rw-r--r-- | llvm/include/llvm/SandboxIR/SandboxIRValues.def | 26 | ||||
| -rw-r--r-- | llvm/lib/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/SandboxIR/CMakeLists.txt | 11 | ||||
| -rw-r--r-- | llvm/lib/SandboxIR/SandboxIR.cpp | 66 | ||||
| -rw-r--r-- | llvm/unittests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/unittests/SandboxIR/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | llvm/unittests/SandboxIR/SandboxIRTest.cpp | 42 |
8 files changed, 314 insertions, 0 deletions
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h new file mode 100644 index 000000000000..ec7ec1a268fa --- /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 000000000000..d41d8dce56e6 --- /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 74e2d03c0795..08f198679551 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 000000000000..225eca0cadd1 --- /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 000000000000..70101ab10ff1 --- /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 b2f10b218588..696926110df7 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 000000000000..362653bfff96 --- /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 000000000000..14e6e745f757 --- /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); +} |
