File indexing completed on 2026-05-10 08:44:25
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_SANDBOXIR_CONTEXT_H
0010 #define LLVM_SANDBOXIR_CONTEXT_H
0011
0012 #include "llvm/ADT/DenseMap.h"
0013 #include "llvm/ADT/MapVector.h"
0014 #include "llvm/ADT/SmallVector.h"
0015 #include "llvm/IR/LLVMContext.h"
0016 #include "llvm/SandboxIR/Tracker.h"
0017 #include "llvm/SandboxIR/Type.h"
0018
0019 #include <cstdint>
0020
0021 namespace llvm {
0022 namespace sandboxir {
0023
0024 class Argument;
0025 class BBIterator;
0026 class Constant;
0027 class Module;
0028 class Value;
0029
0030 class Context {
0031 public:
0032
0033 using EraseInstrCallback = std::function<void(Instruction *)>;
0034
0035 using CreateInstrCallback = std::function<void(Instruction *)>;
0036
0037
0038 using MoveInstrCallback =
0039 std::function<void(Instruction *, const BBIterator &)>;
0040
0041
0042
0043
0044 class CallbackID {
0045 public:
0046
0047
0048 using ValTy = uint64_t;
0049 static constexpr const ValTy InvalidVal = 0;
0050
0051 private:
0052
0053 ValTy Val = InvalidVal;
0054 explicit CallbackID(ValTy Val) : Val{Val} {
0055 assert(Val != InvalidVal && "newly-created ID is invalid!");
0056 }
0057
0058 public:
0059 CallbackID() = default;
0060 friend class Context;
0061 friend struct DenseMapInfo<CallbackID>;
0062 };
0063
0064 protected:
0065 LLVMContext &LLVMCtx;
0066 friend class Type;
0067 friend class PointerType;
0068 friend class IntegerType;
0069 friend class StructType;
0070 friend class Region;
0071 friend class IRSnapshotChecker;
0072
0073 Tracker IRTracker;
0074
0075
0076
0077 DenseMap<llvm::Value *, std::unique_ptr<Value>> LLVMValueToValueMap;
0078
0079
0080 DenseMap<llvm::Module *, std::unique_ptr<Module>> LLVMModuleToModuleMap;
0081
0082
0083
0084
0085 struct TypeDeleter {
0086 void operator()(Type *Ty) { delete Ty; }
0087 };
0088
0089
0090 DenseMap<llvm::Type *, std::unique_ptr<Type, TypeDeleter>> LLVMTypeToTypeMap;
0091
0092
0093
0094 MapVector<CallbackID, EraseInstrCallback> EraseInstrCallbacks;
0095
0096
0097 MapVector<CallbackID, CreateInstrCallback> CreateInstrCallbacks;
0098
0099
0100 MapVector<CallbackID, MoveInstrCallback> MoveInstrCallbacks;
0101
0102
0103
0104
0105 CallbackID::ValTy NextCallbackID = 1;
0106
0107
0108 std::unique_ptr<Value> detachLLVMValue(llvm::Value *V);
0109
0110
0111 std::unique_ptr<Value> detach(Value *V);
0112 friend class Instruction;
0113
0114 Value *registerValue(std::unique_ptr<Value> &&VPtr);
0115 friend class EraseFromParent;
0116
0117
0118 Value *getOrCreateValueInternal(llvm::Value *V, llvm::User *U = nullptr);
0119
0120 Argument *getOrCreateArgument(llvm::Argument *LLVMArg);
0121
0122 Value *getOrCreateValue(llvm::Value *LLVMV) {
0123 return getOrCreateValueInternal(LLVMV, 0);
0124 }
0125
0126 Constant *getOrCreateConstant(llvm::Constant *LLVMC);
0127 friend class Utils;
0128
0129 void runEraseInstrCallbacks(Instruction *I);
0130 void runCreateInstrCallbacks(Instruction *I);
0131 void runMoveInstrCallbacks(Instruction *I, const BBIterator &Where);
0132
0133
0134 #define DEF_CONST(ID, CLASS) friend class CLASS;
0135 #include "llvm/SandboxIR/Values.def"
0136
0137
0138
0139 BasicBlock *createBasicBlock(llvm::BasicBlock *BB);
0140 friend class BasicBlock;
0141
0142 IRBuilder<ConstantFolder> LLVMIRBuilder;
0143 auto &getLLVMIRBuilder() { return LLVMIRBuilder; }
0144
0145 VAArgInst *createVAArgInst(llvm::VAArgInst *SI);
0146 friend VAArgInst;
0147 FreezeInst *createFreezeInst(llvm::FreezeInst *SI);
0148 friend FreezeInst;
0149 FenceInst *createFenceInst(llvm::FenceInst *SI);
0150 friend FenceInst;
0151 SelectInst *createSelectInst(llvm::SelectInst *SI);
0152 friend SelectInst;
0153 InsertElementInst *createInsertElementInst(llvm::InsertElementInst *IEI);
0154 friend InsertElementInst;
0155 ExtractElementInst *createExtractElementInst(llvm::ExtractElementInst *EEI);
0156 friend ExtractElementInst;
0157 ShuffleVectorInst *createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
0158 friend ShuffleVectorInst;
0159 ExtractValueInst *createExtractValueInst(llvm::ExtractValueInst *IVI);
0160 friend ExtractValueInst;
0161 InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
0162 friend InsertValueInst;
0163 BranchInst *createBranchInst(llvm::BranchInst *I);
0164 friend BranchInst;
0165 LoadInst *createLoadInst(llvm::LoadInst *LI);
0166 friend LoadInst;
0167 StoreInst *createStoreInst(llvm::StoreInst *SI);
0168 friend StoreInst;
0169 ReturnInst *createReturnInst(llvm::ReturnInst *I);
0170 friend ReturnInst;
0171 CallInst *createCallInst(llvm::CallInst *I);
0172 friend CallInst;
0173 InvokeInst *createInvokeInst(llvm::InvokeInst *I);
0174 friend InvokeInst;
0175 CallBrInst *createCallBrInst(llvm::CallBrInst *I);
0176 friend CallBrInst;
0177 LandingPadInst *createLandingPadInst(llvm::LandingPadInst *I);
0178 friend LandingPadInst;
0179 CatchPadInst *createCatchPadInst(llvm::CatchPadInst *I);
0180 friend CatchPadInst;
0181 CleanupPadInst *createCleanupPadInst(llvm::CleanupPadInst *I);
0182 friend CleanupPadInst;
0183 CatchReturnInst *createCatchReturnInst(llvm::CatchReturnInst *I);
0184 friend CatchReturnInst;
0185 CleanupReturnInst *createCleanupReturnInst(llvm::CleanupReturnInst *I);
0186 friend CleanupReturnInst;
0187 GetElementPtrInst *createGetElementPtrInst(llvm::GetElementPtrInst *I);
0188 friend GetElementPtrInst;
0189 CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);
0190 friend CatchSwitchInst;
0191 ResumeInst *createResumeInst(llvm::ResumeInst *I);
0192 friend ResumeInst;
0193 SwitchInst *createSwitchInst(llvm::SwitchInst *I);
0194 friend SwitchInst;
0195 UnaryOperator *createUnaryOperator(llvm::UnaryOperator *I);
0196 friend UnaryOperator;
0197 BinaryOperator *createBinaryOperator(llvm::BinaryOperator *I);
0198 friend BinaryOperator;
0199 AtomicRMWInst *createAtomicRMWInst(llvm::AtomicRMWInst *I);
0200 friend AtomicRMWInst;
0201 AtomicCmpXchgInst *createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I);
0202 friend AtomicCmpXchgInst;
0203 AllocaInst *createAllocaInst(llvm::AllocaInst *I);
0204 friend AllocaInst;
0205 CastInst *createCastInst(llvm::CastInst *I);
0206 friend CastInst;
0207 PHINode *createPHINode(llvm::PHINode *I);
0208 friend PHINode;
0209 UnreachableInst *createUnreachableInst(llvm::UnreachableInst *UI);
0210 friend UnreachableInst;
0211 CmpInst *createCmpInst(llvm::CmpInst *I);
0212 friend CmpInst;
0213 ICmpInst *createICmpInst(llvm::ICmpInst *I);
0214 friend ICmpInst;
0215 FCmpInst *createFCmpInst(llvm::FCmpInst *I);
0216 friend FCmpInst;
0217
0218 public:
0219 Context(LLVMContext &LLVMCtx);
0220 ~Context();
0221
0222 void clear();
0223
0224 Tracker &getTracker() { return IRTracker; }
0225
0226 void save() { IRTracker.save(); }
0227
0228 void revert() { IRTracker.revert(); }
0229
0230 void accept() { IRTracker.accept(); }
0231
0232 sandboxir::Value *getValue(llvm::Value *V) const;
0233 const sandboxir::Value *getValue(const llvm::Value *V) const {
0234 return getValue(const_cast<llvm::Value *>(V));
0235 }
0236
0237 Module *getModule(llvm::Module *LLVMM) const;
0238
0239 Module *getOrCreateModule(llvm::Module *LLVMM);
0240
0241 Type *getType(llvm::Type *LLVMTy) {
0242 if (LLVMTy == nullptr)
0243 return nullptr;
0244 auto Pair = LLVMTypeToTypeMap.insert({LLVMTy, nullptr});
0245 auto It = Pair.first;
0246 if (Pair.second)
0247 It->second = std::unique_ptr<Type, TypeDeleter>(new Type(LLVMTy, *this));
0248 return It->second.get();
0249 }
0250
0251
0252
0253
0254
0255
0256 Function *createFunction(llvm::Function *F);
0257
0258
0259 Module *createModule(llvm::Module *LLVMM);
0260
0261
0262 size_t getNumValues() const { return LLVMValueToValueMap.size(); }
0263
0264
0265
0266
0267
0268 CallbackID registerEraseInstrCallback(EraseInstrCallback CB);
0269 void unregisterEraseInstrCallback(CallbackID ID);
0270
0271
0272
0273
0274
0275 CallbackID registerCreateInstrCallback(CreateInstrCallback CB);
0276 void unregisterCreateInstrCallback(CallbackID ID);
0277
0278
0279
0280
0281 CallbackID registerMoveInstrCallback(MoveInstrCallback CB);
0282 void unregisterMoveInstrCallback(CallbackID ID);
0283
0284
0285 };
0286
0287 }
0288
0289
0290 template <> struct DenseMapInfo<sandboxir::Context::CallbackID> {
0291 using CallbackID = sandboxir::Context::CallbackID;
0292 using ReprInfo = DenseMapInfo<CallbackID::ValTy>;
0293
0294 static CallbackID getEmptyKey() {
0295 return CallbackID{ReprInfo::getEmptyKey()};
0296 }
0297 static CallbackID getTombstoneKey() {
0298 return CallbackID{ReprInfo::getTombstoneKey()};
0299 }
0300 static unsigned getHashValue(const CallbackID &ID) {
0301 return ReprInfo::getHashValue(ID.Val);
0302 }
0303 static bool isEqual(const CallbackID &LHS, const CallbackID &RHS) {
0304 return ReprInfo::isEqual(LHS.Val, RHS.Val);
0305 }
0306 };
0307
0308 }
0309
0310 #endif