xref: /llvm-project/llvm/lib/SandboxIR/Context.cpp (revision 79cbad188afd5268235b00267d37ce39544dbd3c)
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