[llvm] 165a912 - [SandboxIR][NFC] Move Context class into a separate file (#110049)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 25 17:04:23 PDT 2024
Author: vporpo
Date: 2024-09-25T17:04:20-07:00
New Revision: 165a912807ee3acbd421d2c819c51872f700c9b0
URL: https://github.com/llvm/llvm-project/commit/165a912807ee3acbd421d2c819c51872f700c9b0
DIFF: https://github.com/llvm/llvm-project/commit/165a912807ee3acbd421d2c819c51872f700c9b0.diff
LOG: [SandboxIR][NFC] Move Context class into a separate file (#110049)
Added:
llvm/include/llvm/SandboxIR/Context.h
llvm/lib/SandboxIR/Context.cpp
Modified:
llvm/include/llvm/SandboxIR/SandboxIR.h
llvm/lib/SandboxIR/CMakeLists.txt
llvm/lib/SandboxIR/SandboxIR.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/SandboxIR/Context.h b/llvm/include/llvm/SandboxIR/Context.h
new file mode 100644
index 00000000000000..dfba3085c66ac1
--- /dev/null
+++ b/llvm/include/llvm/SandboxIR/Context.h
@@ -0,0 +1,208 @@
+//===- Context.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SANDBOXIR_CONTEXT_H
+#define LLVM_SANDBOXIR_CONTEXT_H
+
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/SandboxIR/Tracker.h"
+#include "llvm/SandboxIR/Type.h"
+
+namespace llvm::sandboxir {
+
+class Module;
+class Value;
+class Argument;
+
+class Context {
+protected:
+ LLVMContext &LLVMCtx;
+ friend class Type; // For LLVMCtx.
+ friend class PointerType; // For LLVMCtx.
+ friend class CmpInst; // For LLVMCtx. TODO: cleanup when sandboxir::VectorType
+ // is complete
+ friend class IntegerType; // For LLVMCtx.
+ friend class StructType; // For LLVMCtx.
+ friend class ::llvm::TargetExtType; // For LLVMCtx.
+ friend class Region; // For LLVMCtx.
+
+ Tracker IRTracker;
+
+ /// Maps LLVM Value to the corresponding sandboxir::Value. Owns all
+ /// SandboxIR objects.
+ DenseMap<llvm::Value *, std::unique_ptr<Value>> LLVMValueToValueMap;
+
+ /// Maps an LLVM Module to the corresponding sandboxir::Module.
+ DenseMap<llvm::Module *, std::unique_ptr<Module>> LLVMModuleToModuleMap;
+
+ /// Type has a protected destructor to prohibit the user from managing the
+ /// lifetime of the Type objects. Context is friend of Type, and this custom
+ /// deleter can destroy Type.
+ struct TypeDeleter {
+ void operator()(Type *Ty) { delete Ty; }
+ };
+ /// Maps LLVM Type to the corresonding sandboxir::Type. Owns all Sandbox IR
+ /// Type objects.
+ DenseMap<llvm::Type *, std::unique_ptr<Type, TypeDeleter>> LLVMTypeToTypeMap;
+
+ /// Remove \p V from the maps and returns the unique_ptr.
+ std::unique_ptr<Value> detachLLVMValue(llvm::Value *V);
+ /// Remove \p SBV from all SandboxIR maps and stop owning it. This effectively
+ /// detaches \p V from the underlying IR.
+ std::unique_ptr<Value> detach(Value *V);
+ friend class Instruction; // For detach().
+ /// Take ownership of VPtr and store it in `LLVMValueToValueMap`.
+ Value *registerValue(std::unique_ptr<Value> &&VPtr);
+ friend class EraseFromParent; // For registerValue().
+ /// This is the actual function that creates sandboxir values for \p V,
+ /// and among others handles all instruction types.
+ Value *getOrCreateValueInternal(llvm::Value *V, llvm::User *U = nullptr);
+ /// Get or create a sandboxir::Argument for an existing LLVM IR \p LLVMArg.
+ Argument *getOrCreateArgument(llvm::Argument *LLVMArg);
+ /// Get or create a sandboxir::Value for an existing LLVM IR \p LLVMV.
+ Value *getOrCreateValue(llvm::Value *LLVMV) {
+ return getOrCreateValueInternal(LLVMV, 0);
+ }
+ /// Get or create a sandboxir::Constant from an existing LLVM IR \p LLVMC.
+ Constant *getOrCreateConstant(llvm::Constant *LLVMC) {
+ return cast<Constant>(getOrCreateValueInternal(LLVMC, 0));
+ }
+ // Friends for getOrCreateConstant().
+#define DEF_CONST(ID, CLASS) friend class CLASS;
+#include "llvm/SandboxIR/SandboxIRValues.def"
+
+ /// Create a sandboxir::BasicBlock for an existing LLVM IR \p BB. This will
+ /// also create all contents of the block.
+ BasicBlock *createBasicBlock(llvm::BasicBlock *BB);
+ friend class BasicBlock; // For getOrCreateValue().
+
+ IRBuilder<ConstantFolder> LLVMIRBuilder;
+ auto &getLLVMIRBuilder() { return LLVMIRBuilder; }
+
+ VAArgInst *createVAArgInst(llvm::VAArgInst *SI);
+ friend VAArgInst; // For createVAArgInst()
+ FreezeInst *createFreezeInst(llvm::FreezeInst *SI);
+ friend FreezeInst; // For createFreezeInst()
+ FenceInst *createFenceInst(llvm::FenceInst *SI);
+ friend FenceInst; // For createFenceInst()
+ SelectInst *createSelectInst(llvm::SelectInst *SI);
+ friend SelectInst; // For createSelectInst()
+ InsertElementInst *createInsertElementInst(llvm::InsertElementInst *IEI);
+ friend InsertElementInst; // For createInsertElementInst()
+ ExtractElementInst *createExtractElementInst(llvm::ExtractElementInst *EEI);
+ friend ExtractElementInst; // For createExtractElementInst()
+ ShuffleVectorInst *createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
+ friend ShuffleVectorInst; // For createShuffleVectorInst()
+ ExtractValueInst *createExtractValueInst(llvm::ExtractValueInst *IVI);
+ friend ExtractValueInst; // For createExtractValueInst()
+ InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
+ friend InsertValueInst; // For createInsertValueInst()
+ BranchInst *createBranchInst(llvm::BranchInst *I);
+ friend BranchInst; // For createBranchInst()
+ LoadInst *createLoadInst(llvm::LoadInst *LI);
+ friend LoadInst; // For createLoadInst()
+ StoreInst *createStoreInst(llvm::StoreInst *SI);
+ friend StoreInst; // For createStoreInst()
+ ReturnInst *createReturnInst(llvm::ReturnInst *I);
+ friend ReturnInst; // For createReturnInst()
+ CallInst *createCallInst(llvm::CallInst *I);
+ friend CallInst; // For createCallInst()
+ InvokeInst *createInvokeInst(llvm::InvokeInst *I);
+ friend InvokeInst; // For createInvokeInst()
+ CallBrInst *createCallBrInst(llvm::CallBrInst *I);
+ friend CallBrInst; // For createCallBrInst()
+ LandingPadInst *createLandingPadInst(llvm::LandingPadInst *I);
+ friend LandingPadInst; // For createLandingPadInst()
+ CatchPadInst *createCatchPadInst(llvm::CatchPadInst *I);
+ friend CatchPadInst; // For createCatchPadInst()
+ CleanupPadInst *createCleanupPadInst(llvm::CleanupPadInst *I);
+ friend CleanupPadInst; // For createCleanupPadInst()
+ CatchReturnInst *createCatchReturnInst(llvm::CatchReturnInst *I);
+ friend CatchReturnInst; // For createCatchReturnInst()
+ CleanupReturnInst *createCleanupReturnInst(llvm::CleanupReturnInst *I);
+ friend CleanupReturnInst; // For createCleanupReturnInst()
+ GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
+ friend GetElementPtrInst; // For createGetElementPtrInst()
+ CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);
+ friend CatchSwitchInst; // For createCatchSwitchInst()
+ ResumeInst *createResumeInst(llvm::ResumeInst *I);
+ friend ResumeInst; // For createResumeInst()
+ SwitchInst *createSwitchInst(llvm::SwitchInst *I);
+ friend SwitchInst; // For createSwitchInst()
+ UnaryOperator *createUnaryOperator(llvm::UnaryOperator *I);
+ friend UnaryOperator; // For createUnaryOperator()
+ BinaryOperator *createBinaryOperator(llvm::BinaryOperator *I);
+ friend BinaryOperator; // For createBinaryOperator()
+ AtomicRMWInst *createAtomicRMWInst(llvm::AtomicRMWInst *I);
+ friend AtomicRMWInst; // For createAtomicRMWInst()
+ AtomicCmpXchgInst *createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I);
+ friend AtomicCmpXchgInst; // For createAtomicCmpXchgInst()
+ AllocaInst *createAllocaInst(llvm::AllocaInst *I);
+ friend AllocaInst; // For createAllocaInst()
+ CastInst *createCastInst(llvm::CastInst *I);
+ friend CastInst; // For createCastInst()
+ PHINode *createPHINode(llvm::PHINode *I);
+ friend PHINode; // For createPHINode()
+ UnreachableInst *createUnreachableInst(llvm::UnreachableInst *UI);
+ friend UnreachableInst; // For createUnreachableInst()
+ CmpInst *createCmpInst(llvm::CmpInst *I);
+ friend CmpInst; // For createCmpInst()
+ ICmpInst *createICmpInst(llvm::ICmpInst *I);
+ friend ICmpInst; // For createICmpInst()
+ FCmpInst *createFCmpInst(llvm::FCmpInst *I);
+ friend FCmpInst; // For createFCmpInst()
+
+public:
+ Context(LLVMContext &LLVMCtx)
+ : LLVMCtx(LLVMCtx), IRTracker(*this),
+ LLVMIRBuilder(LLVMCtx, ConstantFolder()) {}
+
+ Tracker &getTracker() { return IRTracker; }
+ /// Convenience function for `getTracker().save()`
+ void save() { IRTracker.save(); }
+ /// Convenience function for `getTracker().revert()`
+ void revert() { IRTracker.revert(); }
+ /// Convenience function for `getTracker().accept()`
+ void accept() { IRTracker.accept(); }
+
+ sandboxir::Value *getValue(llvm::Value *V) const;
+ const sandboxir::Value *getValue(const llvm::Value *V) const {
+ return getValue(const_cast<llvm::Value *>(V));
+ }
+
+ Module *getModule(llvm::Module *LLVMM) const;
+
+ Module *getOrCreateModule(llvm::Module *LLVMM);
+
+ Type *getType(llvm::Type *LLVMTy) {
+ if (LLVMTy == nullptr)
+ return nullptr;
+ auto Pair = LLVMTypeToTypeMap.insert({LLVMTy, nullptr});
+ auto It = Pair.first;
+ if (Pair.second)
+ It->second = std::unique_ptr<Type, TypeDeleter>(new Type(LLVMTy, *this));
+ return It->second.get();
+ }
+
+ /// Create a sandboxir::Function for an existing LLVM IR \p F, including all
+ /// blocks and instructions.
+ /// This is the main API function for creating Sandbox IR.
+ /// Note: this will not fully populate its parent module. The only globals
+ /// that will be available are those used within the function.
+ Function *createFunction(llvm::Function *F);
+
+ /// Create a sandboxir::Module corresponding to \p LLVMM.
+ Module *createModule(llvm::Module *LLVMM);
+
+ /// \Returns the number of values registered with Context.
+ size_t getNumValues() const { return LLVMValueToValueMap.size(); }
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_SANDBOXIR_CONTEXT_H
diff --git a/llvm/include/llvm/SandboxIR/SandboxIR.h b/llvm/include/llvm/SandboxIR/SandboxIR.h
index c9dd7d09d04bc2..eb4f7209798bdb 100644
--- a/llvm/include/llvm/SandboxIR/SandboxIR.h
+++ b/llvm/include/llvm/SandboxIR/SandboxIR.h
@@ -109,6 +109,7 @@
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
+#include "llvm/SandboxIR/Context.h"
#include "llvm/SandboxIR/Module.h"
#include "llvm/SandboxIR/Tracker.h"
#include "llvm/SandboxIR/Type.h"
@@ -4583,199 +4584,6 @@ class OpaqueInst : public SingleLLVMInstructionImpl<llvm::Instruction> {
}
};
-class Context {
-protected:
- LLVMContext &LLVMCtx;
- friend class Type; // For LLVMCtx.
- friend class PointerType; // For LLVMCtx.
- friend class CmpInst; // For LLVMCtx. TODO: cleanup when sandboxir::VectorType
- // is complete
- friend class IntegerType; // For LLVMCtx.
- friend class StructType; // For LLVMCtx.
- friend class ::llvm::TargetExtType; // For LLVMCtx.
- friend class Region; // For LLVMCtx.
-
- Tracker IRTracker;
-
- /// Maps LLVM Value to the corresponding sandboxir::Value. Owns all
- /// SandboxIR objects.
- DenseMap<llvm::Value *, std::unique_ptr<sandboxir::Value>>
- LLVMValueToValueMap;
-
- /// Maps an LLVM Module to the corresponding sandboxir::Module.
- DenseMap<llvm::Module *, std::unique_ptr<Module>> LLVMModuleToModuleMap;
-
- /// Type has a protected destructor to prohibit the user from managing the
- /// lifetime of the Type objects. Context is friend of Type, and this custom
- /// deleter can destroy Type.
- struct TypeDeleter {
- void operator()(Type *Ty) { delete Ty; }
- };
- /// Maps LLVM Type to the corresonding sandboxir::Type. Owns all Sandbox IR
- /// Type objects.
- DenseMap<llvm::Type *, std::unique_ptr<Type, TypeDeleter>> LLVMTypeToTypeMap;
-
- /// Remove \p V from the maps and returns the unique_ptr.
- std::unique_ptr<Value> detachLLVMValue(llvm::Value *V);
- /// Remove \p SBV from all SandboxIR maps and stop owning it. This effectively
- /// detaches \p V from the underlying IR.
- std::unique_ptr<Value> detach(Value *V);
- friend void Instruction::eraseFromParent(); // For detach().
- /// Take ownership of VPtr and store it in `LLVMValueToValueMap`.
- Value *registerValue(std::unique_ptr<Value> &&VPtr);
- friend class EraseFromParent; // For registerValue().
- /// This is the actual function that creates sandboxir values for \p V,
- /// and among others handles all instruction types.
- Value *getOrCreateValueInternal(llvm::Value *V, llvm::User *U = nullptr);
- /// Get or create a sandboxir::Argument for an existing LLVM IR \p LLVMArg.
- Argument *getOrCreateArgument(llvm::Argument *LLVMArg) {
- auto Pair = LLVMValueToValueMap.insert({LLVMArg, nullptr});
- auto It = Pair.first;
- if (Pair.second) {
- It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
- return cast<Argument>(It->second.get());
- }
- return cast<Argument>(It->second.get());
- }
- /// Get or create a sandboxir::Value for an existing LLVM IR \p LLVMV.
- Value *getOrCreateValue(llvm::Value *LLVMV) {
- return getOrCreateValueInternal(LLVMV, 0);
- }
- /// Get or create a sandboxir::Constant from an existing LLVM IR \p LLVMC.
- Constant *getOrCreateConstant(llvm::Constant *LLVMC) {
- return cast<Constant>(getOrCreateValueInternal(LLVMC, 0));
- }
- // Friends for getOrCreateConstant().
-#define DEF_CONST(ID, CLASS) friend class CLASS;
-#include "llvm/SandboxIR/SandboxIRValues.def"
-
- /// Create a sandboxir::BasicBlock for an existing LLVM IR \p BB. This will
- /// also create all contents of the block.
- BasicBlock *createBasicBlock(llvm::BasicBlock *BB);
- friend class BasicBlock; // For getOrCreateValue().
-
- IRBuilder<ConstantFolder> LLVMIRBuilder;
- auto &getLLVMIRBuilder() { return LLVMIRBuilder; }
-
- VAArgInst *createVAArgInst(llvm::VAArgInst *SI);
- friend VAArgInst; // For createVAArgInst()
- FreezeInst *createFreezeInst(llvm::FreezeInst *SI);
- friend FreezeInst; // For createFreezeInst()
- FenceInst *createFenceInst(llvm::FenceInst *SI);
- friend FenceInst; // For createFenceInst()
- SelectInst *createSelectInst(llvm::SelectInst *SI);
- friend SelectInst; // For createSelectInst()
- InsertElementInst *createInsertElementInst(llvm::InsertElementInst *IEI);
- friend InsertElementInst; // For createInsertElementInst()
- ExtractElementInst *createExtractElementInst(llvm::ExtractElementInst *EEI);
- friend ExtractElementInst; // For createExtractElementInst()
- ShuffleVectorInst *createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
- friend ShuffleVectorInst; // For createShuffleVectorInst()
- ExtractValueInst *createExtractValueInst(llvm::ExtractValueInst *IVI);
- friend ExtractValueInst; // For createExtractValueInst()
- InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
- friend InsertValueInst; // For createInsertValueInst()
- BranchInst *createBranchInst(llvm::BranchInst *I);
- friend BranchInst; // For createBranchInst()
- LoadInst *createLoadInst(llvm::LoadInst *LI);
- friend LoadInst; // For createLoadInst()
- StoreInst *createStoreInst(llvm::StoreInst *SI);
- friend StoreInst; // For createStoreInst()
- ReturnInst *createReturnInst(llvm::ReturnInst *I);
- friend ReturnInst; // For createReturnInst()
- CallInst *createCallInst(llvm::CallInst *I);
- friend CallInst; // For createCallInst()
- InvokeInst *createInvokeInst(llvm::InvokeInst *I);
- friend InvokeInst; // For createInvokeInst()
- CallBrInst *createCallBrInst(llvm::CallBrInst *I);
- friend CallBrInst; // For createCallBrInst()
- LandingPadInst *createLandingPadInst(llvm::LandingPadInst *I);
- friend LandingPadInst; // For createLandingPadInst()
- CatchPadInst *createCatchPadInst(llvm::CatchPadInst *I);
- friend CatchPadInst; // For createCatchPadInst()
- CleanupPadInst *createCleanupPadInst(llvm::CleanupPadInst *I);
- friend CleanupPadInst; // For createCleanupPadInst()
- CatchReturnInst *createCatchReturnInst(llvm::CatchReturnInst *I);
- friend CatchReturnInst; // For createCatchReturnInst()
- CleanupReturnInst *createCleanupReturnInst(llvm::CleanupReturnInst *I);
- friend CleanupReturnInst; // For createCleanupReturnInst()
- GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
- friend GetElementPtrInst; // For createGetElementPtrInst()
- CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);
- friend CatchSwitchInst; // For createCatchSwitchInst()
- ResumeInst *createResumeInst(llvm::ResumeInst *I);
- friend ResumeInst; // For createResumeInst()
- SwitchInst *createSwitchInst(llvm::SwitchInst *I);
- friend SwitchInst; // For createSwitchInst()
- UnaryOperator *createUnaryOperator(llvm::UnaryOperator *I);
- friend UnaryOperator; // For createUnaryOperator()
- BinaryOperator *createBinaryOperator(llvm::BinaryOperator *I);
- friend BinaryOperator; // For createBinaryOperator()
- AtomicRMWInst *createAtomicRMWInst(llvm::AtomicRMWInst *I);
- friend AtomicRMWInst; // For createAtomicRMWInst()
- AtomicCmpXchgInst *createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I);
- friend AtomicCmpXchgInst; // For createAtomicCmpXchgInst()
- AllocaInst *createAllocaInst(llvm::AllocaInst *I);
- friend AllocaInst; // For createAllocaInst()
- CastInst *createCastInst(llvm::CastInst *I);
- friend CastInst; // For createCastInst()
- PHINode *createPHINode(llvm::PHINode *I);
- friend PHINode; // For createPHINode()
- UnreachableInst *createUnreachableInst(llvm::UnreachableInst *UI);
- friend UnreachableInst; // For createUnreachableInst()
- CmpInst *createCmpInst(llvm::CmpInst *I);
- friend CmpInst; // For createCmpInst()
- ICmpInst *createICmpInst(llvm::ICmpInst *I);
- friend ICmpInst; // For createICmpInst()
- FCmpInst *createFCmpInst(llvm::FCmpInst *I);
- friend FCmpInst; // For createFCmpInst()
-
-public:
- Context(LLVMContext &LLVMCtx)
- : LLVMCtx(LLVMCtx), IRTracker(*this),
- LLVMIRBuilder(LLVMCtx, ConstantFolder()) {}
-
- Tracker &getTracker() { return IRTracker; }
- /// Convenience function for `getTracker().save()`
- void save() { IRTracker.save(); }
- /// Convenience function for `getTracker().revert()`
- void revert() { IRTracker.revert(); }
- /// Convenience function for `getTracker().accept()`
- void accept() { IRTracker.accept(); }
-
- sandboxir::Value *getValue(llvm::Value *V) const;
- const sandboxir::Value *getValue(const llvm::Value *V) const {
- return getValue(const_cast<llvm::Value *>(V));
- }
-
- Module *getModule(llvm::Module *LLVMM) const;
-
- Module *getOrCreateModule(llvm::Module *LLVMM);
-
- Type *getType(llvm::Type *LLVMTy) {
- if (LLVMTy == nullptr)
- return nullptr;
- auto Pair = LLVMTypeToTypeMap.insert({LLVMTy, nullptr});
- auto It = Pair.first;
- if (Pair.second)
- It->second = std::unique_ptr<Type, TypeDeleter>(new Type(LLVMTy, *this));
- return It->second.get();
- }
-
- /// Create a sandboxir::Function for an existing LLVM IR \p F, including all
- /// blocks and instructions.
- /// This is the main API function for creating Sandbox IR.
- /// Note: this will not fully populate its parent module. The only globals
- /// that will be available are those used within the function.
- Function *createFunction(llvm::Function *F);
-
- /// Create a sandboxir::Module corresponding to \p LLVMM.
- Module *createModule(llvm::Module *LLVMM);
-
- /// \Returns the number of values registered with Context.
- size_t getNumValues() const { return LLVMValueToValueMap.size(); }
-};
-
class Function : public GlobalWithNodeAPI<Function, llvm::Function,
GlobalObject, llvm::GlobalObject> {
/// Helper for mapped_iterator.
diff --git a/llvm/lib/SandboxIR/CMakeLists.txt b/llvm/lib/SandboxIR/CMakeLists.txt
index 7a3b7f65dddc85..1bbbb8c1ac9e86 100644
--- a/llvm/lib/SandboxIR/CMakeLists.txt
+++ b/llvm/lib/SandboxIR/CMakeLists.txt
@@ -1,4 +1,5 @@
add_llvm_component_library(LLVMSandboxIR
+ Context.cpp
Module.cpp
Pass.cpp
PassManager.cpp
diff --git a/llvm/lib/SandboxIR/Context.cpp b/llvm/lib/SandboxIR/Context.cpp
new file mode 100644
index 00000000000000..1dc239ba482880
--- /dev/null
+++ b/llvm/lib/SandboxIR/Context.cpp
@@ -0,0 +1,717 @@
+//===- Context.cpp - The Context class of Sandbox 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/Context.h"
+#include "llvm/SandboxIR/SandboxIR.h"
+
+namespace llvm::sandboxir {
+
+std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
+ std::unique_ptr<Value> Erased;
+ auto It = LLVMValueToValueMap.find(V);
+ if (It != LLVMValueToValueMap.end()) {
+ auto *Val = It->second.release();
+ Erased = std::unique_ptr<Value>(Val);
+ LLVMValueToValueMap.erase(It);
+ }
+ return Erased;
+}
+
+std::unique_ptr<Value> Context::detach(Value *V) {
+ assert(V->getSubclassID() != Value::ClassID::Constant &&
+ "Can't detach a constant!");
+ assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
+ return detachLLVMValue(V->Val);
+}
+
+Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
+ assert(VPtr->getSubclassID() != Value::ClassID::User &&
+ "Can't register a user!");
+
+ // Track creation of instructions.
+ // Please note that we don't allow the creation of detached instructions,
+ // meaning that the instructions need to be inserted into a block upon
+ // creation. This is why the tracker class combines creation and insertion.
+ if (auto *I = dyn_cast<Instruction>(VPtr.get()))
+ getTracker().emplaceIfTracking<CreateAndInsertInst>(I);
+
+ Value *V = VPtr.get();
+ [[maybe_unused]] auto Pair =
+ LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
+ assert(Pair.second && "Already exists!");
+ return V;
+}
+
+Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
+ auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr});
+ auto It = Pair.first;
+ if (!Pair.second)
+ return It->second.get();
+
+ if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
+ switch (C->getValueID()) {
+ case llvm::Value::ConstantIntVal:
+ It->second = std::unique_ptr<ConstantInt>(
+ new ConstantInt(cast<llvm::ConstantInt>(C), *this));
+ return It->second.get();
+ case llvm::Value::ConstantFPVal:
+ It->second = std::unique_ptr<ConstantFP>(
+ new ConstantFP(cast<llvm::ConstantFP>(C), *this));
+ return It->second.get();
+ case llvm::Value::BlockAddressVal:
+ It->second = std::unique_ptr<BlockAddress>(
+ new BlockAddress(cast<llvm::BlockAddress>(C), *this));
+ return It->second.get();
+ case llvm::Value::ConstantTokenNoneVal:
+ It->second = std::unique_ptr<ConstantTokenNone>(
+ new ConstantTokenNone(cast<llvm::ConstantTokenNone>(C), *this));
+ return It->second.get();
+ case llvm::Value::ConstantAggregateZeroVal: {
+ auto *CAZ = cast<llvm::ConstantAggregateZero>(C);
+ It->second = std::unique_ptr<ConstantAggregateZero>(
+ new ConstantAggregateZero(CAZ, *this));
+ auto *Ret = It->second.get();
+ // Must create sandboxir for elements.
+ auto EC = CAZ->getElementCount();
+ if (EC.isFixed()) {
+ for (auto ElmIdx : seq<unsigned>(0, EC.getFixedValue()))
+ getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ);
+ }
+ return Ret;
+ }
+ case llvm::Value::ConstantPointerNullVal:
+ It->second = std::unique_ptr<ConstantPointerNull>(
+ new ConstantPointerNull(cast<llvm::ConstantPointerNull>(C), *this));
+ return It->second.get();
+ case llvm::Value::PoisonValueVal:
+ It->second = std::unique_ptr<PoisonValue>(
+ new PoisonValue(cast<llvm::PoisonValue>(C), *this));
+ return It->second.get();
+ case llvm::Value::UndefValueVal:
+ It->second = std::unique_ptr<UndefValue>(
+ new UndefValue(cast<llvm::UndefValue>(C), *this));
+ return It->second.get();
+ case llvm::Value::DSOLocalEquivalentVal: {
+ auto *DSOLE = cast<llvm::DSOLocalEquivalent>(C);
+ It->second = std::unique_ptr<DSOLocalEquivalent>(
+ new DSOLocalEquivalent(DSOLE, *this));
+ auto *Ret = It->second.get();
+ getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE);
+ return Ret;
+ }
+ case llvm::Value::ConstantArrayVal:
+ It->second = std::unique_ptr<ConstantArray>(
+ new ConstantArray(cast<llvm::ConstantArray>(C), *this));
+ break;
+ case llvm::Value::ConstantStructVal:
+ It->second = std::unique_ptr<ConstantStruct>(
+ new ConstantStruct(cast<llvm::ConstantStruct>(C), *this));
+ break;
+ case llvm::Value::ConstantVectorVal:
+ It->second = std::unique_ptr<ConstantVector>(
+ new ConstantVector(cast<llvm::ConstantVector>(C), *this));
+ break;
+ case llvm::Value::FunctionVal:
+ It->second = std::unique_ptr<Function>(
+ new Function(cast<llvm::Function>(C), *this));
+ break;
+ case llvm::Value::GlobalIFuncVal:
+ It->second = std::unique_ptr<GlobalIFunc>(
+ new GlobalIFunc(cast<llvm::GlobalIFunc>(C), *this));
+ break;
+ case llvm::Value::GlobalVariableVal:
+ It->second = std::unique_ptr<GlobalVariable>(
+ new GlobalVariable(cast<llvm::GlobalVariable>(C), *this));
+ break;
+ case llvm::Value::GlobalAliasVal:
+ It->second = std::unique_ptr<GlobalAlias>(
+ new GlobalAlias(cast<llvm::GlobalAlias>(C), *this));
+ break;
+ case llvm::Value::NoCFIValueVal:
+ It->second = std::unique_ptr<NoCFIValue>(
+ new NoCFIValue(cast<llvm::NoCFIValue>(C), *this));
+ break;
+ case llvm::Value::ConstantPtrAuthVal:
+ It->second = std::unique_ptr<ConstantPtrAuth>(
+ new ConstantPtrAuth(cast<llvm::ConstantPtrAuth>(C), *this));
+ break;
+ case llvm::Value::ConstantExprVal:
+ It->second = std::unique_ptr<ConstantExpr>(
+ new ConstantExpr(cast<llvm::ConstantExpr>(C), *this));
+ break;
+ default:
+ It->second = std::unique_ptr<Constant>(new Constant(C, *this));
+ break;
+ }
+ auto *NewC = It->second.get();
+ for (llvm::Value *COp : C->operands())
+ getOrCreateValueInternal(COp, C);
+ return NewC;
+ }
+ if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
+ It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
+ return It->second.get();
+ }
+ if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
+ assert(isa<llvm::BlockAddress>(U) &&
+ "This won't create a SBBB, don't call this function directly!");
+ if (auto *SBBB = getValue(BB))
+ return SBBB;
+ return nullptr;
+ }
+ assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
+
+ switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
+ case llvm::Instruction::VAArg: {
+ auto *LLVMVAArg = cast<llvm::VAArgInst>(LLVMV);
+ It->second = std::unique_ptr<VAArgInst>(new VAArgInst(LLVMVAArg, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Freeze: {
+ auto *LLVMFreeze = cast<llvm::FreezeInst>(LLVMV);
+ It->second = std::unique_ptr<FreezeInst>(new FreezeInst(LLVMFreeze, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Fence: {
+ auto *LLVMFence = cast<llvm::FenceInst>(LLVMV);
+ It->second = std::unique_ptr<FenceInst>(new FenceInst(LLVMFence, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Select: {
+ auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
+ It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::ExtractElement: {
+ auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
+ It->second = std::unique_ptr<ExtractElementInst>(
+ new ExtractElementInst(LLVMIns, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::InsertElement: {
+ auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
+ It->second = std::unique_ptr<InsertElementInst>(
+ new InsertElementInst(LLVMIns, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::ShuffleVector: {
+ auto *LLVMIns = cast<llvm::ShuffleVectorInst>(LLVMV);
+ It->second = std::unique_ptr<ShuffleVectorInst>(
+ new ShuffleVectorInst(LLVMIns, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::ExtractValue: {
+ auto *LLVMIns = cast<llvm::ExtractValueInst>(LLVMV);
+ It->second =
+ std::unique_ptr<ExtractValueInst>(new ExtractValueInst(LLVMIns, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::InsertValue: {
+ auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
+ It->second =
+ std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Br: {
+ auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
+ It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Load: {
+ auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
+ It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Store: {
+ auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
+ It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Ret: {
+ auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
+ It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Call: {
+ auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
+ It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Invoke: {
+ auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
+ It->second = std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::CallBr: {
+ auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
+ It->second = std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::LandingPad: {
+ auto *LLVMLPad = cast<llvm::LandingPadInst>(LLVMV);
+ It->second =
+ std::unique_ptr<LandingPadInst>(new LandingPadInst(LLVMLPad, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::CatchPad: {
+ auto *LLVMCPI = cast<llvm::CatchPadInst>(LLVMV);
+ It->second =
+ std::unique_ptr<CatchPadInst>(new CatchPadInst(LLVMCPI, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::CleanupPad: {
+ auto *LLVMCPI = cast<llvm::CleanupPadInst>(LLVMV);
+ It->second =
+ std::unique_ptr<CleanupPadInst>(new CleanupPadInst(LLVMCPI, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::CatchRet: {
+ auto *LLVMCRI = cast<llvm::CatchReturnInst>(LLVMV);
+ It->second =
+ std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::CleanupRet: {
+ auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV);
+ It->second = std::unique_ptr<CleanupReturnInst>(
+ new CleanupReturnInst(LLVMCRI, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::GetElementPtr: {
+ auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
+ It->second = std::unique_ptr<GetElementPtrInst>(
+ new GetElementPtrInst(LLVMGEP, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::CatchSwitch: {
+ auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV);
+ It->second = std::unique_ptr<CatchSwitchInst>(
+ new CatchSwitchInst(LLVMCatchSwitchInst, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Resume: {
+ auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV);
+ It->second =
+ std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Switch: {
+ auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
+ It->second =
+ std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::FNeg: {
+ auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
+ It->second = std::unique_ptr<UnaryOperator>(
+ new UnaryOperator(LLVMUnaryOperator, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Add:
+ case llvm::Instruction::FAdd:
+ case llvm::Instruction::Sub:
+ case llvm::Instruction::FSub:
+ case llvm::Instruction::Mul:
+ case llvm::Instruction::FMul:
+ case llvm::Instruction::UDiv:
+ case llvm::Instruction::SDiv:
+ case llvm::Instruction::FDiv:
+ case llvm::Instruction::URem:
+ case llvm::Instruction::SRem:
+ case llvm::Instruction::FRem:
+ case llvm::Instruction::Shl:
+ case llvm::Instruction::LShr:
+ case llvm::Instruction::AShr:
+ case llvm::Instruction::And:
+ case llvm::Instruction::Or:
+ case llvm::Instruction::Xor: {
+ auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
+ It->second = std::unique_ptr<BinaryOperator>(
+ new BinaryOperator(LLVMBinaryOperator, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::AtomicRMW: {
+ auto *LLVMAtomicRMW = cast<llvm::AtomicRMWInst>(LLVMV);
+ It->second =
+ std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(LLVMAtomicRMW, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::AtomicCmpXchg: {
+ auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
+ It->second = std::unique_ptr<AtomicCmpXchgInst>(
+ new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Alloca: {
+ auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
+ It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::ZExt:
+ case llvm::Instruction::SExt:
+ case llvm::Instruction::FPToUI:
+ case llvm::Instruction::FPToSI:
+ case llvm::Instruction::FPExt:
+ case llvm::Instruction::PtrToInt:
+ case llvm::Instruction::IntToPtr:
+ case llvm::Instruction::SIToFP:
+ case llvm::Instruction::UIToFP:
+ case llvm::Instruction::Trunc:
+ case llvm::Instruction::FPTrunc:
+ case llvm::Instruction::BitCast:
+ case llvm::Instruction::AddrSpaceCast: {
+ auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
+ It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::PHI: {
+ auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
+ It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::ICmp: {
+ auto *LLVMICmp = cast<llvm::ICmpInst>(LLVMV);
+ It->second = std::unique_ptr<ICmpInst>(new ICmpInst(LLVMICmp, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::FCmp: {
+ auto *LLVMFCmp = cast<llvm::FCmpInst>(LLVMV);
+ It->second = std::unique_ptr<FCmpInst>(new FCmpInst(LLVMFCmp, *this));
+ return It->second.get();
+ }
+ case llvm::Instruction::Unreachable: {
+ auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
+ It->second = std::unique_ptr<UnreachableInst>(
+ new UnreachableInst(LLVMUnreachable, *this));
+ return It->second.get();
+ }
+ default:
+ break;
+ }
+
+ It->second = std::unique_ptr<OpaqueInst>(
+ new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
+ return It->second.get();
+}
+
+Argument *Context::getOrCreateArgument(llvm::Argument *LLVMArg) {
+ auto Pair = LLVMValueToValueMap.insert({LLVMArg, nullptr});
+ auto It = Pair.first;
+ if (Pair.second) {
+ It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
+ return cast<Argument>(It->second.get());
+ }
+ return cast<Argument>(It->second.get());
+}
+
+BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
+ assert(getValue(LLVMBB) == nullptr && "Already exists!");
+ auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
+ auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
+ // Create SandboxIR for BB's body.
+ BB->buildBasicBlockFromLLVMIR(LLVMBB);
+ return BB;
+}
+
+VAArgInst *Context::createVAArgInst(llvm::VAArgInst *SI) {
+ auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this));
+ return cast<VAArgInst>(registerValue(std::move(NewPtr)));
+}
+
+FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) {
+ auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this));
+ return cast<FreezeInst>(registerValue(std::move(NewPtr)));
+}
+
+FenceInst *Context::createFenceInst(llvm::FenceInst *SI) {
+ auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this));
+ return cast<FenceInst>(registerValue(std::move(NewPtr)));
+}
+
+SelectInst *Context::createSelectInst(llvm::SelectInst *SI) {
+ auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
+ return cast<SelectInst>(registerValue(std::move(NewPtr)));
+}
+
+ExtractElementInst *
+Context::createExtractElementInst(llvm::ExtractElementInst *EEI) {
+ auto NewPtr =
+ std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
+ return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
+}
+
+InsertElementInst *
+Context::createInsertElementInst(llvm::InsertElementInst *IEI) {
+ auto NewPtr =
+ std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
+ return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
+}
+
+ShuffleVectorInst *
+Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) {
+ auto NewPtr =
+ std::unique_ptr<ShuffleVectorInst>(new ShuffleVectorInst(SVI, *this));
+ return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
+}
+
+ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) {
+ auto NewPtr =
+ std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this));
+ return cast<ExtractValueInst>(registerValue(std::move(NewPtr)));
+}
+
+InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
+ auto NewPtr =
+ std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
+ return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
+}
+
+BranchInst *Context::createBranchInst(llvm::BranchInst *BI) {
+ auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
+ return cast<BranchInst>(registerValue(std::move(NewPtr)));
+}
+
+LoadInst *Context::createLoadInst(llvm::LoadInst *LI) {
+ auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
+ return cast<LoadInst>(registerValue(std::move(NewPtr)));
+}
+
+StoreInst *Context::createStoreInst(llvm::StoreInst *SI) {
+ auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
+ return cast<StoreInst>(registerValue(std::move(NewPtr)));
+}
+
+ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) {
+ auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
+ return cast<ReturnInst>(registerValue(std::move(NewPtr)));
+}
+
+CallInst *Context::createCallInst(llvm::CallInst *I) {
+ auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
+ return cast<CallInst>(registerValue(std::move(NewPtr)));
+}
+
+InvokeInst *Context::createInvokeInst(llvm::InvokeInst *I) {
+ auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
+ return cast<InvokeInst>(registerValue(std::move(NewPtr)));
+}
+
+CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) {
+ auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
+ return cast<CallBrInst>(registerValue(std::move(NewPtr)));
+}
+
+UnreachableInst *Context::createUnreachableInst(llvm::UnreachableInst *UI) {
+ auto NewPtr =
+ std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
+ return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
+}
+LandingPadInst *Context::createLandingPadInst(llvm::LandingPadInst *I) {
+ auto NewPtr = std::unique_ptr<LandingPadInst>(new LandingPadInst(I, *this));
+ return cast<LandingPadInst>(registerValue(std::move(NewPtr)));
+}
+CatchPadInst *Context::createCatchPadInst(llvm::CatchPadInst *I) {
+ auto NewPtr = std::unique_ptr<CatchPadInst>(new CatchPadInst(I, *this));
+ return cast<CatchPadInst>(registerValue(std::move(NewPtr)));
+}
+CleanupPadInst *Context::createCleanupPadInst(llvm::CleanupPadInst *I) {
+ auto NewPtr = std::unique_ptr<CleanupPadInst>(new CleanupPadInst(I, *this));
+ return cast<CleanupPadInst>(registerValue(std::move(NewPtr)));
+}
+CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) {
+ auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
+ return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
+}
+CleanupReturnInst *
+Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) {
+ auto NewPtr =
+ std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this));
+ return cast<CleanupReturnInst>(registerValue(std::move(NewPtr)));
+}
+GetElementPtrInst *
+Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
+ auto NewPtr =
+ std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
+ return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
+}
+CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) {
+ auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
+ return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
+}
+ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) {
+ auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this));
+ return cast<ResumeInst>(registerValue(std::move(NewPtr)));
+}
+SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) {
+ auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
+ return cast<SwitchInst>(registerValue(std::move(NewPtr)));
+}
+UnaryOperator *Context::createUnaryOperator(llvm::UnaryOperator *I) {
+ auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this));
+ return cast<UnaryOperator>(registerValue(std::move(NewPtr)));
+}
+BinaryOperator *Context::createBinaryOperator(llvm::BinaryOperator *I) {
+ auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this));
+ return cast<BinaryOperator>(registerValue(std::move(NewPtr)));
+}
+AtomicRMWInst *Context::createAtomicRMWInst(llvm::AtomicRMWInst *I) {
+ auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this));
+ return cast<AtomicRMWInst>(registerValue(std::move(NewPtr)));
+}
+AtomicCmpXchgInst *
+Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) {
+ auto NewPtr =
+ std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
+ return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
+}
+AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) {
+ auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
+ return cast<AllocaInst>(registerValue(std::move(NewPtr)));
+}
+CastInst *Context::createCastInst(llvm::CastInst *I) {
+ auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
+ return cast<CastInst>(registerValue(std::move(NewPtr)));
+}
+PHINode *Context::createPHINode(llvm::PHINode *I) {
+ auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
+ return cast<PHINode>(registerValue(std::move(NewPtr)));
+}
+ICmpInst *Context::createICmpInst(llvm::ICmpInst *I) {
+ auto NewPtr = std::unique_ptr<ICmpInst>(new ICmpInst(I, *this));
+ return cast<ICmpInst>(registerValue(std::move(NewPtr)));
+}
+FCmpInst *Context::createFCmpInst(llvm::FCmpInst *I) {
+ auto NewPtr = std::unique_ptr<FCmpInst>(new FCmpInst(I, *this));
+ return cast<FCmpInst>(registerValue(std::move(NewPtr)));
+}
+CmpInst *CmpInst::create(Predicate P, Value *S1, Value *S2,
+ Instruction *InsertBefore, Context &Ctx,
+ const Twine &Name) {
+ auto &Builder = Ctx.getLLVMIRBuilder();
+ Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
+ auto *LLVMI = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
+ if (dyn_cast<llvm::ICmpInst>(LLVMI))
+ return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMI));
+ return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMI));
+}
+CmpInst *CmpInst::createWithCopiedFlags(Predicate P, Value *S1, Value *S2,
+ const Instruction *F,
+ Instruction *InsertBefore, Context &Ctx,
+ const Twine &Name) {
+ CmpInst *Inst = create(P, S1, S2, InsertBefore, Ctx, Name);
+ cast<llvm::CmpInst>(Inst->Val)->copyIRFlags(F->Val);
+ return Inst;
+}
+
+Type *CmpInst::makeCmpResultType(Type *OpndType) {
+ if (auto *VT = dyn_cast<VectorType>(OpndType)) {
+ // TODO: Cleanup when we have more complete support for
+ // sandboxir::VectorType
+ return OpndType->getContext().getType(llvm::VectorType::get(
+ llvm::Type::getInt1Ty(OpndType->getContext().LLVMCtx),
+ cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
+ }
+ return Type::getInt1Ty(OpndType->getContext());
+}
+
+void CmpInst::setPredicate(Predicate P) {
+ Ctx.getTracker()
+ .emplaceIfTracking<
+ GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this);
+ cast<llvm::CmpInst>(Val)->setPredicate(P);
+}
+
+void CmpInst::swapOperands() {
+ if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
+ IC->swapOperands();
+ else
+ cast<FCmpInst>(this)->swapOperands();
+}
+
+void ICmpInst::swapOperands() {
+ Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
+ cast<llvm::ICmpInst>(Val)->swapOperands();
+}
+
+void FCmpInst::swapOperands() {
+ Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
+ cast<llvm::FCmpInst>(Val)->swapOperands();
+}
+
+#ifndef NDEBUG
+void CmpInst::dumpOS(raw_ostream &OS) const {
+ dumpCommonPrefix(OS);
+ dumpCommonSuffix(OS);
+}
+
+void CmpInst::dump() const {
+ dumpOS(dbgs());
+ dbgs() << "\n";
+}
+#endif // NDEBUG
+
+Value *Context::getValue(llvm::Value *V) const {
+ auto It = LLVMValueToValueMap.find(V);
+ if (It != LLVMValueToValueMap.end())
+ return It->second.get();
+ return nullptr;
+}
+
+Module *Context::getModule(llvm::Module *LLVMM) const {
+ auto It = LLVMModuleToModuleMap.find(LLVMM);
+ if (It != LLVMModuleToModuleMap.end())
+ return It->second.get();
+ return nullptr;
+}
+
+Module *Context::getOrCreateModule(llvm::Module *LLVMM) {
+ auto Pair = LLVMModuleToModuleMap.insert({LLVMM, nullptr});
+ auto It = Pair.first;
+ if (!Pair.second)
+ return It->second.get();
+ It->second = std::unique_ptr<Module>(new Module(*LLVMM, *this));
+ return It->second.get();
+}
+
+Function *Context::createFunction(llvm::Function *F) {
+ assert(getValue(F) == nullptr && "Already exists!");
+ // Create the module if needed before we create the new sandboxir::Function.
+ // Note: this won't fully populate the module. The only globals that will be
+ // available will be the ones being used within the function.
+ getOrCreateModule(F->getParent());
+
+ auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
+ auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
+ // Create arguments.
+ for (auto &Arg : F->args())
+ getOrCreateArgument(&Arg);
+ // Create BBs.
+ for (auto &BB : *F)
+ createBasicBlock(&BB);
+ return SBF;
+}
+
+Module *Context::createModule(llvm::Module *LLVMM) {
+ auto *M = getOrCreateModule(LLVMM);
+ // Create the functions.
+ for (auto &LLVMF : *LLVMM)
+ createFunction(&LLVMF);
+ // Create globals.
+ for (auto &Global : LLVMM->globals())
+ getOrCreateValue(&Global);
+ // Create aliases.
+ for (auto &Alias : LLVMM->aliases())
+ getOrCreateValue(&Alias);
+ // Create ifuncs.
+ for (auto &IFunc : LLVMM->ifuncs())
+ getOrCreateValue(&IFunc);
+
+ return M;
+}
+
+} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/SandboxIR.cpp b/llvm/lib/SandboxIR/SandboxIR.cpp
index 60026d7dcea63b..5f005bd1f5d084 100644
--- a/llvm/lib/SandboxIR/SandboxIR.cpp
+++ b/llvm/lib/SandboxIR/SandboxIR.cpp
@@ -2763,699 +2763,6 @@ BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
return cast_or_null<Instruction>(Ctx->getValue(&*It));
}
-std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
- std::unique_ptr<Value> Erased;
- auto It = LLVMValueToValueMap.find(V);
- if (It != LLVMValueToValueMap.end()) {
- auto *Val = It->second.release();
- Erased = std::unique_ptr<Value>(Val);
- LLVMValueToValueMap.erase(It);
- }
- return Erased;
-}
-
-std::unique_ptr<Value> Context::detach(Value *V) {
- assert(V->getSubclassID() != Value::ClassID::Constant &&
- "Can't detach a constant!");
- assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
- return detachLLVMValue(V->Val);
-}
-
-Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
- assert(VPtr->getSubclassID() != Value::ClassID::User &&
- "Can't register a user!");
-
- // Track creation of instructions.
- // Please note that we don't allow the creation of detached instructions,
- // meaning that the instructions need to be inserted into a block upon
- // creation. This is why the tracker class combines creation and insertion.
- if (auto *I = dyn_cast<Instruction>(VPtr.get()))
- getTracker().emplaceIfTracking<CreateAndInsertInst>(I);
-
- Value *V = VPtr.get();
- [[maybe_unused]] auto Pair =
- LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
- assert(Pair.second && "Already exists!");
- return V;
-}
-
-Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
- auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr});
- auto It = Pair.first;
- if (!Pair.second)
- return It->second.get();
-
- if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
- switch (C->getValueID()) {
- case llvm::Value::ConstantIntVal:
- It->second = std::unique_ptr<ConstantInt>(
- new ConstantInt(cast<llvm::ConstantInt>(C), *this));
- return It->second.get();
- case llvm::Value::ConstantFPVal:
- It->second = std::unique_ptr<ConstantFP>(
- new ConstantFP(cast<llvm::ConstantFP>(C), *this));
- return It->second.get();
- case llvm::Value::BlockAddressVal:
- It->second = std::unique_ptr<BlockAddress>(
- new BlockAddress(cast<llvm::BlockAddress>(C), *this));
- return It->second.get();
- case llvm::Value::ConstantTokenNoneVal:
- It->second = std::unique_ptr<ConstantTokenNone>(
- new ConstantTokenNone(cast<llvm::ConstantTokenNone>(C), *this));
- return It->second.get();
- case llvm::Value::ConstantAggregateZeroVal: {
- auto *CAZ = cast<llvm::ConstantAggregateZero>(C);
- It->second = std::unique_ptr<ConstantAggregateZero>(
- new ConstantAggregateZero(CAZ, *this));
- auto *Ret = It->second.get();
- // Must create sandboxir for elements.
- auto EC = CAZ->getElementCount();
- if (EC.isFixed()) {
- for (auto ElmIdx : seq<unsigned>(0, EC.getFixedValue()))
- getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ);
- }
- return Ret;
- }
- case llvm::Value::ConstantPointerNullVal:
- It->second = std::unique_ptr<ConstantPointerNull>(
- new ConstantPointerNull(cast<llvm::ConstantPointerNull>(C), *this));
- return It->second.get();
- case llvm::Value::PoisonValueVal:
- It->second = std::unique_ptr<PoisonValue>(
- new PoisonValue(cast<llvm::PoisonValue>(C), *this));
- return It->second.get();
- case llvm::Value::UndefValueVal:
- It->second = std::unique_ptr<UndefValue>(
- new UndefValue(cast<llvm::UndefValue>(C), *this));
- return It->second.get();
- case llvm::Value::DSOLocalEquivalentVal: {
- auto *DSOLE = cast<llvm::DSOLocalEquivalent>(C);
- It->second = std::unique_ptr<DSOLocalEquivalent>(
- new DSOLocalEquivalent(DSOLE, *this));
- auto *Ret = It->second.get();
- getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE);
- return Ret;
- }
- case llvm::Value::ConstantArrayVal:
- It->second = std::unique_ptr<ConstantArray>(
- new ConstantArray(cast<llvm::ConstantArray>(C), *this));
- break;
- case llvm::Value::ConstantStructVal:
- It->second = std::unique_ptr<ConstantStruct>(
- new ConstantStruct(cast<llvm::ConstantStruct>(C), *this));
- break;
- case llvm::Value::ConstantVectorVal:
- It->second = std::unique_ptr<ConstantVector>(
- new ConstantVector(cast<llvm::ConstantVector>(C), *this));
- break;
- case llvm::Value::FunctionVal:
- It->second = std::unique_ptr<Function>(
- new Function(cast<llvm::Function>(C), *this));
- break;
- case llvm::Value::GlobalIFuncVal:
- It->second = std::unique_ptr<GlobalIFunc>(
- new GlobalIFunc(cast<llvm::GlobalIFunc>(C), *this));
- break;
- case llvm::Value::GlobalVariableVal:
- It->second = std::unique_ptr<GlobalVariable>(
- new GlobalVariable(cast<llvm::GlobalVariable>(C), *this));
- break;
- case llvm::Value::GlobalAliasVal:
- It->second = std::unique_ptr<GlobalAlias>(
- new GlobalAlias(cast<llvm::GlobalAlias>(C), *this));
- break;
- case llvm::Value::NoCFIValueVal:
- It->second = std::unique_ptr<NoCFIValue>(
- new NoCFIValue(cast<llvm::NoCFIValue>(C), *this));
- break;
- case llvm::Value::ConstantPtrAuthVal:
- It->second = std::unique_ptr<ConstantPtrAuth>(
- new ConstantPtrAuth(cast<llvm::ConstantPtrAuth>(C), *this));
- break;
- case llvm::Value::ConstantExprVal:
- It->second = std::unique_ptr<ConstantExpr>(
- new ConstantExpr(cast<llvm::ConstantExpr>(C), *this));
- break;
- default:
- It->second = std::unique_ptr<Constant>(new Constant(C, *this));
- break;
- }
- auto *NewC = It->second.get();
- for (llvm::Value *COp : C->operands())
- getOrCreateValueInternal(COp, C);
- return NewC;
- }
- if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
- It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
- return It->second.get();
- }
- if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
- assert(isa<llvm::BlockAddress>(U) &&
- "This won't create a SBBB, don't call this function directly!");
- if (auto *SBBB = getValue(BB))
- return SBBB;
- return nullptr;
- }
- assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
-
- switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
- case llvm::Instruction::VAArg: {
- auto *LLVMVAArg = cast<llvm::VAArgInst>(LLVMV);
- It->second = std::unique_ptr<VAArgInst>(new VAArgInst(LLVMVAArg, *this));
- return It->second.get();
- }
- case llvm::Instruction::Freeze: {
- auto *LLVMFreeze = cast<llvm::FreezeInst>(LLVMV);
- It->second = std::unique_ptr<FreezeInst>(new FreezeInst(LLVMFreeze, *this));
- return It->second.get();
- }
- case llvm::Instruction::Fence: {
- auto *LLVMFence = cast<llvm::FenceInst>(LLVMV);
- It->second = std::unique_ptr<FenceInst>(new FenceInst(LLVMFence, *this));
- return It->second.get();
- }
- case llvm::Instruction::Select: {
- auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
- It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
- return It->second.get();
- }
- case llvm::Instruction::ExtractElement: {
- auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
- It->second = std::unique_ptr<ExtractElementInst>(
- new ExtractElementInst(LLVMIns, *this));
- return It->second.get();
- }
- case llvm::Instruction::InsertElement: {
- auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
- It->second = std::unique_ptr<InsertElementInst>(
- new InsertElementInst(LLVMIns, *this));
- return It->second.get();
- }
- case llvm::Instruction::ShuffleVector: {
- auto *LLVMIns = cast<llvm::ShuffleVectorInst>(LLVMV);
- It->second = std::unique_ptr<ShuffleVectorInst>(
- new ShuffleVectorInst(LLVMIns, *this));
- return It->second.get();
- }
- case llvm::Instruction::ExtractValue: {
- auto *LLVMIns = cast<llvm::ExtractValueInst>(LLVMV);
- It->second =
- std::unique_ptr<ExtractValueInst>(new ExtractValueInst(LLVMIns, *this));
- return It->second.get();
- }
- case llvm::Instruction::InsertValue: {
- auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
- It->second =
- std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this));
- return It->second.get();
- }
- case llvm::Instruction::Br: {
- auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
- It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
- return It->second.get();
- }
- case llvm::Instruction::Load: {
- auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
- It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
- return It->second.get();
- }
- case llvm::Instruction::Store: {
- auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
- It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
- return It->second.get();
- }
- case llvm::Instruction::Ret: {
- auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
- It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
- return It->second.get();
- }
- case llvm::Instruction::Call: {
- auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
- It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
- return It->second.get();
- }
- case llvm::Instruction::Invoke: {
- auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
- It->second = std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
- return It->second.get();
- }
- case llvm::Instruction::CallBr: {
- auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
- It->second = std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
- return It->second.get();
- }
- case llvm::Instruction::LandingPad: {
- auto *LLVMLPad = cast<llvm::LandingPadInst>(LLVMV);
- It->second =
- std::unique_ptr<LandingPadInst>(new LandingPadInst(LLVMLPad, *this));
- return It->second.get();
- }
- case llvm::Instruction::CatchPad: {
- auto *LLVMCPI = cast<llvm::CatchPadInst>(LLVMV);
- It->second =
- std::unique_ptr<CatchPadInst>(new CatchPadInst(LLVMCPI, *this));
- return It->second.get();
- }
- case llvm::Instruction::CleanupPad: {
- auto *LLVMCPI = cast<llvm::CleanupPadInst>(LLVMV);
- It->second =
- std::unique_ptr<CleanupPadInst>(new CleanupPadInst(LLVMCPI, *this));
- return It->second.get();
- }
- case llvm::Instruction::CatchRet: {
- auto *LLVMCRI = cast<llvm::CatchReturnInst>(LLVMV);
- It->second =
- std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
- return It->second.get();
- }
- case llvm::Instruction::CleanupRet: {
- auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV);
- It->second = std::unique_ptr<CleanupReturnInst>(
- new CleanupReturnInst(LLVMCRI, *this));
- return It->second.get();
- }
- case llvm::Instruction::GetElementPtr: {
- auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
- It->second = std::unique_ptr<GetElementPtrInst>(
- new GetElementPtrInst(LLVMGEP, *this));
- return It->second.get();
- }
- case llvm::Instruction::CatchSwitch: {
- auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV);
- It->second = std::unique_ptr<CatchSwitchInst>(
- new CatchSwitchInst(LLVMCatchSwitchInst, *this));
- return It->second.get();
- }
- case llvm::Instruction::Resume: {
- auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV);
- It->second =
- std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this));
- return It->second.get();
- }
- case llvm::Instruction::Switch: {
- auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
- It->second =
- std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this));
- return It->second.get();
- }
- case llvm::Instruction::FNeg: {
- auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
- It->second = std::unique_ptr<UnaryOperator>(
- new UnaryOperator(LLVMUnaryOperator, *this));
- return It->second.get();
- }
- case llvm::Instruction::Add:
- case llvm::Instruction::FAdd:
- case llvm::Instruction::Sub:
- case llvm::Instruction::FSub:
- case llvm::Instruction::Mul:
- case llvm::Instruction::FMul:
- case llvm::Instruction::UDiv:
- case llvm::Instruction::SDiv:
- case llvm::Instruction::FDiv:
- case llvm::Instruction::URem:
- case llvm::Instruction::SRem:
- case llvm::Instruction::FRem:
- case llvm::Instruction::Shl:
- case llvm::Instruction::LShr:
- case llvm::Instruction::AShr:
- case llvm::Instruction::And:
- case llvm::Instruction::Or:
- case llvm::Instruction::Xor: {
- auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
- It->second = std::unique_ptr<BinaryOperator>(
- new BinaryOperator(LLVMBinaryOperator, *this));
- return It->second.get();
- }
- case llvm::Instruction::AtomicRMW: {
- auto *LLVMAtomicRMW = cast<llvm::AtomicRMWInst>(LLVMV);
- It->second =
- std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(LLVMAtomicRMW, *this));
- return It->second.get();
- }
- case llvm::Instruction::AtomicCmpXchg: {
- auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
- It->second = std::unique_ptr<AtomicCmpXchgInst>(
- new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this));
- return It->second.get();
- }
- case llvm::Instruction::Alloca: {
- auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
- It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
- return It->second.get();
- }
- case llvm::Instruction::ZExt:
- case llvm::Instruction::SExt:
- case llvm::Instruction::FPToUI:
- case llvm::Instruction::FPToSI:
- case llvm::Instruction::FPExt:
- case llvm::Instruction::PtrToInt:
- case llvm::Instruction::IntToPtr:
- case llvm::Instruction::SIToFP:
- case llvm::Instruction::UIToFP:
- case llvm::Instruction::Trunc:
- case llvm::Instruction::FPTrunc:
- case llvm::Instruction::BitCast:
- case llvm::Instruction::AddrSpaceCast: {
- auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
- It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
- return It->second.get();
- }
- case llvm::Instruction::PHI: {
- auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
- It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
- return It->second.get();
- }
- case llvm::Instruction::ICmp: {
- auto *LLVMICmp = cast<llvm::ICmpInst>(LLVMV);
- It->second = std::unique_ptr<ICmpInst>(new ICmpInst(LLVMICmp, *this));
- return It->second.get();
- }
- case llvm::Instruction::FCmp: {
- auto *LLVMFCmp = cast<llvm::FCmpInst>(LLVMV);
- It->second = std::unique_ptr<FCmpInst>(new FCmpInst(LLVMFCmp, *this));
- return It->second.get();
- }
- case llvm::Instruction::Unreachable: {
- auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
- It->second = std::unique_ptr<UnreachableInst>(
- new UnreachableInst(LLVMUnreachable, *this));
- return It->second.get();
- }
- default:
- break;
- }
-
- It->second = std::unique_ptr<OpaqueInst>(
- new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
- return It->second.get();
-}
-
-BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
- assert(getValue(LLVMBB) == nullptr && "Already exists!");
- auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
- auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
- // Create SandboxIR for BB's body.
- BB->buildBasicBlockFromLLVMIR(LLVMBB);
- return BB;
-}
-
-VAArgInst *Context::createVAArgInst(llvm::VAArgInst *SI) {
- auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this));
- return cast<VAArgInst>(registerValue(std::move(NewPtr)));
-}
-
-FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) {
- auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this));
- return cast<FreezeInst>(registerValue(std::move(NewPtr)));
-}
-
-FenceInst *Context::createFenceInst(llvm::FenceInst *SI) {
- auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this));
- return cast<FenceInst>(registerValue(std::move(NewPtr)));
-}
-
-SelectInst *Context::createSelectInst(llvm::SelectInst *SI) {
- auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
- return cast<SelectInst>(registerValue(std::move(NewPtr)));
-}
-
-ExtractElementInst *
-Context::createExtractElementInst(llvm::ExtractElementInst *EEI) {
- auto NewPtr =
- std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
- return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
-}
-
-InsertElementInst *
-Context::createInsertElementInst(llvm::InsertElementInst *IEI) {
- auto NewPtr =
- std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
- return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
-}
-
-ShuffleVectorInst *
-Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) {
- auto NewPtr =
- std::unique_ptr<ShuffleVectorInst>(new ShuffleVectorInst(SVI, *this));
- return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
-}
-
-ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) {
- auto NewPtr =
- std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this));
- return cast<ExtractValueInst>(registerValue(std::move(NewPtr)));
-}
-
-InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
- auto NewPtr =
- std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
- return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
-}
-
-BranchInst *Context::createBranchInst(llvm::BranchInst *BI) {
- auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
- return cast<BranchInst>(registerValue(std::move(NewPtr)));
-}
-
-LoadInst *Context::createLoadInst(llvm::LoadInst *LI) {
- auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
- return cast<LoadInst>(registerValue(std::move(NewPtr)));
-}
-
-StoreInst *Context::createStoreInst(llvm::StoreInst *SI) {
- auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
- return cast<StoreInst>(registerValue(std::move(NewPtr)));
-}
-
-ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) {
- auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
- return cast<ReturnInst>(registerValue(std::move(NewPtr)));
-}
-
-CallInst *Context::createCallInst(llvm::CallInst *I) {
- auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
- return cast<CallInst>(registerValue(std::move(NewPtr)));
-}
-
-InvokeInst *Context::createInvokeInst(llvm::InvokeInst *I) {
- auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
- return cast<InvokeInst>(registerValue(std::move(NewPtr)));
-}
-
-CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) {
- auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
- return cast<CallBrInst>(registerValue(std::move(NewPtr)));
-}
-
-UnreachableInst *Context::createUnreachableInst(llvm::UnreachableInst *UI) {
- auto NewPtr =
- std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
- return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
-}
-LandingPadInst *Context::createLandingPadInst(llvm::LandingPadInst *I) {
- auto NewPtr = std::unique_ptr<LandingPadInst>(new LandingPadInst(I, *this));
- return cast<LandingPadInst>(registerValue(std::move(NewPtr)));
-}
-CatchPadInst *Context::createCatchPadInst(llvm::CatchPadInst *I) {
- auto NewPtr = std::unique_ptr<CatchPadInst>(new CatchPadInst(I, *this));
- return cast<CatchPadInst>(registerValue(std::move(NewPtr)));
-}
-CleanupPadInst *Context::createCleanupPadInst(llvm::CleanupPadInst *I) {
- auto NewPtr = std::unique_ptr<CleanupPadInst>(new CleanupPadInst(I, *this));
- return cast<CleanupPadInst>(registerValue(std::move(NewPtr)));
-}
-CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) {
- auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
- return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
-}
-CleanupReturnInst *
-Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) {
- auto NewPtr =
- std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this));
- return cast<CleanupReturnInst>(registerValue(std::move(NewPtr)));
-}
-GetElementPtrInst *
-Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
- auto NewPtr =
- std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
- return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
-}
-CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) {
- auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
- return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
-}
-ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) {
- auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this));
- return cast<ResumeInst>(registerValue(std::move(NewPtr)));
-}
-SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) {
- auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
- return cast<SwitchInst>(registerValue(std::move(NewPtr)));
-}
-UnaryOperator *Context::createUnaryOperator(llvm::UnaryOperator *I) {
- auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this));
- return cast<UnaryOperator>(registerValue(std::move(NewPtr)));
-}
-BinaryOperator *Context::createBinaryOperator(llvm::BinaryOperator *I) {
- auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this));
- return cast<BinaryOperator>(registerValue(std::move(NewPtr)));
-}
-AtomicRMWInst *Context::createAtomicRMWInst(llvm::AtomicRMWInst *I) {
- auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this));
- return cast<AtomicRMWInst>(registerValue(std::move(NewPtr)));
-}
-AtomicCmpXchgInst *
-Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) {
- auto NewPtr =
- std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
- return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
-}
-AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) {
- auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
- return cast<AllocaInst>(registerValue(std::move(NewPtr)));
-}
-CastInst *Context::createCastInst(llvm::CastInst *I) {
- auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
- return cast<CastInst>(registerValue(std::move(NewPtr)));
-}
-PHINode *Context::createPHINode(llvm::PHINode *I) {
- auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
- return cast<PHINode>(registerValue(std::move(NewPtr)));
-}
-ICmpInst *Context::createICmpInst(llvm::ICmpInst *I) {
- auto NewPtr = std::unique_ptr<ICmpInst>(new ICmpInst(I, *this));
- return cast<ICmpInst>(registerValue(std::move(NewPtr)));
-}
-FCmpInst *Context::createFCmpInst(llvm::FCmpInst *I) {
- auto NewPtr = std::unique_ptr<FCmpInst>(new FCmpInst(I, *this));
- return cast<FCmpInst>(registerValue(std::move(NewPtr)));
-}
-CmpInst *CmpInst::create(Predicate P, Value *S1, Value *S2,
- Instruction *InsertBefore, Context &Ctx,
- const Twine &Name) {
- auto &Builder = Ctx.getLLVMIRBuilder();
- Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
- auto *LLVMI = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
- if (dyn_cast<llvm::ICmpInst>(LLVMI))
- return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMI));
- return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMI));
-}
-CmpInst *CmpInst::createWithCopiedFlags(Predicate P, Value *S1, Value *S2,
- const Instruction *F,
- Instruction *InsertBefore, Context &Ctx,
- const Twine &Name) {
- CmpInst *Inst = create(P, S1, S2, InsertBefore, Ctx, Name);
- cast<llvm::CmpInst>(Inst->Val)->copyIRFlags(F->Val);
- return Inst;
-}
-
-Type *CmpInst::makeCmpResultType(Type *OpndType) {
- if (auto *VT = dyn_cast<VectorType>(OpndType)) {
- // TODO: Cleanup when we have more complete support for
- // sandboxir::VectorType
- return OpndType->getContext().getType(llvm::VectorType::get(
- llvm::Type::getInt1Ty(OpndType->getContext().LLVMCtx),
- cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
- }
- return Type::getInt1Ty(OpndType->getContext());
-}
-
-void CmpInst::setPredicate(Predicate P) {
- Ctx.getTracker()
- .emplaceIfTracking<
- GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this);
- cast<llvm::CmpInst>(Val)->setPredicate(P);
-}
-
-void CmpInst::swapOperands() {
- if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
- IC->swapOperands();
- else
- cast<FCmpInst>(this)->swapOperands();
-}
-
-void ICmpInst::swapOperands() {
- Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
- cast<llvm::ICmpInst>(Val)->swapOperands();
-}
-
-void FCmpInst::swapOperands() {
- Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
- cast<llvm::FCmpInst>(Val)->swapOperands();
-}
-
-#ifndef NDEBUG
-void CmpInst::dumpOS(raw_ostream &OS) const {
- dumpCommonPrefix(OS);
- dumpCommonSuffix(OS);
-}
-
-void CmpInst::dump() const {
- dumpOS(dbgs());
- dbgs() << "\n";
-}
-#endif // NDEBUG
-
-Value *Context::getValue(llvm::Value *V) const {
- auto It = LLVMValueToValueMap.find(V);
- if (It != LLVMValueToValueMap.end())
- return It->second.get();
- return nullptr;
-}
-
-Module *Context::getModule(llvm::Module *LLVMM) const {
- auto It = LLVMModuleToModuleMap.find(LLVMM);
- if (It != LLVMModuleToModuleMap.end())
- return It->second.get();
- return nullptr;
-}
-
-Module *Context::getOrCreateModule(llvm::Module *LLVMM) {
- auto Pair = LLVMModuleToModuleMap.insert({LLVMM, nullptr});
- auto It = Pair.first;
- if (!Pair.second)
- return It->second.get();
- It->second = std::unique_ptr<Module>(new Module(*LLVMM, *this));
- return It->second.get();
-}
-
-Function *Context::createFunction(llvm::Function *F) {
- assert(getValue(F) == nullptr && "Already exists!");
- // Create the module if needed before we create the new sandboxir::Function.
- // Note: this won't fully populate the module. The only globals that will be
- // available will be the ones being used within the function.
- getOrCreateModule(F->getParent());
-
- auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
- auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
- // Create arguments.
- for (auto &Arg : F->args())
- getOrCreateArgument(&Arg);
- // Create BBs.
- for (auto &BB : *F)
- createBasicBlock(&BB);
- return SBF;
-}
-
-Module *Context::createModule(llvm::Module *LLVMM) {
- auto *M = getOrCreateModule(LLVMM);
- // Create the functions.
- for (auto &LLVMF : *LLVMM)
- createFunction(&LLVMF);
- // Create globals.
- for (auto &Global : LLVMM->globals())
- getOrCreateValue(&Global);
- // Create aliases.
- for (auto &Alias : LLVMM->aliases())
- getOrCreateValue(&Alias);
- // Create ifuncs.
- for (auto &IFunc : LLVMM->ifuncs())
- getOrCreateValue(&IFunc);
-
- return M;
-}
-
Function *BasicBlock::getParent() const {
auto *BB = cast<llvm::BasicBlock>(Val);
auto *F = BB->getParent();
More information about the llvm-commits
mailing list