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