LLVM 20.0.0git
SandboxIR.cpp
Go to the documentation of this file.
1//===- SandboxIR.cpp - A transactional overlay IR on top of LLVM 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
12#include "llvm/IR/Constants.h"
13#include "llvm/Support/Debug.h"
14#include <sstream>
15
16using namespace llvm::sandboxir;
17
18Value *Use::get() const { return Ctx->getValue(LLVMUse->get()); }
19
20void Use::set(Value *V) {
21 Ctx->getTracker().emplaceIfTracking<UseSet>(*this);
22 LLVMUse->set(V->Val);
23}
24
25unsigned Use::getOperandNo() const { return Usr->getUseOperandNo(*this); }
26
27void Use::swap(Use &OtherUse) {
28 Ctx->getTracker().emplaceIfTracking<UseSwap>(*this, OtherUse);
29 LLVMUse->swap(*OtherUse.LLVMUse);
30}
31
32#ifndef NDEBUG
34 Value *Def = nullptr;
35 if (LLVMUse == nullptr)
36 OS << "<null> LLVM Use! ";
37 else
38 Def = Ctx->getValue(LLVMUse->get());
39 OS << "Def: ";
40 if (Def == nullptr)
41 OS << "NULL";
42 else
43 OS << *Def;
44 OS << "\n";
45
46 OS << "User: ";
47 if (Usr == nullptr)
48 OS << "NULL";
49 else
50 OS << *Usr;
51 OS << "\n";
52
53 OS << "OperandNo: ";
54 if (Usr == nullptr)
55 OS << "N/A";
56 else
57 OS << getOperandNo();
58 OS << "\n";
59}
60
61void Use::dump() const { dumpOS(dbgs()); }
62#endif // NDEBUG
63
65
67 assert(Use.LLVMUse != nullptr && "Already at end!");
68 User *User = Use.getUser();
69 Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false);
70 return *this;
71}
72
74 // Get the corresponding llvm::Use, get the next in the list, and update the
75 // sandboxir::Use.
76 llvm::Use *&LLVMUse = Use.LLVMUse;
77 assert(LLVMUse != nullptr && "Already at end!");
78 LLVMUse = LLVMUse->getNext();
79 if (LLVMUse == nullptr) {
80 Use.Usr = nullptr;
81 return *this;
82 }
83 auto *Ctx = Use.Ctx;
84 auto *LLVMUser = LLVMUse->getUser();
85 Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser));
86 return *this;
87}
88
91 Use.getOperandNo() + Num, /*Verify=*/true);
92 return OperandUseIterator(U);
93}
94
96 assert(Use.getOperandNo() >= Num && "Out of bounds!");
98 Use.getOperandNo() - Num, /*Verify=*/true);
99 return OperandUseIterator(U);
100}
101
103 int ThisOpNo = Use.getOperandNo();
104 int OtherOpNo = Other.Use.getOperandNo();
105 return ThisOpNo - OtherOpNo;
106}
107
109 : SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
110#ifndef NDEBUG
111 UID = Ctx.getNumValues();
112#endif
113}
114
116 llvm::Use *LLVMUse = nullptr;
117 if (Val->use_begin() != Val->use_end())
118 LLVMUse = &*Val->use_begin();
119 User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Ctx.getValue(
120 Val->use_begin()->getUser()))
121 : nullptr;
122 return use_iterator(Use(LLVMUse, User, Ctx));
123}
124
126 auto UseBegin = Val->use_begin();
127 auto UseEnd = Val->use_end();
128 bool AtEnd = UseBegin == UseEnd;
129 llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
130 User *User =
131 AtEnd ? nullptr
132 : cast_or_null<sandboxir::User>(Ctx.getValue(&*LLVMUse->getUser()));
133 return user_iterator(Use(LLVMUse, User, Ctx), UseToUser());
134}
135
136unsigned Value::getNumUses() const { return range_size(Val->users()); }
137
139 Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) {
140 assert(getType() == OtherV->getType() && "Can't replace with different type");
141 llvm::Value *OtherVal = OtherV->Val;
142 // We are delegating RUWIf to LLVM IR's RUWIf.
144 OtherVal, [&ShouldReplace, this](llvm::Use &LLVMUse) -> bool {
145 User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser()));
146 if (DstU == nullptr)
147 return false;
148 Use UseToReplace(&LLVMUse, DstU, Ctx);
149 if (!ShouldReplace(UseToReplace))
150 return false;
151 Ctx.getTracker().emplaceIfTracking<UseSet>(UseToReplace);
152 return true;
153 });
154}
155
157 assert(getType() == Other->getType() &&
158 "Replacing with Value of different type!");
159 auto &Tracker = Ctx.getTracker();
160 if (Tracker.isTracking()) {
161 for (auto Use : uses())
162 Tracker.track(std::make_unique<UseSet>(Use));
163 }
164 // We are delegating RAUW to LLVM IR's RAUW.
166}
167
168#ifndef NDEBUG
169std::string Value::getUid() const {
170 std::stringstream SS;
171 SS << "SB" << UID << ".";
172 return SS.str();
173}
174
176 OS << getUid() << " " << getSubclassIDStr(SubclassID) << " ";
177}
178
180 OS.indent(2) << "Val: ";
181 if (Val)
182 OS << *Val;
183 else
184 OS << "NULL";
185 OS << "\n";
186}
187
189 if (Val)
190 OS << *Val;
191 else
192 OS << "NULL ";
193}
194
196 OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")";
197}
198
200 if (Val)
202 else
203 OS << "NULL ";
204}
205
206void Value::dump() const {
207 dumpOS(dbgs());
208 dbgs() << "\n";
209}
210
213}
217}
218#endif // NDEBUG
219
220Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const {
221 assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!");
222 assert(isa<llvm::User>(Val) && "Non-users have no operands!");
223 llvm::Use *LLVMUse;
224 if (OpIdx != getNumOperands())
225 LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx);
226 else
227 LLVMUse = cast<llvm::User>(Val)->op_end();
228 return Use(LLVMUse, const_cast<User *>(this), Ctx);
229}
230
231#ifndef NDEBUG
233 assert(Ctx.getValue(Use.getUser()) == this &&
234 "Use not found in this SBUser's operands!");
235}
236#endif
237
239 switch (From->getSubclassID()) {
240#define DEF_VALUE(ID, CLASS)
241#define DEF_USER(ID, CLASS) \
242 case ClassID::ID: \
243 return true;
244#define DEF_INSTR(ID, OPC, CLASS) \
245 case ClassID::ID: \
246 return true;
247#include "llvm/SandboxIR/SandboxIRValues.def"
248 default:
249 return false;
250 }
251}
252
253void User::setOperand(unsigned OperandIdx, Value *Operand) {
254 assert(isa<llvm::User>(Val) && "No operands!");
256 // We are delegating to llvm::User::setOperand().
257 cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val);
258}
259
261 auto &Tracker = Ctx.getTracker();
262 if (Tracker.isTracking()) {
263 for (auto OpIdx : seq<unsigned>(0, getNumOperands())) {
264 auto Use = getOperandUse(OpIdx);
265 if (Use.get() == FromV)
267 }
268 }
269 // We are delegating RUOW to LLVM IR's RUOW.
270 return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val);
271}
272
273#ifndef NDEBUG
276 // TODO: This is incomplete
277}
278#endif // NDEBUG
279
281 auto ItE = BB->end();
282 assert(It != ItE && "Already at end!");
283 ++It;
284 if (It == ItE)
285 return *this;
286 Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It));
287 unsigned Num = NextI.getNumOfIRInstrs();
288 assert(Num > 0 && "Bad getNumOfIRInstrs()");
289 It = std::next(It, Num - 1);
290 return *this;
291}
292
294 assert(It != BB->begin() && "Already at begin!");
295 if (It == BB->end()) {
296 --It;
297 return *this;
298 }
299 Instruction &CurrI = **this;
300 unsigned Num = CurrI.getNumOfIRInstrs();
301 assert(Num > 0 && "Bad getNumOfIRInstrs()");
302 assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!");
303 It = std::prev(It, Num);
304 return *this;
305}
306
308 switch (Opc) {
309#define OP(OPC) \
310 case Opcode::OPC: \
311 return #OPC;
312#define OPCODES(...) __VA_ARGS__
313#define DEF_INSTR(ID, OPC, CLASS) OPC
314#include "llvm/SandboxIR/SandboxIRValues.def"
315 }
316 llvm_unreachable("Unknown Opcode");
317}
318
320 Instruction *Prev = getPrevNode();
321 if (Prev == nullptr) {
322 // If at top of the BB, return the first BB instruction.
323 return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
324 }
325 // Else get the Previous sandbox IR instruction's bottom IR instruction and
326 // return its successor.
327 llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val);
328 return PrevBotI->getNextNode();
329}
330
332 auto *I = cast<llvm::Instruction>(Val);
333 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
334}
335
337 assert(getParent() != nullptr && "Detached!");
338 assert(getIterator() != getParent()->end() && "Already at end!");
339 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
340 // and get the corresponding sandboxir Instruction that maps to it. This works
341 // even for SandboxIR Instructions that map to more than one LLVM Instruction.
342 auto *LLVMI = cast<llvm::Instruction>(Val);
343 assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
344 auto *NextLLVMI = LLVMI->getNextNode();
345 auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
346 if (NextI == nullptr)
347 return nullptr;
348 return NextI;
349}
350
352 assert(getParent() != nullptr && "Detached!");
353 auto It = getIterator();
354 if (It != getParent()->begin())
355 return std::prev(getIterator()).get();
356 return nullptr;
357}
358
361
362 // Detach all the LLVM IR instructions from their parent BB.
364 I->removeFromParent();
365}
366
368 assert(users().empty() && "Still connected to users, can't erase!");
369 std::unique_ptr<Value> Detached = Ctx.detach(this);
370 auto LLVMInstrs = getLLVMInstrs();
371
372 auto &Tracker = Ctx.getTracker();
373 if (Tracker.isTracking()) {
374 Tracker.track(std::make_unique<EraseFromParent>(std::move(Detached)));
375 // We don't actually delete the IR instruction, because then it would be
376 // impossible to bring it back from the dead at the same memory location.
377 // Instead we remove it from its BB and track its current location.
378 for (llvm::Instruction *I : LLVMInstrs)
379 I->removeFromParent();
380 // TODO: Multi-instructions need special treatment because some of the
381 // references are internal to the instruction.
382 for (llvm::Instruction *I : LLVMInstrs)
383 I->dropAllReferences();
384 } else {
385 // Erase in reverse to avoid erasing nstructions with attached uses.
386 for (llvm::Instruction *I : reverse(LLVMInstrs))
387 I->eraseFromParent();
388 }
389}
390
392 if (std::next(getIterator()) == WhereIt)
393 // Destination is same as origin, nothing to do.
394 return;
395
397
398 auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
400 if (WhereIt == BB.end()) {
401 It = LLVMBB->end();
402 } else {
403 Instruction *WhereI = &*WhereIt;
404 It = WhereI->getTopmostLLVMInstruction()->getIterator();
405 }
406 // TODO: Move this to the verifier of sandboxir::Instruction.
408 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
409 "Expected program order!");
410 // Do the actual move in LLVM IR.
411 for (auto *I : getLLVMInstrs())
412 I->moveBefore(*LLVMBB, It);
413}
414
416 llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
417 // TODO: Move this to the verifier of sandboxir::Instruction.
419 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
420 "Expected program order!");
421
423
424 // Insert the LLVM IR Instructions in program order.
426 I->insertBefore(BeforeTopI);
427}
428
430 insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
431}
432
434 llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
435 llvm::Instruction *LLVMBeforeI;
436 llvm::BasicBlock::iterator LLVMBeforeIt;
437 Instruction *BeforeI;
438 if (WhereIt != BB->end()) {
439 BeforeI = &*WhereIt;
440 LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
441 LLVMBeforeIt = LLVMBeforeI->getIterator();
442 } else {
443 BeforeI = nullptr;
444 LLVMBeforeI = nullptr;
445 LLVMBeforeIt = LLVMBB->end();
446 }
447
449
450 // Insert the LLVM IR Instructions in program order.
452 I->insertInto(LLVMBB, LLVMBeforeIt);
453}
454
456 // Get the LLVM IR Instruction that this maps to, get its parent, and get the
457 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
458 auto *BB = cast<llvm::Instruction>(Val)->getParent();
459 if (BB == nullptr)
460 return nullptr;
461 return cast<BasicBlock>(Ctx.getValue(BB));
462}
463
465 switch (From->getSubclassID()) {
466#define DEF_INSTR(ID, OPC, CLASS) \
467 case ClassID::ID: \
468 return true;
469#include "llvm/SandboxIR/SandboxIRValues.def"
470 default:
471 return false;
472 }
473}
474
475#ifndef NDEBUG
477 OS << "Unimplemented! Please override dump().";
478}
479#endif // NDEBUG
480
481Value *SelectInst::createCommon(Value *Cond, Value *True, Value *False,
482 const Twine &Name, IRBuilder<> &Builder,
483 Context &Ctx) {
484 llvm::Value *NewV =
485 Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
486 if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
487 return Ctx.createSelectInst(NewSI);
488 assert(isa<llvm::Constant>(NewV) && "Expected constant");
489 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
490}
491
493 Instruction *InsertBefore, Context &Ctx,
494 const Twine &Name) {
495 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
496 auto &Builder = Ctx.getLLVMIRBuilder();
497 Builder.SetInsertPoint(BeforeIR);
498 return createCommon(Cond, True, False, Name, Builder, Ctx);
499}
500
502 BasicBlock *InsertAtEnd, Context &Ctx,
503 const Twine &Name) {
504 auto *IRInsertAtEnd = cast<llvm::BasicBlock>(InsertAtEnd->Val);
505 auto &Builder = Ctx.getLLVMIRBuilder();
506 Builder.SetInsertPoint(IRInsertAtEnd);
507 return createCommon(Cond, True, False, Name, Builder, Ctx);
508}
509
511 return From->getSubclassID() == ClassID::Select;
512}
513
515 Context &Ctx) {
516 auto &Builder = Ctx.getLLVMIRBuilder();
517 llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
518 Builder.SetInsertPoint(cast<llvm::Instruction>(LLVMBefore));
519 llvm::BranchInst *NewBr =
520 Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
521 return Ctx.createBranchInst(NewBr);
522}
523
525 Context &Ctx) {
526 auto &Builder = Ctx.getLLVMIRBuilder();
527 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
528 llvm::BranchInst *NewBr =
529 Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
530 return Ctx.createBranchInst(NewBr);
531}
532
534 Value *Cond, Instruction *InsertBefore,
535 Context &Ctx) {
536 auto &Builder = Ctx.getLLVMIRBuilder();
537 llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
538 Builder.SetInsertPoint(LLVMBefore);
539 llvm::BranchInst *NewBr =
540 Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
541 cast<llvm::BasicBlock>(IfFalse->Val));
542 return Ctx.createBranchInst(NewBr);
543}
544
546 Value *Cond, BasicBlock *InsertAtEnd,
547 Context &Ctx) {
548 auto &Builder = Ctx.getLLVMIRBuilder();
549 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
550 llvm::BranchInst *NewBr =
551 Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
552 cast<llvm::BasicBlock>(IfFalse->Val));
553 return Ctx.createBranchInst(NewBr);
554}
555
557 return From->getSubclassID() == ClassID::Br;
558}
559
561 assert(isConditional() && "Cannot get condition of an uncond branch!");
562 return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition());
563}
564
565BasicBlock *BranchInst::getSuccessor(unsigned SuccIdx) const {
566 assert(SuccIdx < getNumSuccessors() &&
567 "Successor # out of range for Branch!");
568 return cast_or_null<BasicBlock>(
569 Ctx.getValue(cast<llvm::BranchInst>(Val)->getSuccessor(SuccIdx)));
570}
571
572void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
573 assert((Idx == 0 || Idx == 1) && "Out of bounds!");
574 setOperand(2u - Idx, NewSucc);
575}
576
577BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
578 return cast<BasicBlock>(Ctx.getValue(BB));
579}
580const BasicBlock *
581BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
582 return cast<BasicBlock>(Ctx.getValue(BB));
583}
584
589 cast<llvm::LoadInst>(Val)->setVolatile(V);
590}
591
593 Instruction *InsertBefore, Context &Ctx,
594 const Twine &Name) {
595 return create(Ty, Ptr, Align, InsertBefore, /*IsVolatile=*/false, Ctx, Name);
596}
597
599 Instruction *InsertBefore, bool IsVolatile,
600 Context &Ctx, const Twine &Name) {
601 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
602 auto &Builder = Ctx.getLLVMIRBuilder();
603 Builder.SetInsertPoint(BeforeIR);
604 auto *NewLI =
605 Builder.CreateAlignedLoad(Ty, Ptr->Val, Align, IsVolatile, Name);
606 auto *NewSBI = Ctx.createLoadInst(NewLI);
607 return NewSBI;
608}
609
611 BasicBlock *InsertAtEnd, Context &Ctx,
612 const Twine &Name) {
613 return create(Ty, Ptr, Align, InsertAtEnd, /*IsVolatile=*/false, Ctx, Name);
614}
615
617 BasicBlock *InsertAtEnd, bool IsVolatile,
618 Context &Ctx, const Twine &Name) {
619 auto &Builder = Ctx.getLLVMIRBuilder();
620 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
621 auto *NewLI =
622 Builder.CreateAlignedLoad(Ty, Ptr->Val, Align, IsVolatile, Name);
623 auto *NewSBI = Ctx.createLoadInst(NewLI);
624 return NewSBI;
625}
626
628 return From->getSubclassID() == ClassID::Load;
629}
630
632 return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());
633}
634
639 cast<llvm::StoreInst>(Val)->setVolatile(V);
640}
641
643 Instruction *InsertBefore, Context &Ctx) {
644 return create(V, Ptr, Align, InsertBefore, /*IsVolatile=*/false, Ctx);
645}
646
648 Instruction *InsertBefore, bool IsVolatile,
649 Context &Ctx) {
650 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
651 auto &Builder = Ctx.getLLVMIRBuilder();
652 Builder.SetInsertPoint(BeforeIR);
653 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
654 auto *NewSBI = Ctx.createStoreInst(NewSI);
655 return NewSBI;
656}
657
659 BasicBlock *InsertAtEnd, Context &Ctx) {
660 return create(V, Ptr, Align, InsertAtEnd, /*IsVolatile=*/false, Ctx);
661}
662
664 BasicBlock *InsertAtEnd, bool IsVolatile,
665 Context &Ctx) {
666 auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->Val);
667 auto &Builder = Ctx.getLLVMIRBuilder();
668 Builder.SetInsertPoint(InsertAtEndIR);
669 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
670 auto *NewSBI = Ctx.createStoreInst(NewSI);
671 return NewSBI;
672}
673
675 return From->getSubclassID() == ClassID::Store;
676}
677
679 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
680}
681
683 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
684}
685
687 Context &Ctx) {
688 auto &Builder = Ctx.getLLVMIRBuilder();
689 llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
690 Builder.SetInsertPoint(LLVMBefore);
691 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
692 return Ctx.createUnreachableInst(NewUI);
693}
694
696 Context &Ctx) {
697 auto &Builder = Ctx.getLLVMIRBuilder();
698 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
699 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
700 return Ctx.createUnreachableInst(NewUI);
701}
702
704 return From->getSubclassID() == ClassID::Unreachable;
705}
706
707ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
708 Context &Ctx) {
709 llvm::ReturnInst *NewRI;
710 if (RetVal != nullptr)
711 NewRI = Builder.CreateRet(RetVal->Val);
712 else
713 NewRI = Builder.CreateRetVoid();
714 return Ctx.createReturnInst(NewRI);
715}
716
718 Context &Ctx) {
719 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
720 auto &Builder = Ctx.getLLVMIRBuilder();
721 Builder.SetInsertPoint(BeforeIR);
722 return createCommon(RetVal, Builder, Ctx);
723}
724
726 Context &Ctx) {
727 auto &Builder = Ctx.getLLVMIRBuilder();
728 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
729 return createCommon(RetVal, Builder, Ctx);
730}
731
733 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
734 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
735}
736
738 return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());
739}
740
742 llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
743 return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
744}
745
747 return cast_or_null<Function>(
748 Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
749}
751 return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
752}
753
755 // F's function type is private, so we rely on `setCalledFunction()` to update
756 // it. But even though we are calling `setCalledFunction()` we also need to
757 // track this change at the SandboxIR level, which is why we call
758 // `setCalledOperand()` here.
759 // Note: This may break if `setCalledFunction()` early returns if `F`
760 // is already set, but we do have a unit test for it.
762 cast<llvm::CallBase>(Val)->setCalledFunction(F->getFunctionType(),
763 cast<llvm::Function>(F->Val));
764}
765
768 BasicBlock *WhereBB, Context &Ctx,
769 const Twine &NameStr) {
770 auto &Builder = Ctx.getLLVMIRBuilder();
771 if (WhereIt != WhereBB->end())
772 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
773 else
774 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
776 LLVMArgs.reserve(Args.size());
777 for (Value *Arg : Args)
778 LLVMArgs.push_back(Arg->Val);
779 llvm::CallInst *NewCI = Builder.CreateCall(FTy, Func->Val, LLVMArgs, NameStr);
780 return Ctx.createCallInst(NewCI);
781}
782
784 ArrayRef<Value *> Args, Instruction *InsertBefore,
785 Context &Ctx, const Twine &NameStr) {
786 return CallInst::create(FTy, Func, Args, InsertBefore->getIterator(),
787 InsertBefore->getParent(), Ctx, NameStr);
788}
789
791 ArrayRef<Value *> Args, BasicBlock *InsertAtEnd,
792 Context &Ctx, const Twine &NameStr) {
793 return CallInst::create(FTy, Func, Args, InsertAtEnd->end(), InsertAtEnd, Ctx,
794 NameStr);
795}
796
798 BasicBlock *IfNormal, BasicBlock *IfException,
799 ArrayRef<Value *> Args, BBIterator WhereIt,
800 BasicBlock *WhereBB, Context &Ctx,
801 const Twine &NameStr) {
802 auto &Builder = Ctx.getLLVMIRBuilder();
803 if (WhereIt != WhereBB->end())
804 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
805 else
806 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
808 LLVMArgs.reserve(Args.size());
809 for (Value *Arg : Args)
810 LLVMArgs.push_back(Arg->Val);
811 llvm::InvokeInst *Invoke = Builder.CreateInvoke(
812 FTy, Func->Val, cast<llvm::BasicBlock>(IfNormal->Val),
813 cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
814 return Ctx.createInvokeInst(Invoke);
815}
816
818 BasicBlock *IfNormal, BasicBlock *IfException,
820 Instruction *InsertBefore, Context &Ctx,
821 const Twine &NameStr) {
822 return create(FTy, Func, IfNormal, IfException, Args,
823 InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
824 NameStr);
825}
826
828 BasicBlock *IfNormal, BasicBlock *IfException,
829 ArrayRef<Value *> Args, BasicBlock *InsertAtEnd,
830 Context &Ctx, const Twine &NameStr) {
831 return create(FTy, Func, IfNormal, IfException, Args, InsertAtEnd->end(),
832 InsertAtEnd, Ctx, NameStr);
833}
834
836 return cast<BasicBlock>(
837 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
838}
840 return cast<BasicBlock>(
841 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
842}
844 setOperand(1, BB);
845 assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
846}
848 setOperand(2, BB);
849 assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
850}
852 return cast<Instruction>(
853 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
854 ;
855}
856BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
857 return cast<BasicBlock>(
858 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
859}
860
862 BasicBlock *DefaultDest,
863 ArrayRef<BasicBlock *> IndirectDests,
864 ArrayRef<Value *> Args, BBIterator WhereIt,
865 BasicBlock *WhereBB, Context &Ctx,
866 const Twine &NameStr) {
867 auto &Builder = Ctx.getLLVMIRBuilder();
868 if (WhereIt != WhereBB->end())
869 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
870 else
871 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
872
873 SmallVector<llvm::BasicBlock *> LLVMIndirectDests;
874 LLVMIndirectDests.reserve(IndirectDests.size());
875 for (BasicBlock *IndDest : IndirectDests)
876 LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
877
879 LLVMArgs.reserve(Args.size());
880 for (Value *Arg : Args)
881 LLVMArgs.push_back(Arg->Val);
882
883 llvm::CallBrInst *CallBr = Builder.CreateCallBr(
884 FTy, Func->Val, cast<llvm::BasicBlock>(DefaultDest->Val),
885 LLVMIndirectDests, LLVMArgs, NameStr);
886 return Ctx.createCallBrInst(CallBr);
887}
888
890 BasicBlock *DefaultDest,
891 ArrayRef<BasicBlock *> IndirectDests,
893 Instruction *InsertBefore, Context &Ctx,
894 const Twine &NameStr) {
895 return create(FTy, Func, DefaultDest, IndirectDests, Args,
896 InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
897 NameStr);
898}
900 BasicBlock *DefaultDest,
901 ArrayRef<BasicBlock *> IndirectDests,
902 ArrayRef<Value *> Args, BasicBlock *InsertAtEnd,
903 Context &Ctx, const Twine &NameStr) {
904 return create(FTy, Func, DefaultDest, IndirectDests, Args, InsertAtEnd->end(),
905 InsertAtEnd, Ctx, NameStr);
906}
907
909 return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
910}
912 return Ctx.getValue(
913 cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx));
914}
916 return cast<BasicBlock>(
917 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
918}
920 return cast<BasicBlock>(
921 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
922}
925 for (llvm::BasicBlock *LLVMBB :
926 cast<llvm::CallBrInst>(Val)->getIndirectDests())
927 BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
928 return BBs;
929}
934 cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
935}
938 cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
939 cast<llvm::BasicBlock>(BB->Val));
940}
942 return cast<BasicBlock>(
943 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
944}
945
947 ArrayRef<Value *> IdxList,
948 BasicBlock::iterator WhereIt,
949 BasicBlock *WhereBB, Context &Ctx,
950 const Twine &NameStr) {
951 auto &Builder = Ctx.getLLVMIRBuilder();
952 if (WhereIt != WhereBB->end())
953 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
954 else
955 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
956 SmallVector<llvm::Value *> LLVMIdxList;
957 LLVMIdxList.reserve(IdxList.size());
958 for (Value *Idx : IdxList)
959 LLVMIdxList.push_back(Idx->Val);
960 llvm::Value *NewV = Builder.CreateGEP(Ty, Ptr->Val, LLVMIdxList, NameStr);
961 if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
962 return Ctx.createGetElementPtrInst(NewGEP);
963 assert(isa<llvm::Constant>(NewV) && "Expected constant");
964 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
965}
966
968 ArrayRef<Value *> IdxList,
969 Instruction *InsertBefore, Context &Ctx,
970 const Twine &NameStr) {
971 return GetElementPtrInst::create(Ty, Ptr, IdxList,
972 InsertBefore->getIterator(),
973 InsertBefore->getParent(), Ctx, NameStr);
974}
975
977 ArrayRef<Value *> IdxList,
978 BasicBlock *InsertAtEnd, Context &Ctx,
979 const Twine &NameStr) {
980 return GetElementPtrInst::create(Ty, Ptr, IdxList, InsertAtEnd->end(),
981 InsertAtEnd, Ctx, NameStr);
982}
983
985 return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand());
986}
987
988BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
989 return cast<BasicBlock>(Ctx.getValue(LLVMBB));
990}
991
992PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
993 Instruction *InsertBefore, Context &Ctx,
994 const Twine &Name) {
996 Ty, NumReservedValues, Name, InsertBefore->getTopmostLLVMInstruction());
997 return Ctx.createPHINode(NewPHI);
998}
999
1001 return From->getSubclassID() == ClassID::PHI;
1002}
1003
1005 return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
1006}
1008 auto &Tracker = Ctx.getTracker();
1011
1012 cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
1013}
1015 return cast<BasicBlock>(
1016 Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
1017}
1019 llvm::Use *LLVMUse = U.LLVMUse;
1020 llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
1021 return cast<BasicBlock>(Ctx.getValue(BB));
1022}
1024 auto &Tracker = Ctx.getTracker();
1027 cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
1028 cast<llvm::BasicBlock>(BB->Val));
1029}
1031 auto &Tracker = Ctx.getTracker();
1033
1034 cast<llvm::PHINode>(Val)->addIncoming(V->Val,
1035 cast<llvm::BasicBlock>(BB->Val));
1036}
1038 auto &Tracker = Ctx.getTracker();
1040 llvm::Value *LLVMV =
1041 cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
1042 /*DeletePHIIfEmpty=*/false);
1043 return Ctx.getValue(LLVMV);
1044}
1046 auto &Tracker = Ctx.getTracker();
1048
1049 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
1050 llvm::Value *LLVMV =
1051 cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
1052 /*DeletePHIIfEmpty=*/false);
1053 return Ctx.getValue(LLVMV);
1054}
1056 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
1057 return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
1058}
1060 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
1061 llvm::Value *LLVMV =
1062 cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
1063 return Ctx.getValue(LLVMV);
1064}
1066 llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
1067 return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
1068}
1070 assert(New && Old && "Sandbox IR PHI node got a null basic block!");
1071 for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
1072 Idx != NumOps; ++Idx)
1073 if (getIncomingBlock(Idx) == Old)
1074 setIncomingBlock(Idx, New);
1075}
1076void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
1077 // Avoid duplicate tracking by going through this->removeIncomingValue here at
1078 // the expense of some performance. Copy PHI::removeIncomingValueIf more
1079 // directly if performance becomes an issue.
1080
1081 // Removing the element at index X, moves the element previously at X + 1
1082 // to X. Working from the end avoids complications from that.
1083 unsigned Idx = getNumIncomingValues();
1084 while (Idx > 0) {
1085 if (Predicate(Idx - 1))
1087 --Idx;
1088 }
1089}
1090
1092 switch (Opc) {
1093 case Instruction::Opcode::ZExt:
1094 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
1095 case Instruction::Opcode::SExt:
1096 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
1097 case Instruction::Opcode::FPToUI:
1098 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
1099 case Instruction::Opcode::FPToSI:
1100 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
1101 case Instruction::Opcode::FPExt:
1102 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
1103 case Instruction::Opcode::PtrToInt:
1104 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
1105 case Instruction::Opcode::IntToPtr:
1106 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
1107 case Instruction::Opcode::SIToFP:
1108 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
1109 case Instruction::Opcode::UIToFP:
1110 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
1111 case Instruction::Opcode::Trunc:
1112 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
1113 case Instruction::Opcode::FPTrunc:
1114 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
1115 case Instruction::Opcode::BitCast:
1116 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
1117 case Instruction::Opcode::AddrSpaceCast:
1118 return static_cast<llvm::Instruction::CastOps>(
1119 llvm::Instruction::AddrSpaceCast);
1120 default:
1121 llvm_unreachable("Opcode not suitable for CastInst!");
1122 }
1123}
1124
1125AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
1126 BasicBlock *WhereBB, Context &Ctx,
1127 Value *ArraySize, const Twine &Name) {
1128 auto &Builder = Ctx.getLLVMIRBuilder();
1129 if (WhereIt == WhereBB->end())
1130 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1131 else
1132 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1133 auto *NewAlloca = Builder.CreateAlloca(Ty, AddrSpace, ArraySize->Val, Name);
1134 return Ctx.createAllocaInst(NewAlloca);
1135}
1136
1137AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
1138 Instruction *InsertBefore, Context &Ctx,
1139 Value *ArraySize, const Twine &Name) {
1140 return create(Ty, AddrSpace, InsertBefore->getIterator(),
1141 InsertBefore->getParent(), Ctx, ArraySize, Name);
1142}
1143
1144AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
1145 BasicBlock *InsertAtEnd, Context &Ctx,
1146 Value *ArraySize, const Twine &Name) {
1147 return create(Ty, AddrSpace, InsertAtEnd->end(), InsertAtEnd, Ctx, ArraySize,
1148 Name);
1149}
1150
1152 Ctx.getTracker()
1155 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty);
1156}
1157
1159 Ctx.getTracker()
1162 this);
1163 cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1164}
1165
1167 Ctx.getTracker()
1170 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1171}
1172
1174 return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
1175}
1176
1178 BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
1179 const Twine &Name) {
1180 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1181 auto &Builder = Ctx.getLLVMIRBuilder();
1182 if (WhereIt == WhereBB->end())
1183 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1184 else
1185 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1186 auto *NewV =
1187 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy, Name);
1188 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1189 return Ctx.createCastInst(NewCI);
1190 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1191 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1192}
1193
1195 Instruction *InsertBefore, Context &Ctx,
1196 const Twine &Name) {
1197 return create(DestTy, Op, Operand, InsertBefore->getIterator(),
1198 InsertBefore->getParent(), Ctx, Name);
1199}
1200
1202 BasicBlock *InsertAtEnd, Context &Ctx,
1203 const Twine &Name) {
1204 return create(DestTy, Op, Operand, InsertAtEnd->end(), InsertAtEnd, Ctx,
1205 Name);
1206}
1207
1209 return From->getSubclassID() == ClassID::Cast;
1210}
1211
1213 Instruction *InsertBefore, Context &Ctx,
1214 const Twine &Name) {
1215 auto &Builder = Ctx.getLLVMIRBuilder();
1216 Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
1217 llvm::Value *NewV =
1218 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1219 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1220 return Ctx.createInsertElementInst(NewInsert);
1221 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1222 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1223}
1224
1226 BasicBlock *InsertAtEnd, Context &Ctx,
1227 const Twine &Name) {
1228 auto &Builder = Ctx.getLLVMIRBuilder();
1229 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
1230 llvm::Value *NewV =
1231 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1232 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1233 return Ctx.createInsertElementInst(NewInsert);
1234 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1235 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1236}
1237
1239 Instruction *InsertBefore, Context &Ctx,
1240 const Twine &Name) {
1241 auto &Builder = Ctx.getLLVMIRBuilder();
1242 Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
1243 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1244 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1245 return Ctx.createExtractElementInst(NewExtract);
1246 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1247 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1248}
1249
1251 BasicBlock *InsertAtEnd, Context &Ctx,
1252 const Twine &Name) {
1253 auto &Builder = Ctx.getLLVMIRBuilder();
1254 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
1255 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1256 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1257 return Ctx.createExtractElementInst(NewExtract);
1258 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1259 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1260}
1261
1263 bool IsSigned) {
1264 llvm::Constant *LLVMC = llvm::ConstantInt::get(Ty, V, IsSigned);
1265 return Ctx.getOrCreateConstant(LLVMC);
1266}
1267
1268#ifndef NDEBUG
1272}
1273
1275 auto *F = cast<llvm::Function>(Val);
1276 OS << *F->getReturnType() << " @" << F->getName() << "(";
1277 interleave(
1278 F->args(),
1279 [this, &OS](const llvm::Argument &LLVMArg) {
1280 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
1281 if (SBArg == nullptr)
1282 OS << "NULL";
1283 else
1284 SBArg->printAsOperand(OS);
1285 },
1286 [&] { OS << ", "; });
1287 OS << ")";
1288}
1291 OS << " {\n";
1292 auto *LLVMF = cast<llvm::Function>(Val);
1293 interleave(
1294 *LLVMF,
1295 [this, &OS](const llvm::BasicBlock &LLVMBB) {
1296 auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
1297 if (BB == nullptr)
1298 OS << "NULL";
1299 else
1300 OS << *BB;
1301 },
1302 [&OS] { OS << "\n"; });
1303 OS << "}\n";
1304}
1305#endif // NDEBUG
1306
1308BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
1309 return cast_or_null<Instruction>(Ctx->getValue(&*It));
1310}
1311
1312std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
1313 std::unique_ptr<Value> Erased;
1314 auto It = LLVMValueToValueMap.find(V);
1315 if (It != LLVMValueToValueMap.end()) {
1316 auto *Val = It->second.release();
1317 Erased = std::unique_ptr<Value>(Val);
1318 LLVMValueToValueMap.erase(It);
1319 }
1320 return Erased;
1321}
1322
1323std::unique_ptr<Value> Context::detach(Value *V) {
1324 assert(V->getSubclassID() != Value::ClassID::Constant &&
1325 "Can't detach a constant!");
1326 assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
1327 return detachLLVMValue(V->Val);
1328}
1329
1330Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
1331 assert(VPtr->getSubclassID() != Value::ClassID::User &&
1332 "Can't register a user!");
1333
1334 // Track creation of instructions.
1335 // Please note that we don't allow the creation of detached instructions,
1336 // meaning that the instructions need to be inserted into a block upon
1337 // creation. This is why the tracker class combines creation and insertion.
1338 if (auto *I = dyn_cast<Instruction>(VPtr.get()))
1340
1341 Value *V = VPtr.get();
1342 [[maybe_unused]] auto Pair =
1343 LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
1344 assert(Pair.second && "Already exists!");
1345 return V;
1346}
1347
1349 auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr});
1350 auto It = Pair.first;
1351 if (!Pair.second)
1352 return It->second.get();
1353
1354 if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
1355 if (auto *F = dyn_cast<llvm::Function>(LLVMV))
1356 It->second = std::unique_ptr<Function>(new Function(F, *this));
1357 else
1358 It->second = std::unique_ptr<Constant>(new Constant(C, *this));
1359 auto *NewC = It->second.get();
1360 for (llvm::Value *COp : C->operands())
1362 return NewC;
1363 }
1364 if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
1365 It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
1366 return It->second.get();
1367 }
1368 if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
1369 assert(isa<BlockAddress>(U) &&
1370 "This won't create a SBBB, don't call this function directly!");
1371 if (auto *SBBB = getValue(BB))
1372 return SBBB;
1373 return nullptr;
1374 }
1375 assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
1376
1377 switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
1378 case llvm::Instruction::Select: {
1379 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
1380 It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
1381 return It->second.get();
1382 }
1383 case llvm::Instruction::ExtractElement: {
1384 auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
1385 It->second = std::unique_ptr<ExtractElementInst>(
1386 new ExtractElementInst(LLVMIns, *this));
1387 return It->second.get();
1388 }
1389 case llvm::Instruction::InsertElement: {
1390 auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
1391 It->second = std::unique_ptr<InsertElementInst>(
1392 new InsertElementInst(LLVMIns, *this));
1393 return It->second.get();
1394 }
1395 case llvm::Instruction::Br: {
1396 auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
1397 It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
1398 return It->second.get();
1399 }
1400 case llvm::Instruction::Load: {
1401 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
1402 It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
1403 return It->second.get();
1404 }
1405 case llvm::Instruction::Store: {
1406 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
1407 It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
1408 return It->second.get();
1409 }
1410 case llvm::Instruction::Ret: {
1411 auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
1412 It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
1413 return It->second.get();
1414 }
1415 case llvm::Instruction::Call: {
1416 auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
1417 It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
1418 return It->second.get();
1419 }
1420 case llvm::Instruction::Invoke: {
1421 auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
1422 It->second = std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
1423 return It->second.get();
1424 }
1425 case llvm::Instruction::CallBr: {
1426 auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
1427 It->second = std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
1428 return It->second.get();
1429 }
1430 case llvm::Instruction::GetElementPtr: {
1431 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
1432 It->second = std::unique_ptr<GetElementPtrInst>(
1433 new GetElementPtrInst(LLVMGEP, *this));
1434 return It->second.get();
1435 }
1436 case llvm::Instruction::Alloca: {
1437 auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
1438 It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
1439 return It->second.get();
1440 }
1441 case llvm::Instruction::ZExt:
1442 case llvm::Instruction::SExt:
1443 case llvm::Instruction::FPToUI:
1444 case llvm::Instruction::FPToSI:
1445 case llvm::Instruction::FPExt:
1446 case llvm::Instruction::PtrToInt:
1447 case llvm::Instruction::IntToPtr:
1448 case llvm::Instruction::SIToFP:
1449 case llvm::Instruction::UIToFP:
1450 case llvm::Instruction::Trunc:
1451 case llvm::Instruction::FPTrunc:
1452 case llvm::Instruction::BitCast:
1453 case llvm::Instruction::AddrSpaceCast: {
1454 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
1455 It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
1456 return It->second.get();
1457 }
1458 case llvm::Instruction::PHI: {
1459 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
1460 It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
1461 return It->second.get();
1462 }
1463 case llvm::Instruction::Unreachable: {
1464 auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
1465 It->second = std::unique_ptr<UnreachableInst>(
1466 new UnreachableInst(LLVMUnreachable, *this));
1467 return It->second.get();
1468 }
1469 default:
1470 break;
1471 }
1472
1473 It->second = std::unique_ptr<OpaqueInst>(
1474 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
1475 return It->second.get();
1476}
1477
1479 assert(getValue(LLVMBB) == nullptr && "Already exists!");
1480 auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
1481 auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
1482 // Create SandboxIR for BB's body.
1483 BB->buildBasicBlockFromLLVMIR(LLVMBB);
1484 return BB;
1485}
1486
1488 auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
1489 return cast<SelectInst>(registerValue(std::move(NewPtr)));
1490}
1491
1494 auto NewPtr =
1495 std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
1496 return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
1497}
1498
1501 auto NewPtr =
1502 std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
1503 return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
1504}
1505
1507 auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
1508 return cast<BranchInst>(registerValue(std::move(NewPtr)));
1509}
1510
1512 auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
1513 return cast<LoadInst>(registerValue(std::move(NewPtr)));
1514}
1515
1517 auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
1518 return cast<StoreInst>(registerValue(std::move(NewPtr)));
1519}
1520
1522 auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
1523 return cast<ReturnInst>(registerValue(std::move(NewPtr)));
1524}
1525
1527 auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
1528 return cast<CallInst>(registerValue(std::move(NewPtr)));
1529}
1530
1532 auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
1533 return cast<InvokeInst>(registerValue(std::move(NewPtr)));
1534}
1535
1537 auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
1538 return cast<CallBrInst>(registerValue(std::move(NewPtr)));
1539}
1540
1542 auto NewPtr =
1543 std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
1544 return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
1545}
1546
1549 auto NewPtr =
1550 std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
1551 return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
1552}
1554 auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
1555 return cast<AllocaInst>(registerValue(std::move(NewPtr)));
1556}
1558 auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
1559 return cast<CastInst>(registerValue(std::move(NewPtr)));
1560}
1562 auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
1563 return cast<PHINode>(registerValue(std::move(NewPtr)));
1564}
1565
1567 auto It = LLVMValueToValueMap.find(V);
1568 if (It != LLVMValueToValueMap.end())
1569 return It->second.get();
1570 return nullptr;
1571}
1572
1574 assert(getValue(F) == nullptr && "Already exists!");
1575 auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
1576 auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
1577 // Create arguments.
1578 for (auto &Arg : F->args())
1579 getOrCreateArgument(&Arg);
1580 // Create BBs.
1581 for (auto &BB : *F)
1582 createBasicBlock(&BB);
1583 return SBF;
1584}
1585
1587 auto *BB = cast<llvm::BasicBlock>(Val);
1588 auto *F = BB->getParent();
1589 if (F == nullptr)
1590 // Detached
1591 return nullptr;
1592 return cast_or_null<Function>(Ctx.getValue(F));
1593}
1594
1595void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
1596 for (llvm::Instruction &IRef : reverse(*LLVMBB)) {
1597 llvm::Instruction *I = &IRef;
1599 for (auto [OpIdx, Op] : enumerate(I->operands())) {
1600 // Skip instruction's label operands
1601 if (isa<llvm::BasicBlock>(Op))
1602 continue;
1603 // Skip metadata
1604 if (isa<llvm::MetadataAsValue>(Op))
1605 continue;
1606 // Skip asm
1607 if (isa<llvm::InlineAsm>(Op))
1608 continue;
1610 }
1611 }
1612#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
1613 verify();
1614#endif
1615}
1616
1618 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
1620 if (!BB->empty()) {
1621 auto *V = Ctx.getValue(&*BB->begin());
1622 assert(V != nullptr && "No SandboxIR for BB->begin()!");
1623 auto *I = cast<Instruction>(V);
1624 unsigned Num = I->getNumOfIRInstrs();
1625 assert(Num >= 1u && "Bad getNumOfIRInstrs()");
1626 It = std::next(It, Num - 1);
1627 }
1628 return iterator(BB, It, &Ctx);
1629}
1630
1632 auto *TerminatorV =
1633 Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
1634 return cast_or_null<Instruction>(TerminatorV);
1635}
1636
1638 auto *BB = cast<llvm::BasicBlock>(Val);
1639 assert(!BB->empty() && "Empty block!");
1640 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
1641 assert(SBI != nullptr && "Expected Instr!");
1642 return *SBI;
1643}
1644
1646 auto *BB = cast<llvm::BasicBlock>(Val);
1647 assert(!BB->empty() && "Empty block!");
1648 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
1649 assert(SBI != nullptr && "Expected Instr!");
1650 return *SBI;
1651}
1652
1653#ifndef NDEBUG
1655 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
1656 const auto &Name = BB->getName();
1657 OS << Name;
1658 if (!Name.empty())
1659 OS << ":\n";
1660 // If there are Instructions in the BB that are not mapped to SandboxIR, then
1661 // use a crash-proof dump.
1662 if (any_of(*BB, [this](llvm::Instruction &I) {
1663 return Ctx.getValue(&I) == nullptr;
1664 })) {
1665 OS << "<Crash-proof mode!>\n";
1667 for (llvm::Instruction &IRef : *BB) {
1668 Value *SBV = Ctx.getValue(&IRef);
1669 if (SBV == nullptr)
1670 OS << IRef << " *** No SandboxIR ***\n";
1671 else {
1672 auto *SBI = dyn_cast<Instruction>(SBV);
1673 if (SBI == nullptr) {
1674 OS << IRef << " *** Not a SBInstruction!!! ***\n";
1675 } else {
1676 if (Visited.insert(SBI).second)
1677 OS << *SBI << "\n";
1678 }
1679 }
1680 }
1681 } else {
1682 for (auto &SBI : *this) {
1683 SBI.dumpOS(OS);
1684 OS << "\n";
1685 }
1686 }
1687}
1688#endif // NDEBUG
BlockVerifier::State From
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
std::string Name
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
ppc ctr loops PowerPC CTR Loops Verify
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc)
Definition: SandboxIR.cpp:1091
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition: VPlanSLP.cpp:191
an instruction to allocate memory on the stack
Definition: Instructions.h:61
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
iterator end()
Definition: BasicBlock.h:461
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:448
bool empty() const
Definition: BasicBlock.h:470
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:177
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:530
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
This instruction extracts a single (scalar) element from a VectorType value.
Class to represent function types.
Definition: DerivedTypes.h:103
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:915
CallBrInst * CreateCallBr(FunctionType *Ty, Value *Callee, BasicBlock *DefaultDest, ArrayRef< BasicBlock * > IndirectDests, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="")
Create a callbr instruction.
Definition: IRBuilder.h:1202
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2480
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition: IRBuilder.h:1778
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2468
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition: IRBuilder.h:1812
UnreachableInst * CreateUnreachable()
Definition: IRBuilder.h:1268
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition: IRBuilder.cpp:1091
InvokeInst * CreateInvoke(FunctionType *Ty, Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > OpBundles, const Twine &Name="")
Create an invoke instruction.
Definition: IRBuilder.h:1163
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:1100
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition: IRBuilder.h:1871
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Definition: IRBuilder.h:1125
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition: IRBuilder.h:1095
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
Definition: IRBuilder.h:1119
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2169
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:177
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition: IRBuilder.h:1831
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2420
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2674
This instruction inserts a single (scalar) element into a VectorType value.
const char * getOpcodeName() const
Definition: Instruction.h:276
Invoke instruction.
An instruction for reading from memory.
Definition: Instructions.h:174
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
Return a value (possibly void), from a function.
This class represents the LLVM 'select' instruction.
void reserve(size_type N)
Definition: SmallVector.h:677
void push_back(const T &Elt)
Definition: SmallVector.h:427
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1210
An instruction for storing to memory.
Definition: Instructions.h:290
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:72
LLVM Value Representation.
Definition: Value.h:74
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:534
iterator_range< user_iterator > users()
Definition: Value.h:421
use_iterator use_begin()
Definition: Value.h:360
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
Definition: AsmWriter.cpp:5106
void replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
Definition: Value.cpp:542
use_iterator use_end()
Definition: Value.h:368
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
Definition: ilist_node.h:132
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:353
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
Definition: SandboxIR.h:1405
Value * getArraySize()
Get the number of elements allocated.
Definition: SandboxIR.cpp:1173
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: SandboxIR.h:1387
void setAlignment(Align Align)
Definition: SandboxIR.cpp:1158
void setUsedWithInAlloca(bool V)
Specify whether this alloca is used to represent the arguments to a call.
Definition: SandboxIR.cpp:1166
static AllocaInst * create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, Value *ArraySize=nullptr, const Twine &Name="")
Definition: SandboxIR.cpp:1125
void setAllocatedType(Type *Ty)
for use only in special circumstances that need to generically transform a whole instruction (eg: IR ...
Definition: SandboxIR.cpp:1151
Argument of a sandboxir::Function.
Definition: SandboxIR.h:370
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:214
void printAsOperand(raw_ostream &OS) const
Definition: SandboxIR.cpp:211
Iterator for Instructions in a `BasicBlock.
Definition: SandboxIR.h:512
Contains a list of sandboxir::Instruction's.
Definition: SandboxIR.h:554
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:1654
void verify() const final
Should crash if there is something wrong with the instruction.
Definition: SandboxIR.h:592
Function * getParent() const
Definition: SandboxIR.cpp:1586
Instruction & front() const
Definition: SandboxIR.cpp:1637
Instruction * getTerminator() const
Definition: SandboxIR.cpp:1631
Context & getContext() const
Definition: SandboxIR.h:585
Instruction & back() const
Definition: SandboxIR.cpp:1645
iterator end() const
Definition: SandboxIR.h:575
unsigned getNumSuccessors() const
Definition: SandboxIR.h:831
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:556
bool isConditional() const
Definition: SandboxIR.h:826
void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
Definition: SandboxIR.cpp:572
BasicBlock * getSuccessor(unsigned SuccIdx) const
Definition: SandboxIR.cpp:565
static BranchInst * create(BasicBlock *IfTrue, Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:514
Value * getCondition() const
Definition: SandboxIR.cpp:560
void setCalledFunction(Function *F)
Definition: SandboxIR.cpp:754
Function * getCalledFunction() const
Definition: SandboxIR.cpp:746
void setCalledOperand(Value *V)
Definition: SandboxIR.h:1128
Value * getCalledOperand() const
Definition: SandboxIR.cpp:737
Use getCalledOperandUse() const
Definition: SandboxIR.cpp:741
static CallBrInst * create(FunctionType *FTy, Value *Func, BasicBlock *DefaultDest, ArrayRef< BasicBlock * > IndirectDests, ArrayRef< Value * > Args, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
Definition: SandboxIR.cpp:861
BasicBlock * getIndirectDest(unsigned Idx) const
Definition: SandboxIR.cpp:919
void setDefaultDest(BasicBlock *BB)
Definition: SandboxIR.cpp:930
Value * getIndirectDestLabel(unsigned Idx) const
Definition: SandboxIR.cpp:908
Value * getIndirectDestLabelUse(unsigned Idx) const
Definition: SandboxIR.cpp:911
SmallVector< BasicBlock *, 16 > getIndirectDests() const
Definition: SandboxIR.cpp:923
BasicBlock * getDefaultDest() const
Definition: SandboxIR.cpp:915
BasicBlock * getSuccessor(unsigned Idx) const
Definition: SandboxIR.cpp:941
void setIndirectDest(unsigned Idx, BasicBlock *BB)
Definition: SandboxIR.cpp:936
static CallInst * create(FunctionType *FTy, Value *Func, ArrayRef< Value * > Args, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
static Value * create(Type *DestTy, Opcode Op, Value *Operand, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1177
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:1208
static Constant * createInt(Type *Ty, uint64_t V, Context &Ctx, bool IsSigned=false)
Definition: SandboxIR.cpp:1262
void dumpOS(raw_ostream &OS) const override
Definition: SandboxIR.cpp:1269
CallBrInst * createCallBrInst(llvm::CallBrInst *I)
Definition: SandboxIR.cpp:1536
GetElementPtrInst * createGetElementPtrInst(llvm::GetElementPtrInst *I)
Definition: SandboxIR.cpp:1548
DenseMap< llvm::Value *, std::unique_ptr< sandboxir::Value > > LLVMValueToValueMap
Maps LLVM Value to the corresponding sandboxir::Value.
Definition: SandboxIR.h:1635
Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
Definition: SandboxIR.cpp:1330
sandboxir::Value * getValue(llvm::Value *V) const
Definition: SandboxIR.cpp:1566
Argument * getOrCreateArgument(llvm::Argument *LLVMArg)
Get or create a sandboxir::Argument for an existing LLVM IR LLVMArg.
Definition: SandboxIR.h:1650
Function * createFunction(llvm::Function *F)
Create a sandboxir::Function for an existing LLVM IR F, including all blocks and instructions.
Definition: SandboxIR.cpp:1573
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: SandboxIR.cpp:1348
std::unique_ptr< Value > detach(Value *V)
Remove SBV from all SandboxIR maps and stop owning it.
Definition: SandboxIR.cpp:1323
UnreachableInst * createUnreachableInst(llvm::UnreachableInst *UI)
Definition: SandboxIR.cpp:1541
BranchInst * createBranchInst(llvm::BranchInst *I)
Definition: SandboxIR.cpp:1506
Constant * getOrCreateConstant(llvm::Constant *LLVMC)
Get or create a sandboxir::Constant from an existing LLVM IR LLVMC.
Definition: SandboxIR.h:1664
BasicBlock * createBasicBlock(llvm::BasicBlock *BB)
Create a sandboxir::BasicBlock for an existing LLVM IR BB.
Definition: SandboxIR.cpp:1478
ExtractElementInst * createExtractElementInst(llvm::ExtractElementInst *EEI)
Definition: SandboxIR.cpp:1493
LoadInst * createLoadInst(llvm::LoadInst *LI)
Definition: SandboxIR.cpp:1511
AllocaInst * createAllocaInst(llvm::AllocaInst *I)
Definition: SandboxIR.cpp:1553
CallInst * createCallInst(llvm::CallInst *I)
Definition: SandboxIR.cpp:1526
std::unique_ptr< Value > detachLLVMValue(llvm::Value *V)
Remove V from the maps and returns the unique_ptr.
Definition: SandboxIR.cpp:1312
StoreInst * createStoreInst(llvm::StoreInst *SI)
Definition: SandboxIR.cpp:1516
Value * getOrCreateValue(llvm::Value *LLVMV)
Get or create a sandboxir::Value for an existing LLVM IR LLVMV.
Definition: SandboxIR.h:1660
InsertElementInst * createInsertElementInst(llvm::InsertElementInst *IEI)
Definition: SandboxIR.cpp:1500
ReturnInst * createReturnInst(llvm::ReturnInst *I)
Definition: SandboxIR.cpp:1521
PHINode * createPHINode(llvm::PHINode *I)
Definition: SandboxIR.cpp:1561
SelectInst * createSelectInst(llvm::SelectInst *SI)
Definition: SandboxIR.cpp:1487
CastInst * createCastInst(llvm::CastInst *I)
Definition: SandboxIR.cpp:1557
friend class BasicBlock
Various leaf nodes.
Definition: SandboxIR.h:1672
InvokeInst * createInvokeInst(llvm::InvokeInst *I)
Definition: SandboxIR.cpp:1531
size_t getNumValues() const
\Returns the number of values registered with Context.
Definition: SandboxIR.h:1731
static Value * create(Value *Vec, Value *Idx, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1238
void dumpNameAndArgs(raw_ostream &OS) const
Definition: SandboxIR.cpp:1274
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:1289
This class can be used for tracking most instruction setters.
Definition: Tracker.h:228
static Value * create(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
static Value * create(Value *Vec, Value *NewElt, Value *Idx, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1212
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: SandboxIR.h:601
BBIterator getIterator() const
\Returns a BasicBlock::iterator for this Instruction.
Definition: SandboxIR.cpp:331
void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
Definition: SandboxIR.cpp:359
virtual unsigned getNumOfIRInstrs() const =0
This is used by BasicBlock::iterator.
static bool classof(const sandboxir::Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:464
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
Definition: SandboxIR.cpp:433
void eraseFromParent()
Detach this Value from its parent and delete it.
Definition: SandboxIR.cpp:367
Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
Definition: SandboxIR.cpp:336
void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
Definition: SandboxIR.cpp:391
llvm::Instruction * getTopmostLLVMInstruction() const
A SandboxIR Instruction may map to multiple LLVM IR Instruction.
Definition: SandboxIR.cpp:319
void insertAfter(Instruction *AfterI)
Insert this detached instruction after AfterI.
Definition: SandboxIR.cpp:429
virtual SmallVector< llvm::Instruction *, 1 > getLLVMInstrs() const =0
\Returns the LLVM IR Instructions that this SandboxIR maps to in program order.
void dumpOS(raw_ostream &OS) const override
Definition: SandboxIR.cpp:476
Instruction * getPrevNode() const
\Returns the previous sandboxir::Instruction in the block, or nullptr if at the beginning of the bloc...
Definition: SandboxIR.cpp:351
void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
Definition: SandboxIR.cpp:415
BasicBlock * getParent() const
\Returns the BasicBlock containing this Instruction, or null if it is detached.
Definition: SandboxIR.cpp:455
Instruction * getLandingPadInst() const
Definition: SandboxIR.cpp:851
BasicBlock * getSuccessor(unsigned SuccIdx) const
Definition: SandboxIR.cpp:856
void setNormalDest(BasicBlock *BB)
Definition: SandboxIR.cpp:843
static InvokeInst * create(FunctionType *FTy, Value *Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef< Value * > Args, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &NameStr="")
Definition: SandboxIR.cpp:797
void setUnwindDest(BasicBlock *BB)
Definition: SandboxIR.cpp:847
BasicBlock * getNormalDest() const
Definition: SandboxIR.cpp:835
BasicBlock * getUnwindDest() const
Definition: SandboxIR.cpp:839
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:627
static LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:592
void setVolatile(bool V)
Specify whether this is a volatile load or not.
Definition: SandboxIR.cpp:585
Value * getPointerOperand() const
Definition: SandboxIR.cpp:631
An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to an OpaqueInstr.
Definition: SandboxIR.h:1614
Iterator for the Use edges of a User's operands.
Definition: SandboxIR.h:136
OperandUseIterator operator+(unsigned Num) const
Definition: SandboxIR.cpp:89
OperandUseIterator operator-(unsigned Num) const
Definition: SandboxIR.cpp:95
OperandUseIterator & operator++()
Definition: SandboxIR.cpp:66
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:1000
void setIncomingBlock(unsigned Idx, BasicBlock *BB)
Definition: SandboxIR.cpp:1023
void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New)
Definition: SandboxIR.cpp:1069
void setIncomingValue(unsigned Idx, Value *V)
Definition: SandboxIR.cpp:1007
unsigned getNumIncomingValues() const
Definition: SandboxIR.h:1575
void addIncoming(Value *V, BasicBlock *BB)
Definition: SandboxIR.cpp:1030
int getBasicBlockIndex(const BasicBlock *BB) const
Definition: SandboxIR.cpp:1055
Value * removeIncomingValue(unsigned Idx)
Definition: SandboxIR.cpp:1037
void removeIncomingValueIf(function_ref< bool(unsigned)> Predicate)
Definition: SandboxIR.cpp:1076
Value * hasConstantValue() const
Definition: SandboxIR.cpp:1065
Value * getIncomingValueForBlock(const BasicBlock *BB) const
Definition: SandboxIR.cpp:1059
BasicBlock * getIncomingBlock(unsigned Idx) const
Definition: SandboxIR.cpp:1014
static PHINode * create(Type *Ty, unsigned NumReservedValues, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:992
Value * getIncomingValue(unsigned Idx) const
Definition: SandboxIR.cpp:1004
Value * getReturnValue() const
\Returns null if there is no return value.
Definition: SandboxIR.cpp:732
static ReturnInst * create(Value *RetVal, Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:717
static Value * create(Value *Cond, Value *True, Value *False, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:492
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:510
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:674
void setVolatile(bool V)
Specify whether this is a volatile store or not.
Definition: SandboxIR.cpp:635
static StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:642
Value * getPointerOperand() const
Definition: SandboxIR.cpp:682
Value * getValueOperand() const
Definition: SandboxIR.cpp:678
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition: Tracker.h:313
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition: Tracker.h:363
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition: Tracker.h:339
bool emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
Definition: Tracker.h:356
static bool classof(const Value *From)
Definition: SandboxIR.cpp:703
static UnreachableInst * create(Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:686
Tracks the change of the source Value of a sandboxir::Use.
Definition: Tracker.h:85
Tracks swapping a Use with another Use.
Definition: Tracker.h:149
Represents a Def-use/Use-def edge in SandboxIR.
Definition: Use.h:32
void dumpOS(raw_ostream &OS) const
Definition: SandboxIR.cpp:33
unsigned getOperandNo() const
Definition: SandboxIR.cpp:25
Value * get() const
Definition: SandboxIR.cpp:18
void set(Value *V)
Definition: SandboxIR.cpp:20
void swap(Use &OtherUse)
Definition: SandboxIR.cpp:27
class User * getUser() const
Definition: Use.h:54
void dump() const
Definition: SandboxIR.cpp:61
Iterator for the Use edges of a Value's users.
Definition: SandboxIR.h:172
UserUseIterator & operator++()
Definition: SandboxIR.cpp:73
A sandboxir::User has operands.
Definition: SandboxIR.h:389
virtual unsigned getUseOperandNo(const Use &Use) const =0
\Returns the operand index of Use.
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:238
bool replaceUsesOfWith(Value *FromV, Value *ToV)
Replaces any operands that match FromV with ToV.
Definition: SandboxIR.cpp:260
void verifyUserOfLLVMUse(const llvm::Use &Use) const
Definition: SandboxIR.cpp:232
Use getOperandUseDefault(unsigned OpIdx, bool Verify) const
\Returns the Use edge that corresponds to OpIdx.
Definition: SandboxIR.cpp:220
virtual void setOperand(unsigned OperandIdx, Value *Operand)
Definition: SandboxIR.cpp:253
virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const =0
\Returns the Use for the OpIdx'th operand.
virtual unsigned getNumOperands() const
Definition: SandboxIR.h:459
Use getOperandUse(unsigned OpIdx) const
\Returns the operand edge for OpIdx.
Definition: SandboxIR.h:456
void dumpCommonHeader(raw_ostream &OS) const final
Definition: SandboxIR.cpp:274
A SandboxIR Value has users. This is the base class.
Definition: SandboxIR.h:198
mapped_iterator< sandboxir::UserUseIterator, UseToUser > user_iterator
Definition: SandboxIR.h:295
LLVM_DUMP_METHOD void dump() const
Definition: SandboxIR.cpp:206
use_iterator use_begin()
Definition: SandboxIR.cpp:115
llvm::Value * Val
The LLVM Value that corresponds to this SandboxIR Value.
Definition: SandboxIR.h:234
std::string getUid() const
Returns the unique id in the form 'SB<number>.' like 'SB1.'.
Definition: SandboxIR.cpp:169
user_iterator user_begin()
Definition: SandboxIR.cpp:125
void replaceAllUsesWith(Value *Other)
Definition: SandboxIR.cpp:156
void dumpCommonFooter(raw_ostream &OS) const
Definition: SandboxIR.cpp:179
virtual void dumpCommonHeader(raw_ostream &OS) const
Definition: SandboxIR.cpp:175
UserUseIterator use_iterator
Definition: SandboxIR.h:271
Context & Ctx
All values point to the context.
Definition: SandboxIR.h:257
ClassID SubclassID
For isa/dyn_cast.
Definition: SandboxIR.h:225
void dumpCommonSuffix(raw_ostream &OS) const
Definition: SandboxIR.cpp:195
Type * getType() const
Definition: SandboxIR.h:339
friend class Use
Definition: SandboxIR.h:238
Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
Definition: SandboxIR.cpp:108
iterator_range< user_iterator > users()
Definition: SandboxIR.h:309
void replaceUsesWithIf(Value *OtherV, llvm::function_ref< bool(const Use &)> ShouldReplace)
Definition: SandboxIR.cpp:138
unsigned getNumUses() const
\Returns the number of user edges (not necessarily to unique users).
Definition: SandboxIR.cpp:136
unsigned UID
A unique ID used for forming the name (used for debugging).
Definition: SandboxIR.h:228
virtual void dumpOS(raw_ostream &OS) const =0
iterator_range< use_iterator > uses()
Definition: SandboxIR.h:283
void dumpCommonPrefix(raw_ostream &OS) const
Definition: SandboxIR.cpp:188
void printAsOperandCommon(raw_ostream &OS) const
Definition: SandboxIR.cpp:199
static const char * getSubclassIDStr(ClassID ID)
Definition: SandboxIR.h:208
@ LLVMCallBr
Definition: Core.h:69
@ LLVMUnreachable
Definition: Core.h:68
@ LLVMCall
Definition: Core.h:121
@ LLVMRet
Definition: Core.h:62
@ LLVMInvoke
Definition: Core.h:66
@ LLVMBr
Definition: Core.h:63
@ LLVMAlloca
Definition: Core.h:97
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2406
void interleave(ForwardIterator begin, ForwardIterator end, UnaryFunctor each_fn, NullaryFunctor between_fn)
An STL-style algorithm similar to std::for_each that applies a second functor between every pair of e...
Definition: STLExtras.h:2127
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:419
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
Definition: STLExtras.h:1705
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1902
@ Other
Any other memory.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Helper for mapped_iterator.
Definition: SandboxIR.h:291