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 auto *LLVMBr = cast<llvm::UncondBrInst>(LLVMV);
118 It->second =
119 std::unique_ptr<UncondBrInst>(new UncondBrInst(LLVMBr, *this));
120 return It->second.get();
121 }
122 case llvm::Instruction::CondBr: {
123 auto *LLVMBr = cast<llvm::CondBrInst>(LLVMV);
124 It->second = std::unique_ptr<CondBrInst>(new CondBrInst(LLVMBr, *this));
125 return It->second.get();
126 }
127 case llvm::Instruction::Load: {
128 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
129 It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
130 return It->second.get();
131 }
132 case llvm::Instruction::Store: {
133 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
134 It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
135 return It->second.get();
136 }
137 case llvm::Instruction::Ret: {
138 auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
139 It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
140 return It->second.get();
141 }
142 case llvm::Instruction::Call: {
143 auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
144 It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
145 return It->second.get();
146 }
147 case llvm::Instruction::Invoke: {
148 auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
149 It->second =
150 std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
151 return It->second.get();
152 }
153 case llvm::Instruction::CallBr: {
154 auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
155 It->second =
156 std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
157 return It->second.get();
158 }
159 case llvm::Instruction::LandingPad: {
160 auto *LLVMLPad = cast<llvm::LandingPadInst>(LLVMV);
161 It->second =
162 std::unique_ptr<LandingPadInst>(new LandingPadInst(LLVMLPad, *this));
163 return It->second.get();
164 }
165 case llvm::Instruction::CatchPad: {
166 auto *LLVMCPI = cast<llvm::CatchPadInst>(LLVMV);
167 It->second =
168 std::unique_ptr<CatchPadInst>(new CatchPadInst(LLVMCPI, *this));
169 return It->second.get();
170 }
171 case llvm::Instruction::CleanupPad: {
172 auto *LLVMCPI = cast<llvm::CleanupPadInst>(LLVMV);
173 It->second =
174 std::unique_ptr<CleanupPadInst>(new CleanupPadInst(LLVMCPI, *this));
175 return It->second.get();
176 }
177 case llvm::Instruction::CatchRet: {
178 auto *LLVMCRI = cast<llvm::CatchReturnInst>(LLVMV);
179 It->second =
180 std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
181 return It->second.get();
182 }
183 case llvm::Instruction::CleanupRet: {
184 auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV);
185 It->second = std::unique_ptr<CleanupReturnInst>(
186 new CleanupReturnInst(LLVMCRI, *this));
187 return It->second.get();
188 }
189 case llvm::Instruction::GetElementPtr: {
190 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
191 It->second = std::unique_ptr<GetElementPtrInst>(
192 new GetElementPtrInst(LLVMGEP, *this));
193 return It->second.get();
194 }
195 case llvm::Instruction::CatchSwitch: {
196 auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV);
197 It->second = std::unique_ptr<CatchSwitchInst>(
198 new CatchSwitchInst(LLVMCatchSwitchInst, *this));
199 return It->second.get();
200 }
201 case llvm::Instruction::Resume: {
202 auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV);
203 It->second =
204 std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this));
205 return It->second.get();
206 }
207 case llvm::Instruction::Switch: {
208 auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
209 It->second =
210 std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this));
211 return It->second.get();
212 }
213 case llvm::Instruction::FNeg: {
214 auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
215 It->second = std::unique_ptr<UnaryOperator>(
216 new UnaryOperator(LLVMUnaryOperator, *this));
217 return It->second.get();
218 }
219 case llvm::Instruction::Add:
220 case llvm::Instruction::FAdd:
221 case llvm::Instruction::Sub:
222 case llvm::Instruction::FSub:
223 case llvm::Instruction::Mul:
224 case llvm::Instruction::FMul:
225 case llvm::Instruction::UDiv:
226 case llvm::Instruction::SDiv:
227 case llvm::Instruction::FDiv:
228 case llvm::Instruction::URem:
229 case llvm::Instruction::SRem:
230 case llvm::Instruction::FRem:
231 case llvm::Instruction::Shl:
232 case llvm::Instruction::LShr:
233 case llvm::Instruction::AShr:
234 case llvm::Instruction::And:
235 case llvm::Instruction::Or:
236 case llvm::Instruction::Xor: {
237 auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
238 It->second = std::unique_ptr<BinaryOperator>(
239 new BinaryOperator(LLVMBinaryOperator, *this));
240 return It->second.get();
241 }
242 case llvm::Instruction::AtomicRMW: {
244 It->second = std::unique_ptr<AtomicRMWInst>(
245 new AtomicRMWInst(LLVMAtomicRMW, *this));
246 return It->second.get();
247 }
248 case llvm::Instruction::AtomicCmpXchg: {
250 It->second = std::unique_ptr<AtomicCmpXchgInst>(
252 return It->second.get();
253 }
254 case llvm::Instruction::Alloca: {
255 auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
256 It->second =
257 std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
258 return It->second.get();
259 }
260 case llvm::Instruction::ZExt:
261 case llvm::Instruction::SExt:
262 case llvm::Instruction::FPToUI:
263 case llvm::Instruction::FPToSI:
264 case llvm::Instruction::FPExt:
265 case llvm::Instruction::PtrToAddr:
266 case llvm::Instruction::PtrToInt:
267 case llvm::Instruction::IntToPtr:
268 case llvm::Instruction::SIToFP:
269 case llvm::Instruction::UIToFP:
270 case llvm::Instruction::Trunc:
271 case llvm::Instruction::FPTrunc:
272 case llvm::Instruction::BitCast:
273 case llvm::Instruction::AddrSpaceCast: {
274 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
275 It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
276 return It->second.get();
277 }
278 case llvm::Instruction::PHI: {
279 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
280 It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
281 return It->second.get();
282 }
283 case llvm::Instruction::ICmp: {
284 auto *LLVMICmp = cast<llvm::ICmpInst>(LLVMV);
285 It->second = std::unique_ptr<ICmpInst>(new ICmpInst(LLVMICmp, *this));
286 return It->second.get();
287 }
288 case llvm::Instruction::FCmp: {
289 auto *LLVMFCmp = cast<llvm::FCmpInst>(LLVMV);
290 It->second = std::unique_ptr<FCmpInst>(new FCmpInst(LLVMFCmp, *this));
291 return It->second.get();
292 }
293 case llvm::Instruction::Unreachable: {
295 It->second = std::unique_ptr<UnreachableInst>(
296 new UnreachableInst(LLVMUnreachable, *this));
297 return It->second.get();
298 }
299 default:
300 break;
301 }
302 It->second = std::unique_ptr<OpaqueInst>(
303 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
304 return It->second.get();
305 }
306 // Constant
307 if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV)) {
308 switch (LLVMC->getValueID()) {
309 case llvm::Value::ConstantIntVal:
310 It->second = std::unique_ptr<ConstantInt>(
311 new ConstantInt(cast<llvm::ConstantInt>(LLVMC), *this));
312 return It->second.get();
313 case llvm::Value::ConstantFPVal:
314 It->second = std::unique_ptr<ConstantFP>(
315 new ConstantFP(cast<llvm::ConstantFP>(LLVMC), *this));
316 return It->second.get();
317 case llvm::Value::BlockAddressVal:
318 It->second = std::unique_ptr<BlockAddress>(
319 new BlockAddress(cast<llvm::BlockAddress>(LLVMC), *this));
320 return It->second.get();
321 case llvm::Value::ConstantTokenNoneVal:
322 It->second = std::unique_ptr<ConstantTokenNone>(
324 return It->second.get();
325 case llvm::Value::ConstantAggregateZeroVal: {
326 auto *CAZ = cast<llvm::ConstantAggregateZero>(LLVMC);
327 It->second = std::unique_ptr<ConstantAggregateZero>(
328 new ConstantAggregateZero(CAZ, *this));
329 auto *Ret = It->second.get();
330 // Must create sandboxir for elements.
331 auto EC = CAZ->getElementCount();
332 if (EC.isFixed()) {
333 for (auto ElmIdx : seq<unsigned>(0, EC.getFixedValue()))
334 getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ);
335 }
336 return Ret;
337 }
338 case llvm::Value::ConstantPointerNullVal:
339 It->second = std::unique_ptr<ConstantPointerNull>(new ConstantPointerNull(
340 cast<llvm::ConstantPointerNull>(LLVMC), *this));
341 return It->second.get();
342 case llvm::Value::PoisonValueVal:
343 It->second = std::unique_ptr<PoisonValue>(
344 new PoisonValue(cast<llvm::PoisonValue>(LLVMC), *this));
345 return It->second.get();
346 case llvm::Value::UndefValueVal:
347 It->second = std::unique_ptr<UndefValue>(
348 new UndefValue(cast<llvm::UndefValue>(LLVMC), *this));
349 return It->second.get();
350 case llvm::Value::DSOLocalEquivalentVal: {
351 auto *DSOLE = cast<llvm::DSOLocalEquivalent>(LLVMC);
352 It->second = std::unique_ptr<DSOLocalEquivalent>(
353 new DSOLocalEquivalent(DSOLE, *this));
354 auto *Ret = It->second.get();
355 getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE);
356 return Ret;
357 }
358 case llvm::Value::ConstantArrayVal:
359 It->second = std::unique_ptr<ConstantArray>(
360 new ConstantArray(cast<llvm::ConstantArray>(LLVMC), *this));
361 break;
362 case llvm::Value::ConstantStructVal:
363 It->second = std::unique_ptr<ConstantStruct>(
364 new ConstantStruct(cast<llvm::ConstantStruct>(LLVMC), *this));
365 break;
366 case llvm::Value::ConstantVectorVal:
367 It->second = std::unique_ptr<ConstantVector>(
368 new ConstantVector(cast<llvm::ConstantVector>(LLVMC), *this));
369 break;
370 case llvm::Value::ConstantDataArrayVal:
371 It->second = std::unique_ptr<ConstantDataArray>(
373 break;
374 case llvm::Value::ConstantDataVectorVal:
375 It->second = std::unique_ptr<ConstantDataVector>(
377 break;
378 case llvm::Value::FunctionVal:
379 It->second = std::unique_ptr<Function>(
380 new Function(cast<llvm::Function>(LLVMC), *this));
381 break;
382 case llvm::Value::GlobalIFuncVal:
383 It->second = std::unique_ptr<GlobalIFunc>(
384 new GlobalIFunc(cast<llvm::GlobalIFunc>(LLVMC), *this));
385 break;
386 case llvm::Value::GlobalVariableVal:
387 It->second = std::unique_ptr<GlobalVariable>(
388 new GlobalVariable(cast<llvm::GlobalVariable>(LLVMC), *this));
389 break;
390 case llvm::Value::GlobalAliasVal:
391 It->second = std::unique_ptr<GlobalAlias>(
392 new GlobalAlias(cast<llvm::GlobalAlias>(LLVMC), *this));
393 break;
394 case llvm::Value::NoCFIValueVal:
395 It->second = std::unique_ptr<NoCFIValue>(
396 new NoCFIValue(cast<llvm::NoCFIValue>(LLVMC), *this));
397 break;
398 case llvm::Value::ConstantPtrAuthVal:
399 It->second = std::unique_ptr<ConstantPtrAuth>(
401 break;
402 case llvm::Value::ConstantExprVal:
403 It->second = std::unique_ptr<ConstantExpr>(
404 new ConstantExpr(cast<llvm::ConstantExpr>(LLVMC), *this));
405 break;
406 default:
407 It->second = std::unique_ptr<Constant>(new Constant(LLVMC, *this));
408 break;
409 }
410 auto *NewC = It->second.get();
411 for (llvm::Value *COp : LLVMC->operands())
412 getOrCreateValueInternal(COp, LLVMC);
413 return NewC;
414 }
415 // Argument
416 if (auto *LLVMArg = dyn_cast<llvm::Argument>(LLVMV)) {
417 It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
418 return It->second.get();
419 }
420 // BasicBlock
421 if (auto *LLVMBB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
423 "This won't create a SBBB, don't call this function directly!");
424 if (auto *SBBB = getValue(LLVMBB))
425 return SBBB;
426 return nullptr;
427 }
428 // Metadata
429 if (auto *LLVMMD = dyn_cast<llvm::MetadataAsValue>(LLVMV)) {
430 It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(LLVMMD, *this));
431 return It->second.get();
432 }
433 // InlineAsm
434 if (auto *LLVMAsm = dyn_cast<llvm::InlineAsm>(LLVMV)) {
435 It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(LLVMAsm, *this));
436 return It->second.get();
437 }
438 llvm_unreachable("Unhandled LLVMV type!");
439}
440
442 auto Pair = LLVMValueToValueMap.try_emplace(LLVMArg);
443 auto It = Pair.first;
444 if (Pair.second) {
445 It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
446 return cast<Argument>(It->second.get());
447 }
448 return cast<Argument>(It->second.get());
449}
450
454
456 assert(getValue(LLVMBB) == nullptr && "Already exists!");
457 auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
458 auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
459 // Create SandboxIR for BB's body.
460 BB->buildBasicBlockFromLLVMIR(LLVMBB);
461 return BB;
462}
463
465 auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this));
466 return cast<VAArgInst>(registerValue(std::move(NewPtr)));
467}
468
470 auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this));
471 return cast<FreezeInst>(registerValue(std::move(NewPtr)));
472}
473
475 auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this));
476 return cast<FenceInst>(registerValue(std::move(NewPtr)));
477}
478
480 auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
481 return cast<SelectInst>(registerValue(std::move(NewPtr)));
482}
483
486 auto NewPtr =
487 std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
488 return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
489}
490
493 auto NewPtr =
494 std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
495 return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
496}
497
500 auto NewPtr =
501 std::unique_ptr<ShuffleVectorInst>(new ShuffleVectorInst(SVI, *this));
502 return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
503}
504
506 auto NewPtr =
507 std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this));
508 return cast<ExtractValueInst>(registerValue(std::move(NewPtr)));
509}
510
512 auto NewPtr =
513 std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
514 return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
515}
516
518 auto NewPtr = std::unique_ptr<UncondBrInst>(new UncondBrInst(UBI, *this));
519 return cast<UncondBrInst>(registerValue(std::move(NewPtr)));
520}
521
523 auto NewPtr = std::unique_ptr<CondBrInst>(new CondBrInst(CBI, *this));
524 return cast<CondBrInst>(registerValue(std::move(NewPtr)));
525}
526
528 auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
529 return cast<LoadInst>(registerValue(std::move(NewPtr)));
530}
531
533 auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
534 return cast<StoreInst>(registerValue(std::move(NewPtr)));
535}
536
538 auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
539 return cast<ReturnInst>(registerValue(std::move(NewPtr)));
540}
541
543 auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
544 return cast<CallInst>(registerValue(std::move(NewPtr)));
545}
546
548 auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
549 return cast<InvokeInst>(registerValue(std::move(NewPtr)));
550}
551
553 auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
554 return cast<CallBrInst>(registerValue(std::move(NewPtr)));
555}
556
558 auto NewPtr =
559 std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
560 return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
561}
563 auto NewPtr = std::unique_ptr<LandingPadInst>(new LandingPadInst(I, *this));
564 return cast<LandingPadInst>(registerValue(std::move(NewPtr)));
565}
567 auto NewPtr = std::unique_ptr<CatchPadInst>(new CatchPadInst(I, *this));
568 return cast<CatchPadInst>(registerValue(std::move(NewPtr)));
569}
571 auto NewPtr = std::unique_ptr<CleanupPadInst>(new CleanupPadInst(I, *this));
572 return cast<CleanupPadInst>(registerValue(std::move(NewPtr)));
573}
575 auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
576 return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
577}
580 auto NewPtr =
581 std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this));
582 return cast<CleanupReturnInst>(registerValue(std::move(NewPtr)));
583}
586 auto NewPtr =
587 std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
588 return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
589}
591 auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
592 return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
593}
595 auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this));
596 return cast<ResumeInst>(registerValue(std::move(NewPtr)));
597}
599 auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
600 return cast<SwitchInst>(registerValue(std::move(NewPtr)));
601}
603 auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this));
604 return cast<UnaryOperator>(registerValue(std::move(NewPtr)));
605}
607 auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this));
608 return cast<BinaryOperator>(registerValue(std::move(NewPtr)));
609}
611 auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this));
612 return cast<AtomicRMWInst>(registerValue(std::move(NewPtr)));
613}
616 auto NewPtr =
617 std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
618 return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
619}
621 auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
622 return cast<AllocaInst>(registerValue(std::move(NewPtr)));
623}
625 auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
626 return cast<CastInst>(registerValue(std::move(NewPtr)));
627}
629 auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
630 return cast<PHINode>(registerValue(std::move(NewPtr)));
631}
633 auto NewPtr = std::unique_ptr<ICmpInst>(new ICmpInst(I, *this));
634 return cast<ICmpInst>(registerValue(std::move(NewPtr)));
635}
637 auto NewPtr = std::unique_ptr<FCmpInst>(new FCmpInst(I, *this));
638 return cast<FCmpInst>(registerValue(std::move(NewPtr)));
639}
641 auto It = LLVMValueToValueMap.find(V);
642 if (It != LLVMValueToValueMap.end())
643 return It->second.get();
644 return nullptr;
645}
646
650
651Context::~Context() = default;
652
654 // TODO: Ideally we should clear only function-scope objects, and keep global
655 // objects, like Constants to avoid recreating them.
656 LLVMValueToValueMap.clear();
657}
658
660 auto It = LLVMModuleToModuleMap.find(LLVMM);
661 if (It != LLVMModuleToModuleMap.end())
662 return It->second.get();
663 return nullptr;
664}
665
667 auto Pair = LLVMModuleToModuleMap.try_emplace(LLVMM);
668 auto It = Pair.first;
669 if (!Pair.second)
670 return It->second.get();
671 It->second = std::unique_ptr<Module>(new Module(*LLVMM, *this));
672 return It->second.get();
673}
674
676 // Create the module if needed before we create the new sandboxir::Function.
677 // Note: this won't fully populate the module. The only globals that will be
678 // available will be the ones being used within the function.
679 getOrCreateModule(F->getParent());
680
681 // There may be a function declaration already defined. Regardless destroy it.
682 if (Function *ExistingF = cast_or_null<Function>(getValue(F)))
683 detach(ExistingF);
684
685 auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
686 auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
687 // Create arguments.
688 for (auto &Arg : F->args())
690 // Create BBs.
691 for (auto &BB : *F)
692 createBasicBlock(&BB);
693 return SBF;
694}
695
697 auto *M = getOrCreateModule(LLVMM);
698 // Create the functions.
699 for (auto &LLVMF : *LLVMM)
700 createFunction(&LLVMF);
701 // Create globals.
702 for (auto &Global : LLVMM->globals())
704 // Create aliases.
705 for (auto &Alias : LLVMM->aliases())
706 getOrCreateValue(&Alias);
707 // Create ifuncs.
708 for (auto &IFunc : LLVMM->ifuncs())
709 getOrCreateValue(&IFunc);
710
711 return M;
712}
713
715 for (const auto &CBEntry : EraseInstrCallbacks)
716 CBEntry.second(I);
717}
718
720 for (auto &CBEntry : CreateInstrCallbacks)
721 CBEntry.second(I);
722}
723
724void Context::runMoveInstrCallbacks(Instruction *I, const BBIterator &WhereIt) {
725 for (auto &CBEntry : MoveInstrCallbacks)
726 CBEntry.second(I, WhereIt);
727}
728
729void Context::runSetUseCallbacks(const Use &U, Value *NewSrc) {
730 for (auto &CBEntry : SetUseCallbacks)
731 CBEntry.second(U, NewSrc);
732}
733
734// An arbitrary limit, to check for accidental misuse. We expect a small number
735// of callbacks to be registered at a time, but we can increase this number if
736// we discover we needed more.
737[[maybe_unused]] static constexpr int MaxRegisteredCallbacks = 16;
738
741 "EraseInstrCallbacks size limit exceeded");
743 EraseInstrCallbacks[ID] = std::move(CB);
744 return ID;
745}
747 [[maybe_unused]] bool Erased = EraseInstrCallbacks.erase(ID);
748 assert(Erased &&
749 "Callback ID not found in EraseInstrCallbacks during deregistration");
750}
751
755 "CreateInstrCallbacks size limit exceeded");
757 CreateInstrCallbacks[ID] = std::move(CB);
758 return ID;
759}
761 [[maybe_unused]] bool Erased = CreateInstrCallbacks.erase(ID);
762 assert(Erased &&
763 "Callback ID not found in CreateInstrCallbacks during deregistration");
764}
765
768 "MoveInstrCallbacks size limit exceeded");
770 MoveInstrCallbacks[ID] = std::move(CB);
771 return ID;
772}
774 [[maybe_unused]] bool Erased = MoveInstrCallbacks.erase(ID);
775 assert(Erased &&
776 "Callback ID not found in MoveInstrCallbacks during deregistration");
777}
778
781 "SetUseCallbacks size limit exceeded");
783 SetUseCallbacks[ID] = std::move(CB);
784 return ID;
785}
787 [[maybe_unused]] bool Erased = SetUseCallbacks.erase(ID);
788 assert(Erased &&
789 "Callback ID not found in SetUseCallbacks during deregistration");
790}
791
792} // 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
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
Conditional Branch instruction.
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.
Unconditional Branch instruction.
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:455
std::function< void(Instruction *)> CreateInstrCallback
Definition Context.h:38
LLVM_ABI GetElementPtrInst * createGetElementPtrInst(llvm::GetElementPtrInst *I)
Definition Context.cpp:585
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:552
LLVM_ABI Module * createModule(llvm::Module *LLVMM)
Create a sandboxir::Module corresponding to LLVMM.
Definition Context.cpp:696
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:640
LLVM_ABI Argument * getOrCreateArgument(llvm::Argument *LLVMArg)
Get or create a sandboxir::Argument for an existing LLVM IR LLVMArg.
Definition Context.cpp:441
LLVM_ABI void unregisterSetUseCallback(CallbackID ID)
Definition Context.cpp:786
LLVM_ABI ReturnInst * createReturnInst(llvm::ReturnInst *I)
Definition Context.cpp:537
LLVM_ABI UncondBrInst * createUncondBrInst(llvm::UncondBrInst *UBI)
Definition Context.cpp:517
LLVM_ABI void runEraseInstrCallbacks(Instruction *I)
Definition Context.cpp:714
LLVM_ABI Module * getModule(llvm::Module *LLVMM) const
Definition Context.cpp:659
LLVM_ABI VAArgInst * createVAArgInst(llvm::VAArgInst *SI)
Definition Context.cpp:464
LLVM_ABI CleanupReturnInst * createCleanupReturnInst(llvm::CleanupReturnInst *I)
Definition Context.cpp:579
LLVM_ABI AllocaInst * createAllocaInst(llvm::AllocaInst *I)
Definition Context.cpp:620
LLVM_ABI void runCreateInstrCallbacks(Instruction *I)
Definition Context.cpp:719
LLVM_ABI AtomicRMWInst * createAtomicRMWInst(llvm::AtomicRMWInst *I)
Definition Context.cpp:610
LLVM_ABI InsertValueInst * createInsertValueInst(llvm::InsertValueInst *IVI)
Definition Context.cpp:511
LLVM_ABI FCmpInst * createFCmpInst(llvm::FCmpInst *I)
Definition Context.cpp:636
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:485
LLVM_ABI Constant * getOrCreateConstant(llvm::Constant *LLVMC)
Get or create a sandboxir::Constant from an existing LLVM IR LLVMC.
Definition Context.cpp:451
LLVM_ABI CallbackID registerSetUseCallback(SetUseCallback CB)
Register a callback that gets called when a Use gets set.
Definition Context.cpp:779
LLVM_ABI ShuffleVectorInst * createShuffleVectorInst(llvm::ShuffleVectorInst *SVI)
Definition Context.cpp:499
LLVM_ABI BinaryOperator * createBinaryOperator(llvm::BinaryOperator *I)
Definition Context.cpp:606
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition Context.h:120
LLVM_ABI Module * getOrCreateModule(llvm::Module *LLVMM)
Definition Context.cpp:666
LLVM_ABI LoadInst * createLoadInst(llvm::LoadInst *LI)
Definition Context.cpp:527
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:469
LLVM_ABI PHINode * createPHINode(llvm::PHINode *I)
Definition Context.cpp:628
LLVM_ABI CallbackID registerCreateInstrCallback(CreateInstrCallback CB)
Register a callback that gets called right after a SandboxIR instruction is created.
Definition Context.cpp:753
LLVM_ABI Context(LLVMContext &LLVMCtx)
Definition Context.cpp:647
LLVM_ABI CatchPadInst * createCatchPadInst(llvm::CatchPadInst *I)
Definition Context.cpp:566
LLVM_ABI void clear()
Clears function-level state.
Definition Context.cpp:653
LLVM_ABI CondBrInst * createCondBrInst(llvm::CondBrInst *CBI)
Definition Context.cpp:522
LLVM_ABI ICmpInst * createICmpInst(llvm::ICmpInst *I)
Definition Context.cpp:632
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:760
LLVM_ABI ExtractValueInst * createExtractValueInst(llvm::ExtractValueInst *IVI)
Definition Context.cpp:505
LLVM_ABI CastInst * createCastInst(llvm::CastInst *I)
Definition Context.cpp:624
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:532
LLVM_ABI CatchReturnInst * createCatchReturnInst(llvm::CatchReturnInst *I)
Definition Context.cpp:574
LLVM_ABI CatchSwitchInst * createCatchSwitchInst(llvm::CatchSwitchInst *I)
Definition Context.cpp:590
std::function< void(Instruction *, const BBIterator &)> MoveInstrCallback
Definition Context.h:41
LLVM_ABI void unregisterMoveInstrCallback(CallbackID ID)
Definition Context.cpp:773
LLVM_ABI CleanupPadInst * createCleanupPadInst(llvm::CleanupPadInst *I)
Definition Context.cpp:570
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:474
LLVM_ABI CallInst * createCallInst(llvm::CallInst *I)
Definition Context.cpp:542
LLVM_ABI SwitchInst * createSwitchInst(llvm::SwitchInst *I)
Definition Context.cpp:598
LLVM_ABI void runMoveInstrCallbacks(Instruction *I, const BBIterator &Where)
Definition Context.cpp:724
LLVM_ABI UnaryOperator * createUnaryOperator(llvm::UnaryOperator *I)
Definition Context.cpp:602
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:547
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:562
LLVM_ABI InsertElementInst * createInsertElementInst(llvm::InsertElementInst *IEI)
Definition Context.cpp:492
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:675
LLVM_ABI SelectInst * createSelectInst(llvm::SelectInst *SI)
Definition Context.cpp:479
LLVM_ABI ResumeInst * createResumeInst(llvm::ResumeInst *I)
Definition Context.cpp:594
LLVM_ABI void unregisterEraseInstrCallback(CallbackID ID)
Definition Context.cpp:746
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:247
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:766
LLVM_ABI UnreachableInst * createUnreachableInst(llvm::UnreachableInst *UI)
Definition Context.cpp:557
LLVM_ABI AtomicCmpXchgInst * createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I)
Definition Context.cpp:615
LLVM_ABI void runSetUseCallbacks(const Use &U, Value *NewSrc)
Definition Context.cpp:729
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:739
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:737
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