LLVM 23.0.0git
Context.cpp
Go to the documentation of this file.
1//===- Context.cpp - The Context class of Sandbox IR ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/IR/InlineAsm.h"
14
15namespace llvm::sandboxir {
16
17std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
18 std::unique_ptr<Value> Erased;
19 auto It = LLVMValueToValueMap.find(V);
20 if (It != LLVMValueToValueMap.end()) {
21 auto *Val = It->second.release();
22 Erased = std::unique_ptr<Value>(Val);
23 LLVMValueToValueMap.erase(It);
24 }
25 return Erased;
26}
27
28std::unique_ptr<Value> Context::detach(Value *V) {
29 assert(V->getSubclassID() != Value::ClassID::Constant &&
30 "Can't detach a constant!");
31 assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
32 return detachLLVMValue(V->Val);
33}
34
35Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
36 assert(VPtr->getSubclassID() != Value::ClassID::User &&
37 "Can't register a user!");
38
39 Value *V = VPtr.get();
40 [[maybe_unused]] auto Pair =
41 LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
42 assert(Pair.second && "Already exists!");
43
44 // Track creation of instructions.
45 // Please note that we don't allow the creation of detached instructions,
46 // meaning that the instructions need to be inserted into a block upon
47 // creation. This is why the tracker class combines creation and insertion.
48 if (auto *I = dyn_cast<Instruction>(V)) {
51 }
52
53 return V;
54}
55
57 auto Pair = LLVMValueToValueMap.try_emplace(LLVMV);
58 auto It = Pair.first;
59 if (!Pair.second)
60 return It->second.get();
61
62 // Instruction
63 if (auto *LLVMI = dyn_cast<llvm::Instruction>(LLVMV)) {
64 switch (LLVMI->getOpcode()) {
65 case llvm::Instruction::VAArg: {
66 auto *LLVMVAArg = cast<llvm::VAArgInst>(LLVMV);
67 It->second = std::unique_ptr<VAArgInst>(new VAArgInst(LLVMVAArg, *this));
68 return It->second.get();
69 }
70 case llvm::Instruction::Freeze: {
72 It->second =
73 std::unique_ptr<FreezeInst>(new FreezeInst(LLVMFreeze, *this));
74 return It->second.get();
75 }
76 case llvm::Instruction::Fence: {
77 auto *LLVMFence = cast<llvm::FenceInst>(LLVMV);
78 It->second = std::unique_ptr<FenceInst>(new FenceInst(LLVMFence, *this));
79 return It->second.get();
80 }
81 case llvm::Instruction::Select: {
82 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
83 It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
84 return It->second.get();
85 }
86 case llvm::Instruction::ExtractElement: {
87 auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
88 It->second = std::unique_ptr<ExtractElementInst>(
89 new ExtractElementInst(LLVMIns, *this));
90 return It->second.get();
91 }
92 case llvm::Instruction::InsertElement: {
93 auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
94 It->second = std::unique_ptr<InsertElementInst>(
95 new InsertElementInst(LLVMIns, *this));
96 return It->second.get();
97 }
98 case llvm::Instruction::ShuffleVector: {
99 auto *LLVMIns = cast<llvm::ShuffleVectorInst>(LLVMV);
100 It->second = std::unique_ptr<ShuffleVectorInst>(
101 new ShuffleVectorInst(LLVMIns, *this));
102 return It->second.get();
103 }
104 case llvm::Instruction::ExtractValue: {
105 auto *LLVMIns = cast<llvm::ExtractValueInst>(LLVMV);
106 It->second = std::unique_ptr<ExtractValueInst>(
107 new ExtractValueInst(LLVMIns, *this));
108 return It->second.get();
109 }
110 case llvm::Instruction::InsertValue: {
111 auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
112 It->second =
113 std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this));
114 return It->second.get();
115 }
116 case llvm::Instruction::UncondBr:
117 case llvm::Instruction::CondBr: {
118 auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
119 It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
120 return It->second.get();
121 }
122 case llvm::Instruction::Load: {
123 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
124 It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
125 return It->second.get();
126 }
127 case llvm::Instruction::Store: {
128 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
129 It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
130 return It->second.get();
131 }
132 case llvm::Instruction::Ret: {
133 auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
134 It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
135 return It->second.get();
136 }
137 case llvm::Instruction::Call: {
138 auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
139 It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
140 return It->second.get();
141 }
142 case llvm::Instruction::Invoke: {
143 auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
144 It->second =
145 std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
146 return It->second.get();
147 }
148 case llvm::Instruction::CallBr: {
149 auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
150 It->second =
151 std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
152 return It->second.get();
153 }
154 case llvm::Instruction::LandingPad: {
155 auto *LLVMLPad = cast<llvm::LandingPadInst>(LLVMV);
156 It->second =
157 std::unique_ptr<LandingPadInst>(new LandingPadInst(LLVMLPad, *this));
158 return It->second.get();
159 }
160 case llvm::Instruction::CatchPad: {
161 auto *LLVMCPI = cast<llvm::CatchPadInst>(LLVMV);
162 It->second =
163 std::unique_ptr<CatchPadInst>(new CatchPadInst(LLVMCPI, *this));
164 return It->second.get();
165 }
166 case llvm::Instruction::CleanupPad: {
167 auto *LLVMCPI = cast<llvm::CleanupPadInst>(LLVMV);
168 It->second =
169 std::unique_ptr<CleanupPadInst>(new CleanupPadInst(LLVMCPI, *this));
170 return It->second.get();
171 }
172 case llvm::Instruction::CatchRet: {
173 auto *LLVMCRI = cast<llvm::CatchReturnInst>(LLVMV);
174 It->second =
175 std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
176 return It->second.get();
177 }
178 case llvm::Instruction::CleanupRet: {
179 auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV);
180 It->second = std::unique_ptr<CleanupReturnInst>(
181 new CleanupReturnInst(LLVMCRI, *this));
182 return It->second.get();
183 }
184 case llvm::Instruction::GetElementPtr: {
185 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
186 It->second = std::unique_ptr<GetElementPtrInst>(
187 new GetElementPtrInst(LLVMGEP, *this));
188 return It->second.get();
189 }
190 case llvm::Instruction::CatchSwitch: {
191 auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV);
192 It->second = std::unique_ptr<CatchSwitchInst>(
193 new CatchSwitchInst(LLVMCatchSwitchInst, *this));
194 return It->second.get();
195 }
196 case llvm::Instruction::Resume: {
197 auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV);
198 It->second =
199 std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this));
200 return It->second.get();
201 }
202 case llvm::Instruction::Switch: {
203 auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
204 It->second =
205 std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this));
206 return It->second.get();
207 }
208 case llvm::Instruction::FNeg: {
209 auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
210 It->second = std::unique_ptr<UnaryOperator>(
211 new UnaryOperator(LLVMUnaryOperator, *this));
212 return It->second.get();
213 }
214 case llvm::Instruction::Add:
215 case llvm::Instruction::FAdd:
216 case llvm::Instruction::Sub:
217 case llvm::Instruction::FSub:
218 case llvm::Instruction::Mul:
219 case llvm::Instruction::FMul:
220 case llvm::Instruction::UDiv:
221 case llvm::Instruction::SDiv:
222 case llvm::Instruction::FDiv:
223 case llvm::Instruction::URem:
224 case llvm::Instruction::SRem:
225 case llvm::Instruction::FRem:
226 case llvm::Instruction::Shl:
227 case llvm::Instruction::LShr:
228 case llvm::Instruction::AShr:
229 case llvm::Instruction::And:
230 case llvm::Instruction::Or:
231 case llvm::Instruction::Xor: {
232 auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
233 It->second = std::unique_ptr<BinaryOperator>(
234 new BinaryOperator(LLVMBinaryOperator, *this));
235 return It->second.get();
236 }
237 case llvm::Instruction::AtomicRMW: {
239 It->second = std::unique_ptr<AtomicRMWInst>(
240 new AtomicRMWInst(LLVMAtomicRMW, *this));
241 return It->second.get();
242 }
243 case llvm::Instruction::AtomicCmpXchg: {
245 It->second = std::unique_ptr<AtomicCmpXchgInst>(
247 return It->second.get();
248 }
249 case llvm::Instruction::Alloca: {
250 auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
251 It->second =
252 std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
253 return It->second.get();
254 }
255 case llvm::Instruction::ZExt:
256 case llvm::Instruction::SExt:
257 case llvm::Instruction::FPToUI:
258 case llvm::Instruction::FPToSI:
259 case llvm::Instruction::FPExt:
260 case llvm::Instruction::PtrToAddr:
261 case llvm::Instruction::PtrToInt:
262 case llvm::Instruction::IntToPtr:
263 case llvm::Instruction::SIToFP:
264 case llvm::Instruction::UIToFP:
265 case llvm::Instruction::Trunc:
266 case llvm::Instruction::FPTrunc:
267 case llvm::Instruction::BitCast:
268 case llvm::Instruction::AddrSpaceCast: {
269 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
270 It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
271 return It->second.get();
272 }
273 case llvm::Instruction::PHI: {
274 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
275 It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
276 return It->second.get();
277 }
278 case llvm::Instruction::ICmp: {
279 auto *LLVMICmp = cast<llvm::ICmpInst>(LLVMV);
280 It->second = std::unique_ptr<ICmpInst>(new ICmpInst(LLVMICmp, *this));
281 return It->second.get();
282 }
283 case llvm::Instruction::FCmp: {
284 auto *LLVMFCmp = cast<llvm::FCmpInst>(LLVMV);
285 It->second = std::unique_ptr<FCmpInst>(new FCmpInst(LLVMFCmp, *this));
286 return It->second.get();
287 }
288 case llvm::Instruction::Unreachable: {
290 It->second = std::unique_ptr<UnreachableInst>(
291 new UnreachableInst(LLVMUnreachable, *this));
292 return It->second.get();
293 }
294 default:
295 break;
296 }
297 It->second = std::unique_ptr<OpaqueInst>(
298 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
299 return It->second.get();
300 }
301 // Constant
302 if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV)) {
303 switch (LLVMC->getValueID()) {
304 case llvm::Value::ConstantIntVal:
305 It->second = std::unique_ptr<ConstantInt>(
306 new ConstantInt(cast<llvm::ConstantInt>(LLVMC), *this));
307 return It->second.get();
308 case llvm::Value::ConstantFPVal:
309 It->second = std::unique_ptr<ConstantFP>(
310 new ConstantFP(cast<llvm::ConstantFP>(LLVMC), *this));
311 return It->second.get();
312 case llvm::Value::BlockAddressVal:
313 It->second = std::unique_ptr<BlockAddress>(
314 new BlockAddress(cast<llvm::BlockAddress>(LLVMC), *this));
315 return It->second.get();
316 case llvm::Value::ConstantTokenNoneVal:
317 It->second = std::unique_ptr<ConstantTokenNone>(
319 return It->second.get();
320 case llvm::Value::ConstantAggregateZeroVal: {
321 auto *CAZ = cast<llvm::ConstantAggregateZero>(LLVMC);
322 It->second = std::unique_ptr<ConstantAggregateZero>(
323 new ConstantAggregateZero(CAZ, *this));
324 auto *Ret = It->second.get();
325 // Must create sandboxir for elements.
326 auto EC = CAZ->getElementCount();
327 if (EC.isFixed()) {
328 for (auto ElmIdx : seq<unsigned>(0, EC.getFixedValue()))
329 getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ);
330 }
331 return Ret;
332 }
333 case llvm::Value::ConstantPointerNullVal:
334 It->second = std::unique_ptr<ConstantPointerNull>(new ConstantPointerNull(
335 cast<llvm::ConstantPointerNull>(LLVMC), *this));
336 return It->second.get();
337 case llvm::Value::PoisonValueVal:
338 It->second = std::unique_ptr<PoisonValue>(
339 new PoisonValue(cast<llvm::PoisonValue>(LLVMC), *this));
340 return It->second.get();
341 case llvm::Value::UndefValueVal:
342 It->second = std::unique_ptr<UndefValue>(
343 new UndefValue(cast<llvm::UndefValue>(LLVMC), *this));
344 return It->second.get();
345 case llvm::Value::DSOLocalEquivalentVal: {
346 auto *DSOLE = cast<llvm::DSOLocalEquivalent>(LLVMC);
347 It->second = std::unique_ptr<DSOLocalEquivalent>(
348 new DSOLocalEquivalent(DSOLE, *this));
349 auto *Ret = It->second.get();
350 getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE);
351 return Ret;
352 }
353 case llvm::Value::ConstantArrayVal:
354 It->second = std::unique_ptr<ConstantArray>(
355 new ConstantArray(cast<llvm::ConstantArray>(LLVMC), *this));
356 break;
357 case llvm::Value::ConstantStructVal:
358 It->second = std::unique_ptr<ConstantStruct>(
359 new ConstantStruct(cast<llvm::ConstantStruct>(LLVMC), *this));
360 break;
361 case llvm::Value::ConstantVectorVal:
362 It->second = std::unique_ptr<ConstantVector>(
363 new ConstantVector(cast<llvm::ConstantVector>(LLVMC), *this));
364 break;
365 case llvm::Value::ConstantDataArrayVal:
366 It->second = std::unique_ptr<ConstantDataArray>(
368 break;
369 case llvm::Value::ConstantDataVectorVal:
370 It->second = std::unique_ptr<ConstantDataVector>(
372 break;
373 case llvm::Value::FunctionVal:
374 It->second = std::unique_ptr<Function>(
375 new Function(cast<llvm::Function>(LLVMC), *this));
376 break;
377 case llvm::Value::GlobalIFuncVal:
378 It->second = std::unique_ptr<GlobalIFunc>(
379 new GlobalIFunc(cast<llvm::GlobalIFunc>(LLVMC), *this));
380 break;
381 case llvm::Value::GlobalVariableVal:
382 It->second = std::unique_ptr<GlobalVariable>(
383 new GlobalVariable(cast<llvm::GlobalVariable>(LLVMC), *this));
384 break;
385 case llvm::Value::GlobalAliasVal:
386 It->second = std::unique_ptr<GlobalAlias>(
387 new GlobalAlias(cast<llvm::GlobalAlias>(LLVMC), *this));
388 break;
389 case llvm::Value::NoCFIValueVal:
390 It->second = std::unique_ptr<NoCFIValue>(
391 new NoCFIValue(cast<llvm::NoCFIValue>(LLVMC), *this));
392 break;
393 case llvm::Value::ConstantPtrAuthVal:
394 It->second = std::unique_ptr<ConstantPtrAuth>(
396 break;
397 case llvm::Value::ConstantExprVal:
398 It->second = std::unique_ptr<ConstantExpr>(
399 new ConstantExpr(cast<llvm::ConstantExpr>(LLVMC), *this));
400 break;
401 default:
402 It->second = std::unique_ptr<Constant>(new Constant(LLVMC, *this));
403 break;
404 }
405 auto *NewC = It->second.get();
406 for (llvm::Value *COp : LLVMC->operands())
407 getOrCreateValueInternal(COp, LLVMC);
408 return NewC;
409 }
410 // Argument
411 if (auto *LLVMArg = dyn_cast<llvm::Argument>(LLVMV)) {
412 It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
413 return It->second.get();
414 }
415 // BasicBlock
416 if (auto *LLVMBB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
418 "This won't create a SBBB, don't call this function directly!");
419 if (auto *SBBB = getValue(LLVMBB))
420 return SBBB;
421 return nullptr;
422 }
423 // Metadata
424 if (auto *LLVMMD = dyn_cast<llvm::MetadataAsValue>(LLVMV)) {
425 It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(LLVMMD, *this));
426 return It->second.get();
427 }
428 // InlineAsm
429 if (auto *LLVMAsm = dyn_cast<llvm::InlineAsm>(LLVMV)) {
430 It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(LLVMAsm, *this));
431 return It->second.get();
432 }
433 llvm_unreachable("Unhandled LLVMV type!");
434}
435
437 auto Pair = LLVMValueToValueMap.try_emplace(LLVMArg);
438 auto It = Pair.first;
439 if (Pair.second) {
440 It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
441 return cast<Argument>(It->second.get());
442 }
443 return cast<Argument>(It->second.get());
444}
445
449
451 assert(getValue(LLVMBB) == nullptr && "Already exists!");
452 auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
453 auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
454 // Create SandboxIR for BB's body.
455 BB->buildBasicBlockFromLLVMIR(LLVMBB);
456 return BB;
457}
458
460 auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this));
461 return cast<VAArgInst>(registerValue(std::move(NewPtr)));
462}
463
465 auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this));
466 return cast<FreezeInst>(registerValue(std::move(NewPtr)));
467}
468
470 auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this));
471 return cast<FenceInst>(registerValue(std::move(NewPtr)));
472}
473
475 auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
476 return cast<SelectInst>(registerValue(std::move(NewPtr)));
477}
478
481 auto NewPtr =
482 std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
483 return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
484}
485
488 auto NewPtr =
489 std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
490 return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
491}
492
495 auto NewPtr =
496 std::unique_ptr<ShuffleVectorInst>(new ShuffleVectorInst(SVI, *this));
497 return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
498}
499
501 auto NewPtr =
502 std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this));
503 return cast<ExtractValueInst>(registerValue(std::move(NewPtr)));
504}
505
507 auto NewPtr =
508 std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
509 return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
510}
511
513 auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
514 return cast<BranchInst>(registerValue(std::move(NewPtr)));
515}
516
518 auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
519 return cast<LoadInst>(registerValue(std::move(NewPtr)));
520}
521
523 auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
524 return cast<StoreInst>(registerValue(std::move(NewPtr)));
525}
526
528 auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
529 return cast<ReturnInst>(registerValue(std::move(NewPtr)));
530}
531
533 auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
534 return cast<CallInst>(registerValue(std::move(NewPtr)));
535}
536
538 auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
539 return cast<InvokeInst>(registerValue(std::move(NewPtr)));
540}
541
543 auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
544 return cast<CallBrInst>(registerValue(std::move(NewPtr)));
545}
546
548 auto NewPtr =
549 std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
550 return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
551}
553 auto NewPtr = std::unique_ptr<LandingPadInst>(new LandingPadInst(I, *this));
554 return cast<LandingPadInst>(registerValue(std::move(NewPtr)));
555}
557 auto NewPtr = std::unique_ptr<CatchPadInst>(new CatchPadInst(I, *this));
558 return cast<CatchPadInst>(registerValue(std::move(NewPtr)));
559}
561 auto NewPtr = std::unique_ptr<CleanupPadInst>(new CleanupPadInst(I, *this));
562 return cast<CleanupPadInst>(registerValue(std::move(NewPtr)));
563}
565 auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
566 return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
567}
570 auto NewPtr =
571 std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this));
572 return cast<CleanupReturnInst>(registerValue(std::move(NewPtr)));
573}
576 auto NewPtr =
577 std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
578 return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
579}
581 auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
582 return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
583}
585 auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this));
586 return cast<ResumeInst>(registerValue(std::move(NewPtr)));
587}
589 auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
590 return cast<SwitchInst>(registerValue(std::move(NewPtr)));
591}
593 auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this));
594 return cast<UnaryOperator>(registerValue(std::move(NewPtr)));
595}
597 auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this));
598 return cast<BinaryOperator>(registerValue(std::move(NewPtr)));
599}
601 auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this));
602 return cast<AtomicRMWInst>(registerValue(std::move(NewPtr)));
603}
606 auto NewPtr =
607 std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
608 return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
609}
611 auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
612 return cast<AllocaInst>(registerValue(std::move(NewPtr)));
613}
615 auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
616 return cast<CastInst>(registerValue(std::move(NewPtr)));
617}
619 auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
620 return cast<PHINode>(registerValue(std::move(NewPtr)));
621}
623 auto NewPtr = std::unique_ptr<ICmpInst>(new ICmpInst(I, *this));
624 return cast<ICmpInst>(registerValue(std::move(NewPtr)));
625}
627 auto NewPtr = std::unique_ptr<FCmpInst>(new FCmpInst(I, *this));
628 return cast<FCmpInst>(registerValue(std::move(NewPtr)));
629}
631 auto It = LLVMValueToValueMap.find(V);
632 if (It != LLVMValueToValueMap.end())
633 return It->second.get();
634 return nullptr;
635}
636
640
641Context::~Context() = default;
642
644 // TODO: Ideally we should clear only function-scope objects, and keep global
645 // objects, like Constants to avoid recreating them.
646 LLVMValueToValueMap.clear();
647}
648
650 auto It = LLVMModuleToModuleMap.find(LLVMM);
651 if (It != LLVMModuleToModuleMap.end())
652 return It->second.get();
653 return nullptr;
654}
655
657 auto Pair = LLVMModuleToModuleMap.try_emplace(LLVMM);
658 auto It = Pair.first;
659 if (!Pair.second)
660 return It->second.get();
661 It->second = std::unique_ptr<Module>(new Module(*LLVMM, *this));
662 return It->second.get();
663}
664
666 // Create the module if needed before we create the new sandboxir::Function.
667 // Note: this won't fully populate the module. The only globals that will be
668 // available will be the ones being used within the function.
669 getOrCreateModule(F->getParent());
670
671 // There may be a function declaration already defined. Regardless destroy it.
672 if (Function *ExistingF = cast_or_null<Function>(getValue(F)))
673 detach(ExistingF);
674
675 auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
676 auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
677 // Create arguments.
678 for (auto &Arg : F->args())
680 // Create BBs.
681 for (auto &BB : *F)
682 createBasicBlock(&BB);
683 return SBF;
684}
685
687 auto *M = getOrCreateModule(LLVMM);
688 // Create the functions.
689 for (auto &LLVMF : *LLVMM)
690 createFunction(&LLVMF);
691 // Create globals.
692 for (auto &Global : LLVMM->globals())
694 // Create aliases.
695 for (auto &Alias : LLVMM->aliases())
696 getOrCreateValue(&Alias);
697 // Create ifuncs.
698 for (auto &IFunc : LLVMM->ifuncs())
699 getOrCreateValue(&IFunc);
700
701 return M;
702}
703
705 for (const auto &CBEntry : EraseInstrCallbacks)
706 CBEntry.second(I);
707}
708
710 for (auto &CBEntry : CreateInstrCallbacks)
711 CBEntry.second(I);
712}
713
714void Context::runMoveInstrCallbacks(Instruction *I, const BBIterator &WhereIt) {
715 for (auto &CBEntry : MoveInstrCallbacks)
716 CBEntry.second(I, WhereIt);
717}
718
719void Context::runSetUseCallbacks(const Use &U, Value *NewSrc) {
720 for (auto &CBEntry : SetUseCallbacks)
721 CBEntry.second(U, NewSrc);
722}
723
724// An arbitrary limit, to check for accidental misuse. We expect a small number
725// of callbacks to be registered at a time, but we can increase this number if
726// we discover we needed more.
727[[maybe_unused]] static constexpr int MaxRegisteredCallbacks = 16;
728
731 "EraseInstrCallbacks size limit exceeded");
733 EraseInstrCallbacks[ID] = std::move(CB);
734 return ID;
735}
737 [[maybe_unused]] bool Erased = EraseInstrCallbacks.erase(ID);
738 assert(Erased &&
739 "Callback ID not found in EraseInstrCallbacks during deregistration");
740}
741
745 "CreateInstrCallbacks size limit exceeded");
747 CreateInstrCallbacks[ID] = std::move(CB);
748 return ID;
749}
751 [[maybe_unused]] bool Erased = CreateInstrCallbacks.erase(ID);
752 assert(Erased &&
753 "Callback ID not found in CreateInstrCallbacks during deregistration");
754}
755
758 "MoveInstrCallbacks size limit exceeded");
760 MoveInstrCallbacks[ID] = std::move(CB);
761 return ID;
762}
764 [[maybe_unused]] bool Erased = MoveInstrCallbacks.erase(ID);
765 assert(Erased &&
766 "Callback ID not found in MoveInstrCallbacks during deregistration");
767}
768
771 "SetUseCallbacks size limit exceeded");
773 SetUseCallbacks[ID] = std::move(CB);
774 return ID;
775}
777 [[maybe_unused]] bool Erased = SetUseCallbacks.erase(ID);
778 assert(Erased &&
779 "Callback ID not found in SetUseCallbacks during deregistration");
780}
781
782} // namespace llvm::sandboxir
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Conditional or Unconditional Branch instruction.
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:448
ConstantFolder - Create constants with minimum, target independent, folding.
This is an important base class in LLVM.
Definition Constant.h:43
This instruction extracts a single (scalar) element from a VectorType value.
This instruction extracts a struct member or array element value from an aggregate value.
This instruction compares its operands according to the predicate given to the constructor.
An instruction for ordering other memory operations.
This class represents a freeze function that returns random concrete value if an operand is either a ...
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This instruction compares its operands according to the predicate given to the constructor.
This instruction inserts a single (scalar) element into a VectorType value.
This instruction inserts a struct field of array element value into an aggregate value.
Invoke instruction.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
The landingpad instruction holds all of the information necessary to generate correct exception handl...
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
iterator_range< ifunc_iterator > ifuncs()
Definition Module.h:753
iterator_range< alias_iterator > aliases()
Definition Module.h:735
iterator_range< global_iterator > globals()
Definition Module.h:684
Resume the propagation of an exception.
Return a value (possibly void), from a function.
This class represents the LLVM 'select' instruction.
This instruction constructs a fixed permutation of two input vectors.
An instruction for storing to memory.
Multiway switch.
This function has undefined behavior.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
Definition Value.h:75
Argument of a sandboxir::Function.
Definition Argument.h:18
A vector constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
Definition Constant.h:669
An ID for a registered callback.
Definition Context.h:49
LLVM_ABI BasicBlock * createBasicBlock(llvm::BasicBlock *BB)
Create a sandboxir::BasicBlock for an existing LLVM IR BB.
Definition Context.cpp:450
std::function< void(Instruction *)> CreateInstrCallback
Definition Context.h:38
LLVM_ABI GetElementPtrInst * createGetElementPtrInst(llvm::GetElementPtrInst *I)
Definition Context.cpp:575
MapVector< CallbackID, CreateInstrCallback > CreateInstrCallbacks
Callbacks called when an IR instruction is about to get created.
Definition Context.h:102
LLVM_ABI CallBrInst * createCallBrInst(llvm::CallBrInst *I)
Definition Context.cpp:542
LLVM_ABI Module * createModule(llvm::Module *LLVMM)
Create a sandboxir::Module corresponding to LLVMM.
Definition Context.cpp:686
IRBuilder< ConstantFolder > LLVMIRBuilder
Definition Context.h:156
std::function< void(const Use &, Value *)> SetUseCallback
Definition Context.h:44
MapVector< CallbackID, EraseInstrCallback > EraseInstrCallbacks
Callbacks called when an IR instruction is about to get erased.
Definition Context.h:99
LLVM_ABI sandboxir::Value * getValue(llvm::Value *V) const
Definition Context.cpp:630
LLVM_ABI Argument * getOrCreateArgument(llvm::Argument *LLVMArg)
Get or create a sandboxir::Argument for an existing LLVM IR LLVMArg.
Definition Context.cpp:436
LLVM_ABI void unregisterSetUseCallback(CallbackID ID)
Definition Context.cpp:776
LLVM_ABI ReturnInst * createReturnInst(llvm::ReturnInst *I)
Definition Context.cpp:527
LLVM_ABI void runEraseInstrCallbacks(Instruction *I)
Definition Context.cpp:704
LLVM_ABI Module * getModule(llvm::Module *LLVMM) const
Definition Context.cpp:649
LLVM_ABI VAArgInst * createVAArgInst(llvm::VAArgInst *SI)
Definition Context.cpp:459
LLVM_ABI CleanupReturnInst * createCleanupReturnInst(llvm::CleanupReturnInst *I)
Definition Context.cpp:569
LLVM_ABI AllocaInst * createAllocaInst(llvm::AllocaInst *I)
Definition Context.cpp:610
LLVM_ABI void runCreateInstrCallbacks(Instruction *I)
Definition Context.cpp:709
LLVM_ABI AtomicRMWInst * createAtomicRMWInst(llvm::AtomicRMWInst *I)
Definition Context.cpp:600
LLVM_ABI InsertValueInst * createInsertValueInst(llvm::InsertValueInst *IVI)
Definition Context.cpp:506
LLVM_ABI FCmpInst * createFCmpInst(llvm::FCmpInst *I)
Definition Context.cpp:626
std::function< void(Instruction *)> EraseInstrCallback
Definition Context.h:36
CallbackID::ValTy NextCallbackID
A counter used for assigning callback IDs during registration.
Definition Context.h:113
LLVM_ABI ExtractElementInst * createExtractElementInst(llvm::ExtractElementInst *EEI)
Definition Context.cpp:480
LLVM_ABI Constant * getOrCreateConstant(llvm::Constant *LLVMC)
Get or create a sandboxir::Constant from an existing LLVM IR LLVMC.
Definition Context.cpp:446
LLVM_ABI CallbackID registerSetUseCallback(SetUseCallback CB)
Register a callback that gets called when a Use gets set.
Definition Context.cpp:769
LLVM_ABI BranchInst * createBranchInst(llvm::BranchInst *I)
Definition Context.cpp:512
LLVM_ABI ShuffleVectorInst * createShuffleVectorInst(llvm::ShuffleVectorInst *SVI)
Definition Context.cpp:494
LLVM_ABI BinaryOperator * createBinaryOperator(llvm::BinaryOperator *I)
Definition Context.cpp:596
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition Context.h:120
LLVM_ABI Module * getOrCreateModule(llvm::Module *LLVMM)
Definition Context.cpp:656
LLVM_ABI LoadInst * createLoadInst(llvm::LoadInst *LI)
Definition Context.cpp:517
DenseMap< llvm::Value *, std::unique_ptr< Value > > LLVMValueToValueMap
Maps LLVM Value to the corresponding sandboxir::Value.
Definition Context.h:82
LLVM_ABI FreezeInst * createFreezeInst(llvm::FreezeInst *SI)
Definition Context.cpp:464
LLVM_ABI PHINode * createPHINode(llvm::PHINode *I)
Definition Context.cpp:618
LLVM_ABI CallbackID registerCreateInstrCallback(CreateInstrCallback CB)
Register a callback that gets called right after a SandboxIR instruction is created.
Definition Context.cpp:743
LLVM_ABI Context(LLVMContext &LLVMCtx)
Definition Context.cpp:637
LLVM_ABI CatchPadInst * createCatchPadInst(llvm::CatchPadInst *I)
Definition Context.cpp:556
LLVM_ABI void clear()
Clears function-level state.
Definition Context.cpp:643
LLVM_ABI ICmpInst * createICmpInst(llvm::ICmpInst *I)
Definition Context.cpp:622
MapVector< CallbackID, MoveInstrCallback > MoveInstrCallbacks
Callbacks called when an IR instruction is about to get moved.
Definition Context.h:105
LLVM_ABI std::unique_ptr< Value > detach(Value *V)
Remove SBV from all SandboxIR maps and stop owning it.
Definition Context.cpp:28
LLVM_ABI void unregisterCreateInstrCallback(CallbackID ID)
Definition Context.cpp:750
LLVM_ABI ExtractValueInst * createExtractValueInst(llvm::ExtractValueInst *IVI)
Definition Context.cpp:500
LLVM_ABI CastInst * createCastInst(llvm::CastInst *I)
Definition Context.cpp:614
DenseMap< llvm::Module *, std::unique_ptr< Module > > LLVMModuleToModuleMap
Maps an LLVM Module to the corresponding sandboxir::Module.
Definition Context.h:85
LLVM_ABI StoreInst * createStoreInst(llvm::StoreInst *SI)
Definition Context.cpp:522
LLVM_ABI CatchReturnInst * createCatchReturnInst(llvm::CatchReturnInst *I)
Definition Context.cpp:564
LLVM_ABI CatchSwitchInst * createCatchSwitchInst(llvm::CatchSwitchInst *I)
Definition Context.cpp:580
std::function< void(Instruction *, const BBIterator &)> MoveInstrCallback
Definition Context.h:41
LLVM_ABI void unregisterMoveInstrCallback(CallbackID ID)
Definition Context.cpp:763
LLVM_ABI CleanupPadInst * createCleanupPadInst(llvm::CleanupPadInst *I)
Definition Context.cpp:560
Value * getOrCreateValue(llvm::Value *LLVMV)
Get or create a sandboxir::Value for an existing LLVM IR LLVMV.
Definition Context.h:131
LLVM_ABI FenceInst * createFenceInst(llvm::FenceInst *SI)
Definition Context.cpp:469
LLVM_ABI CallInst * createCallInst(llvm::CallInst *I)
Definition Context.cpp:532
LLVM_ABI SwitchInst * createSwitchInst(llvm::SwitchInst *I)
Definition Context.cpp:588
LLVM_ABI void runMoveInstrCallbacks(Instruction *I, const BBIterator &Where)
Definition Context.cpp:714
LLVM_ABI UnaryOperator * createUnaryOperator(llvm::UnaryOperator *I)
Definition Context.cpp:592
LLVM_ABI Value * getOrCreateValueInternal(llvm::Value *V, llvm::User *U=nullptr)
This is the actual function that creates sandboxir values for V, and among others handles all instruc...
Definition Context.cpp:56
LLVM_ABI InvokeInst * createInvokeInst(llvm::InvokeInst *I)
Definition Context.cpp:537
LLVM_ABI Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
Definition Context.cpp:35
LLVM_ABI LandingPadInst * createLandingPadInst(llvm::LandingPadInst *I)
Definition Context.cpp:552
LLVM_ABI InsertElementInst * createInsertElementInst(llvm::InsertElementInst *IEI)
Definition Context.cpp:487
LLVM_ABI Function * createFunction(llvm::Function *F)
Create a sandboxir::Function for an existing LLVM IR F, including all blocks and instructions.
Definition Context.cpp:665
LLVM_ABI SelectInst * createSelectInst(llvm::SelectInst *SI)
Definition Context.cpp:474
LLVM_ABI ResumeInst * createResumeInst(llvm::ResumeInst *I)
Definition Context.cpp:584
LLVM_ABI void unregisterEraseInstrCallback(CallbackID ID)
Definition Context.cpp:736
LLVMContext & LLVMCtx
Definition Context.h:70
MapVector< CallbackID, SetUseCallback > SetUseCallbacks
Callbacks called when a Use gets its source set.
Definition Context.h:108
Tracker & getTracker()
Definition Context.h:245
friend class BasicBlock
Various leaf nodes.
Definition Context.h:154
LLVM_ABI CallbackID registerMoveInstrCallback(MoveInstrCallback CB)
Register a callback that gets called when a SandboxIR instruction is about to be moved.
Definition Context.cpp:756
LLVM_ABI UnreachableInst * createUnreachableInst(llvm::UnreachableInst *UI)
Definition Context.cpp:547
LLVM_ABI AtomicCmpXchgInst * createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I)
Definition Context.cpp:605
LLVM_ABI void runSetUseCallbacks(const Use &U, Value *NewSrc)
Definition Context.cpp:719
LLVM_ABI CallbackID registerEraseInstrCallback(EraseInstrCallback CB)
Register a callback that gets called when a SandboxIR instruction is about to be removed from its par...
Definition Context.cpp:729
LLVM_ABI std::unique_ptr< Value > detachLLVMValue(llvm::Value *V)
Remove V from the maps and returns the unique_ptr.
Definition Context.cpp:17
In SandboxIR the Module is mainly used to access the list of global objects.
Definition Module.h:32
An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to an OpaqueInstr.
bool emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
Definition Tracker.h:500
Represents a Def-use/Use-def edge in SandboxIR.
Definition Use.h:33
@ LLVMCallBr
Definition Core.h:72
@ LLVMAtomicRMW
Definition Core.h:140
@ LLVMUnreachable
Definition Core.h:71
@ LLVMCall
Definition Core.h:125
@ LLVMICmp
Definition Core.h:122
@ LLVMRet
Definition Core.h:63
@ LLVMFreeze
Definition Core.h:135
@ LLVMInvoke
Definition Core.h:69
@ LLVMFence
Definition Core.h:138
@ LLVMVAArg
Definition Core.h:129
@ LLVMFCmp
Definition Core.h:123
@ LLVMAlloca
Definition Core.h:100
@ LLVMAtomicCmpXchg
Definition Core.h:139
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
static constexpr int MaxRegisteredCallbacks
Definition Context.cpp:727
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto cast_or_null(const Y &Val)
Definition Casting.h:714
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ Global
Append to llvm.global_dtors.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305