diff --git a/llvm/include/llvm/SandboxIR/Context.h b/llvm/include/llvm/SandboxIR/Context.h new file mode 100644 index 0000000000000..dfba3085c66ac --- /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> LLVMValueToValueMap; + + /// Maps an LLVM Module to the corresponding sandboxir::Module. + DenseMap> 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> LLVMTypeToTypeMap; + + /// Remove \p V from the maps and returns the unique_ptr. + std::unique_ptr 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 detach(Value *V); + friend class Instruction; // For detach(). + /// Take ownership of VPtr and store it in `LLVMValueToValueMap`. + Value *registerValue(std::unique_ptr &&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(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 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(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(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 ae54042c6df29..cc8c2094d0682 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" @@ -4542,199 +4543,6 @@ class OpaqueInst : public SingleLLVMInstructionImpl { } }; -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> - LLVMValueToValueMap; - - /// Maps an LLVM Module to the corresponding sandboxir::Module. - DenseMap> 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> LLVMTypeToTypeMap; - - /// Remove \p V from the maps and returns the unique_ptr. - std::unique_ptr 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 detach(Value *V); - friend void Instruction::eraseFromParent(); // For detach(). - /// Take ownership of VPtr and store it in `LLVMValueToValueMap`. - Value *registerValue(std::unique_ptr &&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(new Argument(LLVMArg, *this)); - return cast(It->second.get()); - } - return cast(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(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 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(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(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 { /// Helper for mapped_iterator. diff --git a/llvm/lib/SandboxIR/CMakeLists.txt b/llvm/lib/SandboxIR/CMakeLists.txt index 7a3b7f65dddc8..1bbbb8c1ac9e8 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 0000000000000..1dc239ba48288 --- /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 Context::detachLLVMValue(llvm::Value *V) { + std::unique_ptr Erased; + auto It = LLVMValueToValueMap.find(V); + if (It != LLVMValueToValueMap.end()) { + auto *Val = It->second.release(); + Erased = std::unique_ptr(Val); + LLVMValueToValueMap.erase(It); + } + return Erased; +} + +std::unique_ptr 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 &&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(VPtr.get())) + getTracker().emplaceIfTracking(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(LLVMV)) { + switch (C->getValueID()) { + case llvm::Value::ConstantIntVal: + It->second = std::unique_ptr( + new ConstantInt(cast(C), *this)); + return It->second.get(); + case llvm::Value::ConstantFPVal: + It->second = std::unique_ptr( + new ConstantFP(cast(C), *this)); + return It->second.get(); + case llvm::Value::BlockAddressVal: + It->second = std::unique_ptr( + new BlockAddress(cast(C), *this)); + return It->second.get(); + case llvm::Value::ConstantTokenNoneVal: + It->second = std::unique_ptr( + new ConstantTokenNone(cast(C), *this)); + return It->second.get(); + case llvm::Value::ConstantAggregateZeroVal: { + auto *CAZ = cast(C); + It->second = std::unique_ptr( + 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(0, EC.getFixedValue())) + getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ); + } + return Ret; + } + case llvm::Value::ConstantPointerNullVal: + It->second = std::unique_ptr( + new ConstantPointerNull(cast(C), *this)); + return It->second.get(); + case llvm::Value::PoisonValueVal: + It->second = std::unique_ptr( + new PoisonValue(cast(C), *this)); + return It->second.get(); + case llvm::Value::UndefValueVal: + It->second = std::unique_ptr( + new UndefValue(cast(C), *this)); + return It->second.get(); + case llvm::Value::DSOLocalEquivalentVal: { + auto *DSOLE = cast(C); + It->second = std::unique_ptr( + new DSOLocalEquivalent(DSOLE, *this)); + auto *Ret = It->second.get(); + getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE); + return Ret; + } + case llvm::Value::ConstantArrayVal: + It->second = std::unique_ptr( + new ConstantArray(cast(C), *this)); + break; + case llvm::Value::ConstantStructVal: + It->second = std::unique_ptr( + new ConstantStruct(cast(C), *this)); + break; + case llvm::Value::ConstantVectorVal: + It->second = std::unique_ptr( + new ConstantVector(cast(C), *this)); + break; + case llvm::Value::FunctionVal: + It->second = std::unique_ptr( + new Function(cast(C), *this)); + break; + case llvm::Value::GlobalIFuncVal: + It->second = std::unique_ptr( + new GlobalIFunc(cast(C), *this)); + break; + case llvm::Value::GlobalVariableVal: + It->second = std::unique_ptr( + new GlobalVariable(cast(C), *this)); + break; + case llvm::Value::GlobalAliasVal: + It->second = std::unique_ptr( + new GlobalAlias(cast(C), *this)); + break; + case llvm::Value::NoCFIValueVal: + It->second = std::unique_ptr( + new NoCFIValue(cast(C), *this)); + break; + case llvm::Value::ConstantPtrAuthVal: + It->second = std::unique_ptr( + new ConstantPtrAuth(cast(C), *this)); + break; + case llvm::Value::ConstantExprVal: + It->second = std::unique_ptr( + new ConstantExpr(cast(C), *this)); + break; + default: + It->second = std::unique_ptr(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(LLVMV)) { + It->second = std::unique_ptr(new Argument(Arg, *this)); + return It->second.get(); + } + if (auto *BB = dyn_cast(LLVMV)) { + assert(isa(U) && + "This won't create a SBBB, don't call this function directly!"); + if (auto *SBBB = getValue(BB)) + return SBBB; + return nullptr; + } + assert(isa(LLVMV) && "Expected Instruction"); + + switch (cast(LLVMV)->getOpcode()) { + case llvm::Instruction::VAArg: { + auto *LLVMVAArg = cast(LLVMV); + It->second = std::unique_ptr(new VAArgInst(LLVMVAArg, *this)); + return It->second.get(); + } + case llvm::Instruction::Freeze: { + auto *LLVMFreeze = cast(LLVMV); + It->second = std::unique_ptr(new FreezeInst(LLVMFreeze, *this)); + return It->second.get(); + } + case llvm::Instruction::Fence: { + auto *LLVMFence = cast(LLVMV); + It->second = std::unique_ptr(new FenceInst(LLVMFence, *this)); + return It->second.get(); + } + case llvm::Instruction::Select: { + auto *LLVMSel = cast(LLVMV); + It->second = std::unique_ptr(new SelectInst(LLVMSel, *this)); + return It->second.get(); + } + case llvm::Instruction::ExtractElement: { + auto *LLVMIns = cast(LLVMV); + It->second = std::unique_ptr( + new ExtractElementInst(LLVMIns, *this)); + return It->second.get(); + } + case llvm::Instruction::InsertElement: { + auto *LLVMIns = cast(LLVMV); + It->second = std::unique_ptr( + new InsertElementInst(LLVMIns, *this)); + return It->second.get(); + } + case llvm::Instruction::ShuffleVector: { + auto *LLVMIns = cast(LLVMV); + It->second = std::unique_ptr( + new ShuffleVectorInst(LLVMIns, *this)); + return It->second.get(); + } + case llvm::Instruction::ExtractValue: { + auto *LLVMIns = cast(LLVMV); + It->second = + std::unique_ptr(new ExtractValueInst(LLVMIns, *this)); + return It->second.get(); + } + case llvm::Instruction::InsertValue: { + auto *LLVMIns = cast(LLVMV); + It->second = + std::unique_ptr(new InsertValueInst(LLVMIns, *this)); + return It->second.get(); + } + case llvm::Instruction::Br: { + auto *LLVMBr = cast(LLVMV); + It->second = std::unique_ptr(new BranchInst(LLVMBr, *this)); + return It->second.get(); + } + case llvm::Instruction::Load: { + auto *LLVMLd = cast(LLVMV); + It->second = std::unique_ptr(new LoadInst(LLVMLd, *this)); + return It->second.get(); + } + case llvm::Instruction::Store: { + auto *LLVMSt = cast(LLVMV); + It->second = std::unique_ptr(new StoreInst(LLVMSt, *this)); + return It->second.get(); + } + case llvm::Instruction::Ret: { + auto *LLVMRet = cast(LLVMV); + It->second = std::unique_ptr(new ReturnInst(LLVMRet, *this)); + return It->second.get(); + } + case llvm::Instruction::Call: { + auto *LLVMCall = cast(LLVMV); + It->second = std::unique_ptr(new CallInst(LLVMCall, *this)); + return It->second.get(); + } + case llvm::Instruction::Invoke: { + auto *LLVMInvoke = cast(LLVMV); + It->second = std::unique_ptr(new InvokeInst(LLVMInvoke, *this)); + return It->second.get(); + } + case llvm::Instruction::CallBr: { + auto *LLVMCallBr = cast(LLVMV); + It->second = std::unique_ptr(new CallBrInst(LLVMCallBr, *this)); + return It->second.get(); + } + case llvm::Instruction::LandingPad: { + auto *LLVMLPad = cast(LLVMV); + It->second = + std::unique_ptr(new LandingPadInst(LLVMLPad, *this)); + return It->second.get(); + } + case llvm::Instruction::CatchPad: { + auto *LLVMCPI = cast(LLVMV); + It->second = + std::unique_ptr(new CatchPadInst(LLVMCPI, *this)); + return It->second.get(); + } + case llvm::Instruction::CleanupPad: { + auto *LLVMCPI = cast(LLVMV); + It->second = + std::unique_ptr(new CleanupPadInst(LLVMCPI, *this)); + return It->second.get(); + } + case llvm::Instruction::CatchRet: { + auto *LLVMCRI = cast(LLVMV); + It->second = + std::unique_ptr(new CatchReturnInst(LLVMCRI, *this)); + return It->second.get(); + } + case llvm::Instruction::CleanupRet: { + auto *LLVMCRI = cast(LLVMV); + It->second = std::unique_ptr( + new CleanupReturnInst(LLVMCRI, *this)); + return It->second.get(); + } + case llvm::Instruction::GetElementPtr: { + auto *LLVMGEP = cast(LLVMV); + It->second = std::unique_ptr( + new GetElementPtrInst(LLVMGEP, *this)); + return It->second.get(); + } + case llvm::Instruction::CatchSwitch: { + auto *LLVMCatchSwitchInst = cast(LLVMV); + It->second = std::unique_ptr( + new CatchSwitchInst(LLVMCatchSwitchInst, *this)); + return It->second.get(); + } + case llvm::Instruction::Resume: { + auto *LLVMResumeInst = cast(LLVMV); + It->second = + std::unique_ptr(new ResumeInst(LLVMResumeInst, *this)); + return It->second.get(); + } + case llvm::Instruction::Switch: { + auto *LLVMSwitchInst = cast(LLVMV); + It->second = + std::unique_ptr(new SwitchInst(LLVMSwitchInst, *this)); + return It->second.get(); + } + case llvm::Instruction::FNeg: { + auto *LLVMUnaryOperator = cast(LLVMV); + It->second = std::unique_ptr( + 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(LLVMV); + It->second = std::unique_ptr( + new BinaryOperator(LLVMBinaryOperator, *this)); + return It->second.get(); + } + case llvm::Instruction::AtomicRMW: { + auto *LLVMAtomicRMW = cast(LLVMV); + It->second = + std::unique_ptr(new AtomicRMWInst(LLVMAtomicRMW, *this)); + return It->second.get(); + } + case llvm::Instruction::AtomicCmpXchg: { + auto *LLVMAtomicCmpXchg = cast(LLVMV); + It->second = std::unique_ptr( + new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this)); + return It->second.get(); + } + case llvm::Instruction::Alloca: { + auto *LLVMAlloca = cast(LLVMV); + It->second = std::unique_ptr(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(LLVMV); + It->second = std::unique_ptr(new CastInst(LLVMCast, *this)); + return It->second.get(); + } + case llvm::Instruction::PHI: { + auto *LLVMPhi = cast(LLVMV); + It->second = std::unique_ptr(new PHINode(LLVMPhi, *this)); + return It->second.get(); + } + case llvm::Instruction::ICmp: { + auto *LLVMICmp = cast(LLVMV); + It->second = std::unique_ptr(new ICmpInst(LLVMICmp, *this)); + return It->second.get(); + } + case llvm::Instruction::FCmp: { + auto *LLVMFCmp = cast(LLVMV); + It->second = std::unique_ptr(new FCmpInst(LLVMFCmp, *this)); + return It->second.get(); + } + case llvm::Instruction::Unreachable: { + auto *LLVMUnreachable = cast(LLVMV); + It->second = std::unique_ptr( + new UnreachableInst(LLVMUnreachable, *this)); + return It->second.get(); + } + default: + break; + } + + It->second = std::unique_ptr( + new OpaqueInst(cast(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(new Argument(LLVMArg, *this)); + return cast(It->second.get()); + } + return cast(It->second.get()); +} + +BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) { + assert(getValue(LLVMBB) == nullptr && "Already exists!"); + auto NewBBPtr = std::unique_ptr(new BasicBlock(LLVMBB, *this)); + auto *BB = cast(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(new VAArgInst(SI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) { + auto NewPtr = std::unique_ptr(new FreezeInst(SI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +FenceInst *Context::createFenceInst(llvm::FenceInst *SI) { + auto NewPtr = std::unique_ptr(new FenceInst(SI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +SelectInst *Context::createSelectInst(llvm::SelectInst *SI) { + auto NewPtr = std::unique_ptr(new SelectInst(SI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +ExtractElementInst * +Context::createExtractElementInst(llvm::ExtractElementInst *EEI) { + auto NewPtr = + std::unique_ptr(new ExtractElementInst(EEI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +InsertElementInst * +Context::createInsertElementInst(llvm::InsertElementInst *IEI) { + auto NewPtr = + std::unique_ptr(new InsertElementInst(IEI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +ShuffleVectorInst * +Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) { + auto NewPtr = + std::unique_ptr(new ShuffleVectorInst(SVI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) { + auto NewPtr = + std::unique_ptr(new ExtractValueInst(EVI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) { + auto NewPtr = + std::unique_ptr(new InsertValueInst(IVI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +BranchInst *Context::createBranchInst(llvm::BranchInst *BI) { + auto NewPtr = std::unique_ptr(new BranchInst(BI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +LoadInst *Context::createLoadInst(llvm::LoadInst *LI) { + auto NewPtr = std::unique_ptr(new LoadInst(LI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +StoreInst *Context::createStoreInst(llvm::StoreInst *SI) { + auto NewPtr = std::unique_ptr(new StoreInst(SI, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) { + auto NewPtr = std::unique_ptr(new ReturnInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +CallInst *Context::createCallInst(llvm::CallInst *I) { + auto NewPtr = std::unique_ptr(new CallInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +InvokeInst *Context::createInvokeInst(llvm::InvokeInst *I) { + auto NewPtr = std::unique_ptr(new InvokeInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) { + auto NewPtr = std::unique_ptr(new CallBrInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} + +UnreachableInst *Context::createUnreachableInst(llvm::UnreachableInst *UI) { + auto NewPtr = + std::unique_ptr(new UnreachableInst(UI, *this)); + return cast(registerValue(std::move(NewPtr))); +} +LandingPadInst *Context::createLandingPadInst(llvm::LandingPadInst *I) { + auto NewPtr = std::unique_ptr(new LandingPadInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +CatchPadInst *Context::createCatchPadInst(llvm::CatchPadInst *I) { + auto NewPtr = std::unique_ptr(new CatchPadInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +CleanupPadInst *Context::createCleanupPadInst(llvm::CleanupPadInst *I) { + auto NewPtr = std::unique_ptr(new CleanupPadInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) { + auto NewPtr = std::unique_ptr(new CatchReturnInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +CleanupReturnInst * +Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) { + auto NewPtr = + std::unique_ptr(new CleanupReturnInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +GetElementPtrInst * +Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) { + auto NewPtr = + std::unique_ptr(new GetElementPtrInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) { + auto NewPtr = std::unique_ptr(new CatchSwitchInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) { + auto NewPtr = std::unique_ptr(new ResumeInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) { + auto NewPtr = std::unique_ptr(new SwitchInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +UnaryOperator *Context::createUnaryOperator(llvm::UnaryOperator *I) { + auto NewPtr = std::unique_ptr(new UnaryOperator(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +BinaryOperator *Context::createBinaryOperator(llvm::BinaryOperator *I) { + auto NewPtr = std::unique_ptr(new BinaryOperator(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +AtomicRMWInst *Context::createAtomicRMWInst(llvm::AtomicRMWInst *I) { + auto NewPtr = std::unique_ptr(new AtomicRMWInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +AtomicCmpXchgInst * +Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) { + auto NewPtr = + std::unique_ptr(new AtomicCmpXchgInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) { + auto NewPtr = std::unique_ptr(new AllocaInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +CastInst *Context::createCastInst(llvm::CastInst *I) { + auto NewPtr = std::unique_ptr(new CastInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +PHINode *Context::createPHINode(llvm::PHINode *I) { + auto NewPtr = std::unique_ptr(new PHINode(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +ICmpInst *Context::createICmpInst(llvm::ICmpInst *I) { + auto NewPtr = std::unique_ptr(new ICmpInst(I, *this)); + return cast(registerValue(std::move(NewPtr))); +} +FCmpInst *Context::createFCmpInst(llvm::FCmpInst *I) { + auto NewPtr = std::unique_ptr(new FCmpInst(I, *this)); + return cast(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(LLVMI)) + return Ctx.createICmpInst(cast(LLVMI)); + return Ctx.createFCmpInst(cast(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(Inst->Val)->copyIRFlags(F->Val); + return Inst; +} + +Type *CmpInst::makeCmpResultType(Type *OpndType) { + if (auto *VT = dyn_cast(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(VT->LLVMTy)->getElementCount())); + } + return Type::getInt1Ty(OpndType->getContext()); +} + +void CmpInst::setPredicate(Predicate P) { + Ctx.getTracker() + .emplaceIfTracking< + GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this); + cast(Val)->setPredicate(P); +} + +void CmpInst::swapOperands() { + if (ICmpInst *IC = dyn_cast(this)) + IC->swapOperands(); + else + cast(this)->swapOperands(); +} + +void ICmpInst::swapOperands() { + Ctx.getTracker().emplaceIfTracking(this); + cast(Val)->swapOperands(); +} + +void FCmpInst::swapOperands() { + Ctx.getTracker().emplaceIfTracking(this); + cast(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(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(new Function(F, *this)); + auto *SBF = cast(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 60026d7dcea63..5f005bd1f5d08 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(Ctx->getValue(&*It)); } -std::unique_ptr Context::detachLLVMValue(llvm::Value *V) { - std::unique_ptr Erased; - auto It = LLVMValueToValueMap.find(V); - if (It != LLVMValueToValueMap.end()) { - auto *Val = It->second.release(); - Erased = std::unique_ptr(Val); - LLVMValueToValueMap.erase(It); - } - return Erased; -} - -std::unique_ptr 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 &&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(VPtr.get())) - getTracker().emplaceIfTracking(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(LLVMV)) { - switch (C->getValueID()) { - case llvm::Value::ConstantIntVal: - It->second = std::unique_ptr( - new ConstantInt(cast(C), *this)); - return It->second.get(); - case llvm::Value::ConstantFPVal: - It->second = std::unique_ptr( - new ConstantFP(cast(C), *this)); - return It->second.get(); - case llvm::Value::BlockAddressVal: - It->second = std::unique_ptr( - new BlockAddress(cast(C), *this)); - return It->second.get(); - case llvm::Value::ConstantTokenNoneVal: - It->second = std::unique_ptr( - new ConstantTokenNone(cast(C), *this)); - return It->second.get(); - case llvm::Value::ConstantAggregateZeroVal: { - auto *CAZ = cast(C); - It->second = std::unique_ptr( - 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(0, EC.getFixedValue())) - getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ); - } - return Ret; - } - case llvm::Value::ConstantPointerNullVal: - It->second = std::unique_ptr( - new ConstantPointerNull(cast(C), *this)); - return It->second.get(); - case llvm::Value::PoisonValueVal: - It->second = std::unique_ptr( - new PoisonValue(cast(C), *this)); - return It->second.get(); - case llvm::Value::UndefValueVal: - It->second = std::unique_ptr( - new UndefValue(cast(C), *this)); - return It->second.get(); - case llvm::Value::DSOLocalEquivalentVal: { - auto *DSOLE = cast(C); - It->second = std::unique_ptr( - new DSOLocalEquivalent(DSOLE, *this)); - auto *Ret = It->second.get(); - getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE); - return Ret; - } - case llvm::Value::ConstantArrayVal: - It->second = std::unique_ptr( - new ConstantArray(cast(C), *this)); - break; - case llvm::Value::ConstantStructVal: - It->second = std::unique_ptr( - new ConstantStruct(cast(C), *this)); - break; - case llvm::Value::ConstantVectorVal: - It->second = std::unique_ptr( - new ConstantVector(cast(C), *this)); - break; - case llvm::Value::FunctionVal: - It->second = std::unique_ptr( - new Function(cast(C), *this)); - break; - case llvm::Value::GlobalIFuncVal: - It->second = std::unique_ptr( - new GlobalIFunc(cast(C), *this)); - break; - case llvm::Value::GlobalVariableVal: - It->second = std::unique_ptr( - new GlobalVariable(cast(C), *this)); - break; - case llvm::Value::GlobalAliasVal: - It->second = std::unique_ptr( - new GlobalAlias(cast(C), *this)); - break; - case llvm::Value::NoCFIValueVal: - It->second = std::unique_ptr( - new NoCFIValue(cast(C), *this)); - break; - case llvm::Value::ConstantPtrAuthVal: - It->second = std::unique_ptr( - new ConstantPtrAuth(cast(C), *this)); - break; - case llvm::Value::ConstantExprVal: - It->second = std::unique_ptr( - new ConstantExpr(cast(C), *this)); - break; - default: - It->second = std::unique_ptr(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(LLVMV)) { - It->second = std::unique_ptr(new Argument(Arg, *this)); - return It->second.get(); - } - if (auto *BB = dyn_cast(LLVMV)) { - assert(isa(U) && - "This won't create a SBBB, don't call this function directly!"); - if (auto *SBBB = getValue(BB)) - return SBBB; - return nullptr; - } - assert(isa(LLVMV) && "Expected Instruction"); - - switch (cast(LLVMV)->getOpcode()) { - case llvm::Instruction::VAArg: { - auto *LLVMVAArg = cast(LLVMV); - It->second = std::unique_ptr(new VAArgInst(LLVMVAArg, *this)); - return It->second.get(); - } - case llvm::Instruction::Freeze: { - auto *LLVMFreeze = cast(LLVMV); - It->second = std::unique_ptr(new FreezeInst(LLVMFreeze, *this)); - return It->second.get(); - } - case llvm::Instruction::Fence: { - auto *LLVMFence = cast(LLVMV); - It->second = std::unique_ptr(new FenceInst(LLVMFence, *this)); - return It->second.get(); - } - case llvm::Instruction::Select: { - auto *LLVMSel = cast(LLVMV); - It->second = std::unique_ptr(new SelectInst(LLVMSel, *this)); - return It->second.get(); - } - case llvm::Instruction::ExtractElement: { - auto *LLVMIns = cast(LLVMV); - It->second = std::unique_ptr( - new ExtractElementInst(LLVMIns, *this)); - return It->second.get(); - } - case llvm::Instruction::InsertElement: { - auto *LLVMIns = cast(LLVMV); - It->second = std::unique_ptr( - new InsertElementInst(LLVMIns, *this)); - return It->second.get(); - } - case llvm::Instruction::ShuffleVector: { - auto *LLVMIns = cast(LLVMV); - It->second = std::unique_ptr( - new ShuffleVectorInst(LLVMIns, *this)); - return It->second.get(); - } - case llvm::Instruction::ExtractValue: { - auto *LLVMIns = cast(LLVMV); - It->second = - std::unique_ptr(new ExtractValueInst(LLVMIns, *this)); - return It->second.get(); - } - case llvm::Instruction::InsertValue: { - auto *LLVMIns = cast(LLVMV); - It->second = - std::unique_ptr(new InsertValueInst(LLVMIns, *this)); - return It->second.get(); - } - case llvm::Instruction::Br: { - auto *LLVMBr = cast(LLVMV); - It->second = std::unique_ptr(new BranchInst(LLVMBr, *this)); - return It->second.get(); - } - case llvm::Instruction::Load: { - auto *LLVMLd = cast(LLVMV); - It->second = std::unique_ptr(new LoadInst(LLVMLd, *this)); - return It->second.get(); - } - case llvm::Instruction::Store: { - auto *LLVMSt = cast(LLVMV); - It->second = std::unique_ptr(new StoreInst(LLVMSt, *this)); - return It->second.get(); - } - case llvm::Instruction::Ret: { - auto *LLVMRet = cast(LLVMV); - It->second = std::unique_ptr(new ReturnInst(LLVMRet, *this)); - return It->second.get(); - } - case llvm::Instruction::Call: { - auto *LLVMCall = cast(LLVMV); - It->second = std::unique_ptr(new CallInst(LLVMCall, *this)); - return It->second.get(); - } - case llvm::Instruction::Invoke: { - auto *LLVMInvoke = cast(LLVMV); - It->second = std::unique_ptr(new InvokeInst(LLVMInvoke, *this)); - return It->second.get(); - } - case llvm::Instruction::CallBr: { - auto *LLVMCallBr = cast(LLVMV); - It->second = std::unique_ptr(new CallBrInst(LLVMCallBr, *this)); - return It->second.get(); - } - case llvm::Instruction::LandingPad: { - auto *LLVMLPad = cast(LLVMV); - It->second = - std::unique_ptr(new LandingPadInst(LLVMLPad, *this)); - return It->second.get(); - } - case llvm::Instruction::CatchPad: { - auto *LLVMCPI = cast(LLVMV); - It->second = - std::unique_ptr(new CatchPadInst(LLVMCPI, *this)); - return It->second.get(); - } - case llvm::Instruction::CleanupPad: { - auto *LLVMCPI = cast(LLVMV); - It->second = - std::unique_ptr(new CleanupPadInst(LLVMCPI, *this)); - return It->second.get(); - } - case llvm::Instruction::CatchRet: { - auto *LLVMCRI = cast(LLVMV); - It->second = - std::unique_ptr(new CatchReturnInst(LLVMCRI, *this)); - return It->second.get(); - } - case llvm::Instruction::CleanupRet: { - auto *LLVMCRI = cast(LLVMV); - It->second = std::unique_ptr( - new CleanupReturnInst(LLVMCRI, *this)); - return It->second.get(); - } - case llvm::Instruction::GetElementPtr: { - auto *LLVMGEP = cast(LLVMV); - It->second = std::unique_ptr( - new GetElementPtrInst(LLVMGEP, *this)); - return It->second.get(); - } - case llvm::Instruction::CatchSwitch: { - auto *LLVMCatchSwitchInst = cast(LLVMV); - It->second = std::unique_ptr( - new CatchSwitchInst(LLVMCatchSwitchInst, *this)); - return It->second.get(); - } - case llvm::Instruction::Resume: { - auto *LLVMResumeInst = cast(LLVMV); - It->second = - std::unique_ptr(new ResumeInst(LLVMResumeInst, *this)); - return It->second.get(); - } - case llvm::Instruction::Switch: { - auto *LLVMSwitchInst = cast(LLVMV); - It->second = - std::unique_ptr(new SwitchInst(LLVMSwitchInst, *this)); - return It->second.get(); - } - case llvm::Instruction::FNeg: { - auto *LLVMUnaryOperator = cast(LLVMV); - It->second = std::unique_ptr( - 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(LLVMV); - It->second = std::unique_ptr( - new BinaryOperator(LLVMBinaryOperator, *this)); - return It->second.get(); - } - case llvm::Instruction::AtomicRMW: { - auto *LLVMAtomicRMW = cast(LLVMV); - It->second = - std::unique_ptr(new AtomicRMWInst(LLVMAtomicRMW, *this)); - return It->second.get(); - } - case llvm::Instruction::AtomicCmpXchg: { - auto *LLVMAtomicCmpXchg = cast(LLVMV); - It->second = std::unique_ptr( - new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this)); - return It->second.get(); - } - case llvm::Instruction::Alloca: { - auto *LLVMAlloca = cast(LLVMV); - It->second = std::unique_ptr(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(LLVMV); - It->second = std::unique_ptr(new CastInst(LLVMCast, *this)); - return It->second.get(); - } - case llvm::Instruction::PHI: { - auto *LLVMPhi = cast(LLVMV); - It->second = std::unique_ptr(new PHINode(LLVMPhi, *this)); - return It->second.get(); - } - case llvm::Instruction::ICmp: { - auto *LLVMICmp = cast(LLVMV); - It->second = std::unique_ptr(new ICmpInst(LLVMICmp, *this)); - return It->second.get(); - } - case llvm::Instruction::FCmp: { - auto *LLVMFCmp = cast(LLVMV); - It->second = std::unique_ptr(new FCmpInst(LLVMFCmp, *this)); - return It->second.get(); - } - case llvm::Instruction::Unreachable: { - auto *LLVMUnreachable = cast(LLVMV); - It->second = std::unique_ptr( - new UnreachableInst(LLVMUnreachable, *this)); - return It->second.get(); - } - default: - break; - } - - It->second = std::unique_ptr( - new OpaqueInst(cast(LLVMV), *this)); - return It->second.get(); -} - -BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) { - assert(getValue(LLVMBB) == nullptr && "Already exists!"); - auto NewBBPtr = std::unique_ptr(new BasicBlock(LLVMBB, *this)); - auto *BB = cast(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(new VAArgInst(SI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) { - auto NewPtr = std::unique_ptr(new FreezeInst(SI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -FenceInst *Context::createFenceInst(llvm::FenceInst *SI) { - auto NewPtr = std::unique_ptr(new FenceInst(SI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -SelectInst *Context::createSelectInst(llvm::SelectInst *SI) { - auto NewPtr = std::unique_ptr(new SelectInst(SI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -ExtractElementInst * -Context::createExtractElementInst(llvm::ExtractElementInst *EEI) { - auto NewPtr = - std::unique_ptr(new ExtractElementInst(EEI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -InsertElementInst * -Context::createInsertElementInst(llvm::InsertElementInst *IEI) { - auto NewPtr = - std::unique_ptr(new InsertElementInst(IEI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -ShuffleVectorInst * -Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) { - auto NewPtr = - std::unique_ptr(new ShuffleVectorInst(SVI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) { - auto NewPtr = - std::unique_ptr(new ExtractValueInst(EVI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) { - auto NewPtr = - std::unique_ptr(new InsertValueInst(IVI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -BranchInst *Context::createBranchInst(llvm::BranchInst *BI) { - auto NewPtr = std::unique_ptr(new BranchInst(BI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -LoadInst *Context::createLoadInst(llvm::LoadInst *LI) { - auto NewPtr = std::unique_ptr(new LoadInst(LI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -StoreInst *Context::createStoreInst(llvm::StoreInst *SI) { - auto NewPtr = std::unique_ptr(new StoreInst(SI, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) { - auto NewPtr = std::unique_ptr(new ReturnInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -CallInst *Context::createCallInst(llvm::CallInst *I) { - auto NewPtr = std::unique_ptr(new CallInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -InvokeInst *Context::createInvokeInst(llvm::InvokeInst *I) { - auto NewPtr = std::unique_ptr(new InvokeInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) { - auto NewPtr = std::unique_ptr(new CallBrInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} - -UnreachableInst *Context::createUnreachableInst(llvm::UnreachableInst *UI) { - auto NewPtr = - std::unique_ptr(new UnreachableInst(UI, *this)); - return cast(registerValue(std::move(NewPtr))); -} -LandingPadInst *Context::createLandingPadInst(llvm::LandingPadInst *I) { - auto NewPtr = std::unique_ptr(new LandingPadInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -CatchPadInst *Context::createCatchPadInst(llvm::CatchPadInst *I) { - auto NewPtr = std::unique_ptr(new CatchPadInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -CleanupPadInst *Context::createCleanupPadInst(llvm::CleanupPadInst *I) { - auto NewPtr = std::unique_ptr(new CleanupPadInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) { - auto NewPtr = std::unique_ptr(new CatchReturnInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -CleanupReturnInst * -Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) { - auto NewPtr = - std::unique_ptr(new CleanupReturnInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -GetElementPtrInst * -Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) { - auto NewPtr = - std::unique_ptr(new GetElementPtrInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) { - auto NewPtr = std::unique_ptr(new CatchSwitchInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) { - auto NewPtr = std::unique_ptr(new ResumeInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) { - auto NewPtr = std::unique_ptr(new SwitchInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -UnaryOperator *Context::createUnaryOperator(llvm::UnaryOperator *I) { - auto NewPtr = std::unique_ptr(new UnaryOperator(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -BinaryOperator *Context::createBinaryOperator(llvm::BinaryOperator *I) { - auto NewPtr = std::unique_ptr(new BinaryOperator(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -AtomicRMWInst *Context::createAtomicRMWInst(llvm::AtomicRMWInst *I) { - auto NewPtr = std::unique_ptr(new AtomicRMWInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -AtomicCmpXchgInst * -Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) { - auto NewPtr = - std::unique_ptr(new AtomicCmpXchgInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) { - auto NewPtr = std::unique_ptr(new AllocaInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -CastInst *Context::createCastInst(llvm::CastInst *I) { - auto NewPtr = std::unique_ptr(new CastInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -PHINode *Context::createPHINode(llvm::PHINode *I) { - auto NewPtr = std::unique_ptr(new PHINode(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -ICmpInst *Context::createICmpInst(llvm::ICmpInst *I) { - auto NewPtr = std::unique_ptr(new ICmpInst(I, *this)); - return cast(registerValue(std::move(NewPtr))); -} -FCmpInst *Context::createFCmpInst(llvm::FCmpInst *I) { - auto NewPtr = std::unique_ptr(new FCmpInst(I, *this)); - return cast(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(LLVMI)) - return Ctx.createICmpInst(cast(LLVMI)); - return Ctx.createFCmpInst(cast(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(Inst->Val)->copyIRFlags(F->Val); - return Inst; -} - -Type *CmpInst::makeCmpResultType(Type *OpndType) { - if (auto *VT = dyn_cast(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(VT->LLVMTy)->getElementCount())); - } - return Type::getInt1Ty(OpndType->getContext()); -} - -void CmpInst::setPredicate(Predicate P) { - Ctx.getTracker() - .emplaceIfTracking< - GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this); - cast(Val)->setPredicate(P); -} - -void CmpInst::swapOperands() { - if (ICmpInst *IC = dyn_cast(this)) - IC->swapOperands(); - else - cast(this)->swapOperands(); -} - -void ICmpInst::swapOperands() { - Ctx.getTracker().emplaceIfTracking(this); - cast(Val)->swapOperands(); -} - -void FCmpInst::swapOperands() { - Ctx.getTracker().emplaceIfTracking(this); - cast(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(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(new Function(F, *this)); - auto *SBF = cast(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(Val); auto *F = BB->getParent();