1165a9128Svporpo //===- Context.cpp - The Context class of Sandbox IR ----------------------===// 2165a9128Svporpo // 3165a9128Svporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4165a9128Svporpo // See https://llvm.org/LICENSE.txt for license information. 5165a9128Svporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6165a9128Svporpo // 7165a9128Svporpo //===----------------------------------------------------------------------===// 8165a9128Svporpo 9165a9128Svporpo #include "llvm/SandboxIR/Context.h" 10e22b07e7Svporpo #include "llvm/SandboxIR/Function.h" 11eba106d4Svporpo #include "llvm/SandboxIR/Instruction.h" 12eba106d4Svporpo #include "llvm/SandboxIR/Module.h" 13165a9128Svporpo 14165a9128Svporpo namespace llvm::sandboxir { 15165a9128Svporpo 16165a9128Svporpo std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) { 17165a9128Svporpo std::unique_ptr<Value> Erased; 18165a9128Svporpo auto It = LLVMValueToValueMap.find(V); 19165a9128Svporpo if (It != LLVMValueToValueMap.end()) { 20165a9128Svporpo auto *Val = It->second.release(); 21165a9128Svporpo Erased = std::unique_ptr<Value>(Val); 22165a9128Svporpo LLVMValueToValueMap.erase(It); 23165a9128Svporpo } 24165a9128Svporpo return Erased; 25165a9128Svporpo } 26165a9128Svporpo 27165a9128Svporpo std::unique_ptr<Value> Context::detach(Value *V) { 28165a9128Svporpo assert(V->getSubclassID() != Value::ClassID::Constant && 29165a9128Svporpo "Can't detach a constant!"); 30165a9128Svporpo assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!"); 31165a9128Svporpo return detachLLVMValue(V->Val); 32165a9128Svporpo } 33165a9128Svporpo 34165a9128Svporpo Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) { 35165a9128Svporpo assert(VPtr->getSubclassID() != Value::ClassID::User && 36165a9128Svporpo "Can't register a user!"); 37165a9128Svporpo 38165a9128Svporpo Value *V = VPtr.get(); 39165a9128Svporpo [[maybe_unused]] auto Pair = 40165a9128Svporpo LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)}); 41165a9128Svporpo assert(Pair.second && "Already exists!"); 424df71ab7SJorge Gorbe Moya 434df71ab7SJorge Gorbe Moya // Track creation of instructions. 444df71ab7SJorge Gorbe Moya // Please note that we don't allow the creation of detached instructions, 454df71ab7SJorge Gorbe Moya // meaning that the instructions need to be inserted into a block upon 464df71ab7SJorge Gorbe Moya // creation. This is why the tracker class combines creation and insertion. 474df71ab7SJorge Gorbe Moya if (auto *I = dyn_cast<Instruction>(V)) { 484df71ab7SJorge Gorbe Moya getTracker().emplaceIfTracking<CreateAndInsertInst>(I); 494df71ab7SJorge Gorbe Moya runCreateInstrCallbacks(I); 504df71ab7SJorge Gorbe Moya } 514df71ab7SJorge Gorbe Moya 52165a9128Svporpo return V; 53165a9128Svporpo } 54165a9128Svporpo 55165a9128Svporpo Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) { 56165a9128Svporpo auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr}); 57165a9128Svporpo auto It = Pair.first; 58165a9128Svporpo if (!Pair.second) 59165a9128Svporpo return It->second.get(); 60165a9128Svporpo 61165a9128Svporpo if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) { 62165a9128Svporpo switch (C->getValueID()) { 63165a9128Svporpo case llvm::Value::ConstantIntVal: 64165a9128Svporpo It->second = std::unique_ptr<ConstantInt>( 65165a9128Svporpo new ConstantInt(cast<llvm::ConstantInt>(C), *this)); 66165a9128Svporpo return It->second.get(); 67165a9128Svporpo case llvm::Value::ConstantFPVal: 68165a9128Svporpo It->second = std::unique_ptr<ConstantFP>( 69165a9128Svporpo new ConstantFP(cast<llvm::ConstantFP>(C), *this)); 70165a9128Svporpo return It->second.get(); 71165a9128Svporpo case llvm::Value::BlockAddressVal: 72165a9128Svporpo It->second = std::unique_ptr<BlockAddress>( 73165a9128Svporpo new BlockAddress(cast<llvm::BlockAddress>(C), *this)); 74165a9128Svporpo return It->second.get(); 75165a9128Svporpo case llvm::Value::ConstantTokenNoneVal: 76165a9128Svporpo It->second = std::unique_ptr<ConstantTokenNone>( 77165a9128Svporpo new ConstantTokenNone(cast<llvm::ConstantTokenNone>(C), *this)); 78165a9128Svporpo return It->second.get(); 79165a9128Svporpo case llvm::Value::ConstantAggregateZeroVal: { 80165a9128Svporpo auto *CAZ = cast<llvm::ConstantAggregateZero>(C); 81165a9128Svporpo It->second = std::unique_ptr<ConstantAggregateZero>( 82165a9128Svporpo new ConstantAggregateZero(CAZ, *this)); 83165a9128Svporpo auto *Ret = It->second.get(); 84165a9128Svporpo // Must create sandboxir for elements. 85165a9128Svporpo auto EC = CAZ->getElementCount(); 86165a9128Svporpo if (EC.isFixed()) { 87165a9128Svporpo for (auto ElmIdx : seq<unsigned>(0, EC.getFixedValue())) 88165a9128Svporpo getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ); 89165a9128Svporpo } 90165a9128Svporpo return Ret; 91165a9128Svporpo } 92165a9128Svporpo case llvm::Value::ConstantPointerNullVal: 93165a9128Svporpo It->second = std::unique_ptr<ConstantPointerNull>( 94165a9128Svporpo new ConstantPointerNull(cast<llvm::ConstantPointerNull>(C), *this)); 95165a9128Svporpo return It->second.get(); 96165a9128Svporpo case llvm::Value::PoisonValueVal: 97165a9128Svporpo It->second = std::unique_ptr<PoisonValue>( 98165a9128Svporpo new PoisonValue(cast<llvm::PoisonValue>(C), *this)); 99165a9128Svporpo return It->second.get(); 100165a9128Svporpo case llvm::Value::UndefValueVal: 101165a9128Svporpo It->second = std::unique_ptr<UndefValue>( 102165a9128Svporpo new UndefValue(cast<llvm::UndefValue>(C), *this)); 103165a9128Svporpo return It->second.get(); 104165a9128Svporpo case llvm::Value::DSOLocalEquivalentVal: { 105165a9128Svporpo auto *DSOLE = cast<llvm::DSOLocalEquivalent>(C); 106165a9128Svporpo It->second = std::unique_ptr<DSOLocalEquivalent>( 107165a9128Svporpo new DSOLocalEquivalent(DSOLE, *this)); 108165a9128Svporpo auto *Ret = It->second.get(); 109165a9128Svporpo getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE); 110165a9128Svporpo return Ret; 111165a9128Svporpo } 112165a9128Svporpo case llvm::Value::ConstantArrayVal: 113165a9128Svporpo It->second = std::unique_ptr<ConstantArray>( 114165a9128Svporpo new ConstantArray(cast<llvm::ConstantArray>(C), *this)); 115165a9128Svporpo break; 116165a9128Svporpo case llvm::Value::ConstantStructVal: 117165a9128Svporpo It->second = std::unique_ptr<ConstantStruct>( 118165a9128Svporpo new ConstantStruct(cast<llvm::ConstantStruct>(C), *this)); 119165a9128Svporpo break; 120165a9128Svporpo case llvm::Value::ConstantVectorVal: 121165a9128Svporpo It->second = std::unique_ptr<ConstantVector>( 122165a9128Svporpo new ConstantVector(cast<llvm::ConstantVector>(C), *this)); 123165a9128Svporpo break; 124165a9128Svporpo case llvm::Value::FunctionVal: 125165a9128Svporpo It->second = std::unique_ptr<Function>( 126165a9128Svporpo new Function(cast<llvm::Function>(C), *this)); 127165a9128Svporpo break; 128165a9128Svporpo case llvm::Value::GlobalIFuncVal: 129165a9128Svporpo It->second = std::unique_ptr<GlobalIFunc>( 130165a9128Svporpo new GlobalIFunc(cast<llvm::GlobalIFunc>(C), *this)); 131165a9128Svporpo break; 132165a9128Svporpo case llvm::Value::GlobalVariableVal: 133165a9128Svporpo It->second = std::unique_ptr<GlobalVariable>( 134165a9128Svporpo new GlobalVariable(cast<llvm::GlobalVariable>(C), *this)); 135165a9128Svporpo break; 136165a9128Svporpo case llvm::Value::GlobalAliasVal: 137165a9128Svporpo It->second = std::unique_ptr<GlobalAlias>( 138165a9128Svporpo new GlobalAlias(cast<llvm::GlobalAlias>(C), *this)); 139165a9128Svporpo break; 140165a9128Svporpo case llvm::Value::NoCFIValueVal: 141165a9128Svporpo It->second = std::unique_ptr<NoCFIValue>( 142165a9128Svporpo new NoCFIValue(cast<llvm::NoCFIValue>(C), *this)); 143165a9128Svporpo break; 144165a9128Svporpo case llvm::Value::ConstantPtrAuthVal: 145165a9128Svporpo It->second = std::unique_ptr<ConstantPtrAuth>( 146165a9128Svporpo new ConstantPtrAuth(cast<llvm::ConstantPtrAuth>(C), *this)); 147165a9128Svporpo break; 148165a9128Svporpo case llvm::Value::ConstantExprVal: 149165a9128Svporpo It->second = std::unique_ptr<ConstantExpr>( 150165a9128Svporpo new ConstantExpr(cast<llvm::ConstantExpr>(C), *this)); 151165a9128Svporpo break; 152165a9128Svporpo default: 153165a9128Svporpo It->second = std::unique_ptr<Constant>(new Constant(C, *this)); 154165a9128Svporpo break; 155165a9128Svporpo } 156165a9128Svporpo auto *NewC = It->second.get(); 157165a9128Svporpo for (llvm::Value *COp : C->operands()) 158165a9128Svporpo getOrCreateValueInternal(COp, C); 159165a9128Svporpo return NewC; 160165a9128Svporpo } 161165a9128Svporpo if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) { 162165a9128Svporpo It->second = std::unique_ptr<Argument>(new Argument(Arg, *this)); 163165a9128Svporpo return It->second.get(); 164165a9128Svporpo } 165165a9128Svporpo if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) { 166165a9128Svporpo assert(isa<llvm::BlockAddress>(U) && 167165a9128Svporpo "This won't create a SBBB, don't call this function directly!"); 168165a9128Svporpo if (auto *SBBB = getValue(BB)) 169165a9128Svporpo return SBBB; 170165a9128Svporpo return nullptr; 171165a9128Svporpo } 172165a9128Svporpo assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction"); 173165a9128Svporpo 174165a9128Svporpo switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) { 175165a9128Svporpo case llvm::Instruction::VAArg: { 176165a9128Svporpo auto *LLVMVAArg = cast<llvm::VAArgInst>(LLVMV); 177165a9128Svporpo It->second = std::unique_ptr<VAArgInst>(new VAArgInst(LLVMVAArg, *this)); 178165a9128Svporpo return It->second.get(); 179165a9128Svporpo } 180165a9128Svporpo case llvm::Instruction::Freeze: { 181165a9128Svporpo auto *LLVMFreeze = cast<llvm::FreezeInst>(LLVMV); 182165a9128Svporpo It->second = std::unique_ptr<FreezeInst>(new FreezeInst(LLVMFreeze, *this)); 183165a9128Svporpo return It->second.get(); 184165a9128Svporpo } 185165a9128Svporpo case llvm::Instruction::Fence: { 186165a9128Svporpo auto *LLVMFence = cast<llvm::FenceInst>(LLVMV); 187165a9128Svporpo It->second = std::unique_ptr<FenceInst>(new FenceInst(LLVMFence, *this)); 188165a9128Svporpo return It->second.get(); 189165a9128Svporpo } 190165a9128Svporpo case llvm::Instruction::Select: { 191165a9128Svporpo auto *LLVMSel = cast<llvm::SelectInst>(LLVMV); 192165a9128Svporpo It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this)); 193165a9128Svporpo return It->second.get(); 194165a9128Svporpo } 195165a9128Svporpo case llvm::Instruction::ExtractElement: { 196165a9128Svporpo auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV); 197165a9128Svporpo It->second = std::unique_ptr<ExtractElementInst>( 198165a9128Svporpo new ExtractElementInst(LLVMIns, *this)); 199165a9128Svporpo return It->second.get(); 200165a9128Svporpo } 201165a9128Svporpo case llvm::Instruction::InsertElement: { 202165a9128Svporpo auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV); 203165a9128Svporpo It->second = std::unique_ptr<InsertElementInst>( 204165a9128Svporpo new InsertElementInst(LLVMIns, *this)); 205165a9128Svporpo return It->second.get(); 206165a9128Svporpo } 207165a9128Svporpo case llvm::Instruction::ShuffleVector: { 208165a9128Svporpo auto *LLVMIns = cast<llvm::ShuffleVectorInst>(LLVMV); 209165a9128Svporpo It->second = std::unique_ptr<ShuffleVectorInst>( 210165a9128Svporpo new ShuffleVectorInst(LLVMIns, *this)); 211165a9128Svporpo return It->second.get(); 212165a9128Svporpo } 213165a9128Svporpo case llvm::Instruction::ExtractValue: { 214165a9128Svporpo auto *LLVMIns = cast<llvm::ExtractValueInst>(LLVMV); 215165a9128Svporpo It->second = 216165a9128Svporpo std::unique_ptr<ExtractValueInst>(new ExtractValueInst(LLVMIns, *this)); 217165a9128Svporpo return It->second.get(); 218165a9128Svporpo } 219165a9128Svporpo case llvm::Instruction::InsertValue: { 220165a9128Svporpo auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV); 221165a9128Svporpo It->second = 222165a9128Svporpo std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this)); 223165a9128Svporpo return It->second.get(); 224165a9128Svporpo } 225165a9128Svporpo case llvm::Instruction::Br: { 226165a9128Svporpo auto *LLVMBr = cast<llvm::BranchInst>(LLVMV); 227165a9128Svporpo It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this)); 228165a9128Svporpo return It->second.get(); 229165a9128Svporpo } 230165a9128Svporpo case llvm::Instruction::Load: { 231165a9128Svporpo auto *LLVMLd = cast<llvm::LoadInst>(LLVMV); 232165a9128Svporpo It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this)); 233165a9128Svporpo return It->second.get(); 234165a9128Svporpo } 235165a9128Svporpo case llvm::Instruction::Store: { 236165a9128Svporpo auto *LLVMSt = cast<llvm::StoreInst>(LLVMV); 237165a9128Svporpo It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this)); 238165a9128Svporpo return It->second.get(); 239165a9128Svporpo } 240165a9128Svporpo case llvm::Instruction::Ret: { 241165a9128Svporpo auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV); 242165a9128Svporpo It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this)); 243165a9128Svporpo return It->second.get(); 244165a9128Svporpo } 245165a9128Svporpo case llvm::Instruction::Call: { 246165a9128Svporpo auto *LLVMCall = cast<llvm::CallInst>(LLVMV); 247165a9128Svporpo It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this)); 248165a9128Svporpo return It->second.get(); 249165a9128Svporpo } 250165a9128Svporpo case llvm::Instruction::Invoke: { 251165a9128Svporpo auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV); 252165a9128Svporpo It->second = std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this)); 253165a9128Svporpo return It->second.get(); 254165a9128Svporpo } 255165a9128Svporpo case llvm::Instruction::CallBr: { 256165a9128Svporpo auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV); 257165a9128Svporpo It->second = std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this)); 258165a9128Svporpo return It->second.get(); 259165a9128Svporpo } 260165a9128Svporpo case llvm::Instruction::LandingPad: { 261165a9128Svporpo auto *LLVMLPad = cast<llvm::LandingPadInst>(LLVMV); 262165a9128Svporpo It->second = 263165a9128Svporpo std::unique_ptr<LandingPadInst>(new LandingPadInst(LLVMLPad, *this)); 264165a9128Svporpo return It->second.get(); 265165a9128Svporpo } 266165a9128Svporpo case llvm::Instruction::CatchPad: { 267165a9128Svporpo auto *LLVMCPI = cast<llvm::CatchPadInst>(LLVMV); 268165a9128Svporpo It->second = 269165a9128Svporpo std::unique_ptr<CatchPadInst>(new CatchPadInst(LLVMCPI, *this)); 270165a9128Svporpo return It->second.get(); 271165a9128Svporpo } 272165a9128Svporpo case llvm::Instruction::CleanupPad: { 273165a9128Svporpo auto *LLVMCPI = cast<llvm::CleanupPadInst>(LLVMV); 274165a9128Svporpo It->second = 275165a9128Svporpo std::unique_ptr<CleanupPadInst>(new CleanupPadInst(LLVMCPI, *this)); 276165a9128Svporpo return It->second.get(); 277165a9128Svporpo } 278165a9128Svporpo case llvm::Instruction::CatchRet: { 279165a9128Svporpo auto *LLVMCRI = cast<llvm::CatchReturnInst>(LLVMV); 280165a9128Svporpo It->second = 281165a9128Svporpo std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this)); 282165a9128Svporpo return It->second.get(); 283165a9128Svporpo } 284165a9128Svporpo case llvm::Instruction::CleanupRet: { 285165a9128Svporpo auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV); 286165a9128Svporpo It->second = std::unique_ptr<CleanupReturnInst>( 287165a9128Svporpo new CleanupReturnInst(LLVMCRI, *this)); 288165a9128Svporpo return It->second.get(); 289165a9128Svporpo } 290165a9128Svporpo case llvm::Instruction::GetElementPtr: { 291165a9128Svporpo auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV); 292165a9128Svporpo It->second = std::unique_ptr<GetElementPtrInst>( 293165a9128Svporpo new GetElementPtrInst(LLVMGEP, *this)); 294165a9128Svporpo return It->second.get(); 295165a9128Svporpo } 296165a9128Svporpo case llvm::Instruction::CatchSwitch: { 297165a9128Svporpo auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV); 298165a9128Svporpo It->second = std::unique_ptr<CatchSwitchInst>( 299165a9128Svporpo new CatchSwitchInst(LLVMCatchSwitchInst, *this)); 300165a9128Svporpo return It->second.get(); 301165a9128Svporpo } 302165a9128Svporpo case llvm::Instruction::Resume: { 303165a9128Svporpo auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV); 304165a9128Svporpo It->second = 305165a9128Svporpo std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this)); 306165a9128Svporpo return It->second.get(); 307165a9128Svporpo } 308165a9128Svporpo case llvm::Instruction::Switch: { 309165a9128Svporpo auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV); 310165a9128Svporpo It->second = 311165a9128Svporpo std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this)); 312165a9128Svporpo return It->second.get(); 313165a9128Svporpo } 314165a9128Svporpo case llvm::Instruction::FNeg: { 315165a9128Svporpo auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV); 316165a9128Svporpo It->second = std::unique_ptr<UnaryOperator>( 317165a9128Svporpo new UnaryOperator(LLVMUnaryOperator, *this)); 318165a9128Svporpo return It->second.get(); 319165a9128Svporpo } 320165a9128Svporpo case llvm::Instruction::Add: 321165a9128Svporpo case llvm::Instruction::FAdd: 322165a9128Svporpo case llvm::Instruction::Sub: 323165a9128Svporpo case llvm::Instruction::FSub: 324165a9128Svporpo case llvm::Instruction::Mul: 325165a9128Svporpo case llvm::Instruction::FMul: 326165a9128Svporpo case llvm::Instruction::UDiv: 327165a9128Svporpo case llvm::Instruction::SDiv: 328165a9128Svporpo case llvm::Instruction::FDiv: 329165a9128Svporpo case llvm::Instruction::URem: 330165a9128Svporpo case llvm::Instruction::SRem: 331165a9128Svporpo case llvm::Instruction::FRem: 332165a9128Svporpo case llvm::Instruction::Shl: 333165a9128Svporpo case llvm::Instruction::LShr: 334165a9128Svporpo case llvm::Instruction::AShr: 335165a9128Svporpo case llvm::Instruction::And: 336165a9128Svporpo case llvm::Instruction::Or: 337165a9128Svporpo case llvm::Instruction::Xor: { 338165a9128Svporpo auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV); 339165a9128Svporpo It->second = std::unique_ptr<BinaryOperator>( 340165a9128Svporpo new BinaryOperator(LLVMBinaryOperator, *this)); 341165a9128Svporpo return It->second.get(); 342165a9128Svporpo } 343165a9128Svporpo case llvm::Instruction::AtomicRMW: { 344165a9128Svporpo auto *LLVMAtomicRMW = cast<llvm::AtomicRMWInst>(LLVMV); 345165a9128Svporpo It->second = 346165a9128Svporpo std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(LLVMAtomicRMW, *this)); 347165a9128Svporpo return It->second.get(); 348165a9128Svporpo } 349165a9128Svporpo case llvm::Instruction::AtomicCmpXchg: { 350165a9128Svporpo auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV); 351165a9128Svporpo It->second = std::unique_ptr<AtomicCmpXchgInst>( 352165a9128Svporpo new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this)); 353165a9128Svporpo return It->second.get(); 354165a9128Svporpo } 355165a9128Svporpo case llvm::Instruction::Alloca: { 356165a9128Svporpo auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV); 357165a9128Svporpo It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this)); 358165a9128Svporpo return It->second.get(); 359165a9128Svporpo } 360165a9128Svporpo case llvm::Instruction::ZExt: 361165a9128Svporpo case llvm::Instruction::SExt: 362165a9128Svporpo case llvm::Instruction::FPToUI: 363165a9128Svporpo case llvm::Instruction::FPToSI: 364165a9128Svporpo case llvm::Instruction::FPExt: 365165a9128Svporpo case llvm::Instruction::PtrToInt: 366165a9128Svporpo case llvm::Instruction::IntToPtr: 367165a9128Svporpo case llvm::Instruction::SIToFP: 368165a9128Svporpo case llvm::Instruction::UIToFP: 369165a9128Svporpo case llvm::Instruction::Trunc: 370165a9128Svporpo case llvm::Instruction::FPTrunc: 371165a9128Svporpo case llvm::Instruction::BitCast: 372165a9128Svporpo case llvm::Instruction::AddrSpaceCast: { 373165a9128Svporpo auto *LLVMCast = cast<llvm::CastInst>(LLVMV); 374165a9128Svporpo It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this)); 375165a9128Svporpo return It->second.get(); 376165a9128Svporpo } 377165a9128Svporpo case llvm::Instruction::PHI: { 378165a9128Svporpo auto *LLVMPhi = cast<llvm::PHINode>(LLVMV); 379165a9128Svporpo It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this)); 380165a9128Svporpo return It->second.get(); 381165a9128Svporpo } 382165a9128Svporpo case llvm::Instruction::ICmp: { 383165a9128Svporpo auto *LLVMICmp = cast<llvm::ICmpInst>(LLVMV); 384165a9128Svporpo It->second = std::unique_ptr<ICmpInst>(new ICmpInst(LLVMICmp, *this)); 385165a9128Svporpo return It->second.get(); 386165a9128Svporpo } 387165a9128Svporpo case llvm::Instruction::FCmp: { 388165a9128Svporpo auto *LLVMFCmp = cast<llvm::FCmpInst>(LLVMV); 389165a9128Svporpo It->second = std::unique_ptr<FCmpInst>(new FCmpInst(LLVMFCmp, *this)); 390165a9128Svporpo return It->second.get(); 391165a9128Svporpo } 392165a9128Svporpo case llvm::Instruction::Unreachable: { 393165a9128Svporpo auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV); 394165a9128Svporpo It->second = std::unique_ptr<UnreachableInst>( 395165a9128Svporpo new UnreachableInst(LLVMUnreachable, *this)); 396165a9128Svporpo return It->second.get(); 397165a9128Svporpo } 398165a9128Svporpo default: 399165a9128Svporpo break; 400165a9128Svporpo } 401165a9128Svporpo 402165a9128Svporpo It->second = std::unique_ptr<OpaqueInst>( 403165a9128Svporpo new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this)); 404165a9128Svporpo return It->second.get(); 405165a9128Svporpo } 406165a9128Svporpo 407165a9128Svporpo Argument *Context::getOrCreateArgument(llvm::Argument *LLVMArg) { 408165a9128Svporpo auto Pair = LLVMValueToValueMap.insert({LLVMArg, nullptr}); 409165a9128Svporpo auto It = Pair.first; 410165a9128Svporpo if (Pair.second) { 411165a9128Svporpo It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this)); 412165a9128Svporpo return cast<Argument>(It->second.get()); 413165a9128Svporpo } 414165a9128Svporpo return cast<Argument>(It->second.get()); 415165a9128Svporpo } 416165a9128Svporpo 4177a2c5c69Svporpo Constant *Context::getOrCreateConstant(llvm::Constant *LLVMC) { 4187a2c5c69Svporpo return cast<Constant>(getOrCreateValueInternal(LLVMC, 0)); 4197a2c5c69Svporpo } 4207a2c5c69Svporpo 421165a9128Svporpo BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) { 422165a9128Svporpo assert(getValue(LLVMBB) == nullptr && "Already exists!"); 423165a9128Svporpo auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this)); 424165a9128Svporpo auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr))); 425165a9128Svporpo // Create SandboxIR for BB's body. 426165a9128Svporpo BB->buildBasicBlockFromLLVMIR(LLVMBB); 427165a9128Svporpo return BB; 428165a9128Svporpo } 429165a9128Svporpo 430165a9128Svporpo VAArgInst *Context::createVAArgInst(llvm::VAArgInst *SI) { 431165a9128Svporpo auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this)); 432165a9128Svporpo return cast<VAArgInst>(registerValue(std::move(NewPtr))); 433165a9128Svporpo } 434165a9128Svporpo 435165a9128Svporpo FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) { 436165a9128Svporpo auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this)); 437165a9128Svporpo return cast<FreezeInst>(registerValue(std::move(NewPtr))); 438165a9128Svporpo } 439165a9128Svporpo 440165a9128Svporpo FenceInst *Context::createFenceInst(llvm::FenceInst *SI) { 441165a9128Svporpo auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this)); 442165a9128Svporpo return cast<FenceInst>(registerValue(std::move(NewPtr))); 443165a9128Svporpo } 444165a9128Svporpo 445165a9128Svporpo SelectInst *Context::createSelectInst(llvm::SelectInst *SI) { 446165a9128Svporpo auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this)); 447165a9128Svporpo return cast<SelectInst>(registerValue(std::move(NewPtr))); 448165a9128Svporpo } 449165a9128Svporpo 450165a9128Svporpo ExtractElementInst * 451165a9128Svporpo Context::createExtractElementInst(llvm::ExtractElementInst *EEI) { 452165a9128Svporpo auto NewPtr = 453165a9128Svporpo std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this)); 454165a9128Svporpo return cast<ExtractElementInst>(registerValue(std::move(NewPtr))); 455165a9128Svporpo } 456165a9128Svporpo 457165a9128Svporpo InsertElementInst * 458165a9128Svporpo Context::createInsertElementInst(llvm::InsertElementInst *IEI) { 459165a9128Svporpo auto NewPtr = 460165a9128Svporpo std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this)); 461165a9128Svporpo return cast<InsertElementInst>(registerValue(std::move(NewPtr))); 462165a9128Svporpo } 463165a9128Svporpo 464165a9128Svporpo ShuffleVectorInst * 465165a9128Svporpo Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) { 466165a9128Svporpo auto NewPtr = 467165a9128Svporpo std::unique_ptr<ShuffleVectorInst>(new ShuffleVectorInst(SVI, *this)); 468165a9128Svporpo return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr))); 469165a9128Svporpo } 470165a9128Svporpo 471165a9128Svporpo ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) { 472165a9128Svporpo auto NewPtr = 473165a9128Svporpo std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this)); 474165a9128Svporpo return cast<ExtractValueInst>(registerValue(std::move(NewPtr))); 475165a9128Svporpo } 476165a9128Svporpo 477165a9128Svporpo InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) { 478165a9128Svporpo auto NewPtr = 479165a9128Svporpo std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this)); 480165a9128Svporpo return cast<InsertValueInst>(registerValue(std::move(NewPtr))); 481165a9128Svporpo } 482165a9128Svporpo 483165a9128Svporpo BranchInst *Context::createBranchInst(llvm::BranchInst *BI) { 484165a9128Svporpo auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this)); 485165a9128Svporpo return cast<BranchInst>(registerValue(std::move(NewPtr))); 486165a9128Svporpo } 487165a9128Svporpo 488165a9128Svporpo LoadInst *Context::createLoadInst(llvm::LoadInst *LI) { 489165a9128Svporpo auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this)); 490165a9128Svporpo return cast<LoadInst>(registerValue(std::move(NewPtr))); 491165a9128Svporpo } 492165a9128Svporpo 493165a9128Svporpo StoreInst *Context::createStoreInst(llvm::StoreInst *SI) { 494165a9128Svporpo auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this)); 495165a9128Svporpo return cast<StoreInst>(registerValue(std::move(NewPtr))); 496165a9128Svporpo } 497165a9128Svporpo 498165a9128Svporpo ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) { 499165a9128Svporpo auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this)); 500165a9128Svporpo return cast<ReturnInst>(registerValue(std::move(NewPtr))); 501165a9128Svporpo } 502165a9128Svporpo 503165a9128Svporpo CallInst *Context::createCallInst(llvm::CallInst *I) { 504165a9128Svporpo auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this)); 505165a9128Svporpo return cast<CallInst>(registerValue(std::move(NewPtr))); 506165a9128Svporpo } 507165a9128Svporpo 508165a9128Svporpo InvokeInst *Context::createInvokeInst(llvm::InvokeInst *I) { 509165a9128Svporpo auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this)); 510165a9128Svporpo return cast<InvokeInst>(registerValue(std::move(NewPtr))); 511165a9128Svporpo } 512165a9128Svporpo 513165a9128Svporpo CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) { 514165a9128Svporpo auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this)); 515165a9128Svporpo return cast<CallBrInst>(registerValue(std::move(NewPtr))); 516165a9128Svporpo } 517165a9128Svporpo 518165a9128Svporpo UnreachableInst *Context::createUnreachableInst(llvm::UnreachableInst *UI) { 519165a9128Svporpo auto NewPtr = 520165a9128Svporpo std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this)); 521165a9128Svporpo return cast<UnreachableInst>(registerValue(std::move(NewPtr))); 522165a9128Svporpo } 523165a9128Svporpo LandingPadInst *Context::createLandingPadInst(llvm::LandingPadInst *I) { 524165a9128Svporpo auto NewPtr = std::unique_ptr<LandingPadInst>(new LandingPadInst(I, *this)); 525165a9128Svporpo return cast<LandingPadInst>(registerValue(std::move(NewPtr))); 526165a9128Svporpo } 527165a9128Svporpo CatchPadInst *Context::createCatchPadInst(llvm::CatchPadInst *I) { 528165a9128Svporpo auto NewPtr = std::unique_ptr<CatchPadInst>(new CatchPadInst(I, *this)); 529165a9128Svporpo return cast<CatchPadInst>(registerValue(std::move(NewPtr))); 530165a9128Svporpo } 531165a9128Svporpo CleanupPadInst *Context::createCleanupPadInst(llvm::CleanupPadInst *I) { 532165a9128Svporpo auto NewPtr = std::unique_ptr<CleanupPadInst>(new CleanupPadInst(I, *this)); 533165a9128Svporpo return cast<CleanupPadInst>(registerValue(std::move(NewPtr))); 534165a9128Svporpo } 535165a9128Svporpo CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) { 536165a9128Svporpo auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this)); 537165a9128Svporpo return cast<CatchReturnInst>(registerValue(std::move(NewPtr))); 538165a9128Svporpo } 539165a9128Svporpo CleanupReturnInst * 540165a9128Svporpo Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) { 541165a9128Svporpo auto NewPtr = 542165a9128Svporpo std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this)); 543165a9128Svporpo return cast<CleanupReturnInst>(registerValue(std::move(NewPtr))); 544165a9128Svporpo } 545165a9128Svporpo GetElementPtrInst * 546165a9128Svporpo Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) { 547165a9128Svporpo auto NewPtr = 548165a9128Svporpo std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this)); 549165a9128Svporpo return cast<GetElementPtrInst>(registerValue(std::move(NewPtr))); 550165a9128Svporpo } 551165a9128Svporpo CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) { 552165a9128Svporpo auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this)); 553165a9128Svporpo return cast<CatchSwitchInst>(registerValue(std::move(NewPtr))); 554165a9128Svporpo } 555165a9128Svporpo ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) { 556165a9128Svporpo auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this)); 557165a9128Svporpo return cast<ResumeInst>(registerValue(std::move(NewPtr))); 558165a9128Svporpo } 559165a9128Svporpo SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) { 560165a9128Svporpo auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this)); 561165a9128Svporpo return cast<SwitchInst>(registerValue(std::move(NewPtr))); 562165a9128Svporpo } 563165a9128Svporpo UnaryOperator *Context::createUnaryOperator(llvm::UnaryOperator *I) { 564165a9128Svporpo auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this)); 565165a9128Svporpo return cast<UnaryOperator>(registerValue(std::move(NewPtr))); 566165a9128Svporpo } 567165a9128Svporpo BinaryOperator *Context::createBinaryOperator(llvm::BinaryOperator *I) { 568165a9128Svporpo auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this)); 569165a9128Svporpo return cast<BinaryOperator>(registerValue(std::move(NewPtr))); 570165a9128Svporpo } 571165a9128Svporpo AtomicRMWInst *Context::createAtomicRMWInst(llvm::AtomicRMWInst *I) { 572165a9128Svporpo auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this)); 573165a9128Svporpo return cast<AtomicRMWInst>(registerValue(std::move(NewPtr))); 574165a9128Svporpo } 575165a9128Svporpo AtomicCmpXchgInst * 576165a9128Svporpo Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) { 577165a9128Svporpo auto NewPtr = 578165a9128Svporpo std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this)); 579165a9128Svporpo return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr))); 580165a9128Svporpo } 581165a9128Svporpo AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) { 582165a9128Svporpo auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this)); 583165a9128Svporpo return cast<AllocaInst>(registerValue(std::move(NewPtr))); 584165a9128Svporpo } 585165a9128Svporpo CastInst *Context::createCastInst(llvm::CastInst *I) { 586165a9128Svporpo auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this)); 587165a9128Svporpo return cast<CastInst>(registerValue(std::move(NewPtr))); 588165a9128Svporpo } 589165a9128Svporpo PHINode *Context::createPHINode(llvm::PHINode *I) { 590165a9128Svporpo auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this)); 591165a9128Svporpo return cast<PHINode>(registerValue(std::move(NewPtr))); 592165a9128Svporpo } 593165a9128Svporpo ICmpInst *Context::createICmpInst(llvm::ICmpInst *I) { 594165a9128Svporpo auto NewPtr = std::unique_ptr<ICmpInst>(new ICmpInst(I, *this)); 595165a9128Svporpo return cast<ICmpInst>(registerValue(std::move(NewPtr))); 596165a9128Svporpo } 597165a9128Svporpo FCmpInst *Context::createFCmpInst(llvm::FCmpInst *I) { 598165a9128Svporpo auto NewPtr = std::unique_ptr<FCmpInst>(new FCmpInst(I, *this)); 599165a9128Svporpo return cast<FCmpInst>(registerValue(std::move(NewPtr))); 600165a9128Svporpo } 601165a9128Svporpo Value *Context::getValue(llvm::Value *V) const { 602165a9128Svporpo auto It = LLVMValueToValueMap.find(V); 603165a9128Svporpo if (It != LLVMValueToValueMap.end()) 604165a9128Svporpo return It->second.get(); 605165a9128Svporpo return nullptr; 606165a9128Svporpo } 607165a9128Svporpo 6087a2c5c69Svporpo Context::Context(LLVMContext &LLVMCtx) 6097a2c5c69Svporpo : LLVMCtx(LLVMCtx), IRTracker(*this), 6107a2c5c69Svporpo LLVMIRBuilder(LLVMCtx, ConstantFolder()) {} 6117a2c5c69Svporpo 612eba106d4Svporpo Context::~Context() {} 613eba106d4Svporpo 614*79cbad18Svporpo void Context::clear() { 615*79cbad18Svporpo // TODO: Ideally we should clear only function-scope objects, and keep global 616*79cbad18Svporpo // objects, like Constants to avoid recreating them. 617*79cbad18Svporpo LLVMValueToValueMap.clear(); 618*79cbad18Svporpo } 619*79cbad18Svporpo 620165a9128Svporpo Module *Context::getModule(llvm::Module *LLVMM) const { 621165a9128Svporpo auto It = LLVMModuleToModuleMap.find(LLVMM); 622165a9128Svporpo if (It != LLVMModuleToModuleMap.end()) 623165a9128Svporpo return It->second.get(); 624165a9128Svporpo return nullptr; 625165a9128Svporpo } 626165a9128Svporpo 627165a9128Svporpo Module *Context::getOrCreateModule(llvm::Module *LLVMM) { 628165a9128Svporpo auto Pair = LLVMModuleToModuleMap.insert({LLVMM, nullptr}); 629165a9128Svporpo auto It = Pair.first; 630165a9128Svporpo if (!Pair.second) 631165a9128Svporpo return It->second.get(); 632165a9128Svporpo It->second = std::unique_ptr<Module>(new Module(*LLVMM, *this)); 633165a9128Svporpo return It->second.get(); 634165a9128Svporpo } 635165a9128Svporpo 636165a9128Svporpo Function *Context::createFunction(llvm::Function *F) { 637165a9128Svporpo // Create the module if needed before we create the new sandboxir::Function. 638165a9128Svporpo // Note: this won't fully populate the module. The only globals that will be 639165a9128Svporpo // available will be the ones being used within the function. 640165a9128Svporpo getOrCreateModule(F->getParent()); 641165a9128Svporpo 642334a1cdbSvporpo // There may be a function declaration already defined. Regardless destroy it. 643334a1cdbSvporpo if (Function *ExistingF = cast_or_null<Function>(getValue(F))) 644334a1cdbSvporpo detach(ExistingF); 645334a1cdbSvporpo 646165a9128Svporpo auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this)); 647165a9128Svporpo auto *SBF = cast<Function>(registerValue(std::move(NewFPtr))); 648165a9128Svporpo // Create arguments. 649165a9128Svporpo for (auto &Arg : F->args()) 650165a9128Svporpo getOrCreateArgument(&Arg); 651165a9128Svporpo // Create BBs. 652165a9128Svporpo for (auto &BB : *F) 653165a9128Svporpo createBasicBlock(&BB); 654165a9128Svporpo return SBF; 655165a9128Svporpo } 656165a9128Svporpo 657165a9128Svporpo Module *Context::createModule(llvm::Module *LLVMM) { 658165a9128Svporpo auto *M = getOrCreateModule(LLVMM); 659165a9128Svporpo // Create the functions. 660165a9128Svporpo for (auto &LLVMF : *LLVMM) 661165a9128Svporpo createFunction(&LLVMF); 662165a9128Svporpo // Create globals. 663165a9128Svporpo for (auto &Global : LLVMM->globals()) 664165a9128Svporpo getOrCreateValue(&Global); 665165a9128Svporpo // Create aliases. 666165a9128Svporpo for (auto &Alias : LLVMM->aliases()) 667165a9128Svporpo getOrCreateValue(&Alias); 668165a9128Svporpo // Create ifuncs. 669165a9128Svporpo for (auto &IFunc : LLVMM->ifuncs()) 670165a9128Svporpo getOrCreateValue(&IFunc); 671165a9128Svporpo 672165a9128Svporpo return M; 673165a9128Svporpo } 674165a9128Svporpo 6754df71ab7SJorge Gorbe Moya void Context::runEraseInstrCallbacks(Instruction *I) { 6764df71ab7SJorge Gorbe Moya for (const auto &CBEntry : EraseInstrCallbacks) 6774df71ab7SJorge Gorbe Moya CBEntry.second(I); 6784df71ab7SJorge Gorbe Moya } 6794df71ab7SJorge Gorbe Moya 6804df71ab7SJorge Gorbe Moya void Context::runCreateInstrCallbacks(Instruction *I) { 6814df71ab7SJorge Gorbe Moya for (auto &CBEntry : CreateInstrCallbacks) 6824df71ab7SJorge Gorbe Moya CBEntry.second(I); 6834df71ab7SJorge Gorbe Moya } 6844df71ab7SJorge Gorbe Moya 6854df71ab7SJorge Gorbe Moya void Context::runMoveInstrCallbacks(Instruction *I, const BBIterator &WhereIt) { 6864df71ab7SJorge Gorbe Moya for (auto &CBEntry : MoveInstrCallbacks) 6874df71ab7SJorge Gorbe Moya CBEntry.second(I, WhereIt); 6884df71ab7SJorge Gorbe Moya } 6894df71ab7SJorge Gorbe Moya 6904df71ab7SJorge Gorbe Moya // An arbitrary limit, to check for accidental misuse. We expect a small number 6914df71ab7SJorge Gorbe Moya // of callbacks to be registered at a time, but we can increase this number if 6924df71ab7SJorge Gorbe Moya // we discover we needed more. 693c79827cdSKazu Hirata [[maybe_unused]] static constexpr int MaxRegisteredCallbacks = 16; 6944df71ab7SJorge Gorbe Moya 6954df71ab7SJorge Gorbe Moya Context::CallbackID Context::registerEraseInstrCallback(EraseInstrCallback CB) { 6964df71ab7SJorge Gorbe Moya assert(EraseInstrCallbacks.size() <= MaxRegisteredCallbacks && 6974df71ab7SJorge Gorbe Moya "EraseInstrCallbacks size limit exceeded"); 6984c0a0f72STyler Lanphear CallbackID ID{NextCallbackID++}; 6994df71ab7SJorge Gorbe Moya EraseInstrCallbacks[ID] = CB; 7004df71ab7SJorge Gorbe Moya return ID; 7014df71ab7SJorge Gorbe Moya } 7024df71ab7SJorge Gorbe Moya void Context::unregisterEraseInstrCallback(CallbackID ID) { 7034df71ab7SJorge Gorbe Moya [[maybe_unused]] bool Erased = EraseInstrCallbacks.erase(ID); 7044df71ab7SJorge Gorbe Moya assert(Erased && 7054df71ab7SJorge Gorbe Moya "Callback ID not found in EraseInstrCallbacks during deregistration"); 7064df71ab7SJorge Gorbe Moya } 7074df71ab7SJorge Gorbe Moya 7084df71ab7SJorge Gorbe Moya Context::CallbackID 7094df71ab7SJorge Gorbe Moya Context::registerCreateInstrCallback(CreateInstrCallback CB) { 7104df71ab7SJorge Gorbe Moya assert(CreateInstrCallbacks.size() <= MaxRegisteredCallbacks && 7114df71ab7SJorge Gorbe Moya "CreateInstrCallbacks size limit exceeded"); 7124c0a0f72STyler Lanphear CallbackID ID{NextCallbackID++}; 7134df71ab7SJorge Gorbe Moya CreateInstrCallbacks[ID] = CB; 7144df71ab7SJorge Gorbe Moya return ID; 7154df71ab7SJorge Gorbe Moya } 7164df71ab7SJorge Gorbe Moya void Context::unregisterCreateInstrCallback(CallbackID ID) { 7174df71ab7SJorge Gorbe Moya [[maybe_unused]] bool Erased = CreateInstrCallbacks.erase(ID); 7184df71ab7SJorge Gorbe Moya assert(Erased && 7194df71ab7SJorge Gorbe Moya "Callback ID not found in CreateInstrCallbacks during deregistration"); 7204df71ab7SJorge Gorbe Moya } 7214df71ab7SJorge Gorbe Moya 7224df71ab7SJorge Gorbe Moya Context::CallbackID Context::registerMoveInstrCallback(MoveInstrCallback CB) { 7234df71ab7SJorge Gorbe Moya assert(MoveInstrCallbacks.size() <= MaxRegisteredCallbacks && 7244df71ab7SJorge Gorbe Moya "MoveInstrCallbacks size limit exceeded"); 7254c0a0f72STyler Lanphear CallbackID ID{NextCallbackID++}; 7264df71ab7SJorge Gorbe Moya MoveInstrCallbacks[ID] = CB; 7274df71ab7SJorge Gorbe Moya return ID; 7284df71ab7SJorge Gorbe Moya } 7294df71ab7SJorge Gorbe Moya void Context::unregisterMoveInstrCallback(CallbackID ID) { 7304df71ab7SJorge Gorbe Moya [[maybe_unused]] bool Erased = MoveInstrCallbacks.erase(ID); 7314df71ab7SJorge Gorbe Moya assert(Erased && 7324df71ab7SJorge Gorbe Moya "Callback ID not found in MoveInstrCallbacks during deregistration"); 7334df71ab7SJorge Gorbe Moya } 7344df71ab7SJorge Gorbe Moya 735165a9128Svporpo } // namespace llvm::sandboxir 736