-
Notifications
You must be signed in to change notification settings - Fork 11.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reapply "[SandboxIR] Boilerplate code (#95814)"
This reverts commit 2f4f43c.
- Loading branch information
Showing
8 changed files
with
314 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
set(LLVM_LINK_COMPONENTS | ||
AsmParser | ||
SandboxIR | ||
Core | ||
) | ||
|
||
add_llvm_unittest(SandboxIRTests | ||
SandboxIRTest.cpp | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} |