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
479 this);
480 cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B);
481}
482
487 cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B);
488}
489
494 cast<llvm::Instruction>(Val)->setFast(B);
495}
496
501 cast<llvm::Instruction>(Val)->setIsExact(B);
502}
503
508 cast<llvm::Instruction>(Val)->setHasAllowReassoc(B);
509}
510
515 this);
516 cast<llvm::Instruction>(Val)->setHasNoNaNs(B);
517}
518
523 this);
524 cast<llvm::Instruction>(Val)->setHasNoInfs(B);
525}
526
531 this);
532 cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B);
533}
534
539 this);
540 cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B);
541}
542
547 this);
548 cast<llvm::Instruction>(Val)->setHasAllowContract(B);
549}
550
555 cast<llvm::Instruction>(Val)->setFastMathFlags(FMF);
556}
557
562 cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF);
563}
564
569 cast<llvm::Instruction>(Val)->setHasApproxFunc(B);
570}
571
572#ifndef NDEBUG
574 OS << "Unimplemented! Please override dump().";
575}
576#endif // NDEBUG
577
578Value *SelectInst::createCommon(Value *Cond, Value *True, Value *False,
579 const Twine &Name, IRBuilder<> &Builder,
580 Context &Ctx) {
581 llvm::Value *NewV =
582 Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
583 if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
584 return Ctx.createSelectInst(NewSI);
585 assert(isa<llvm::Constant>(NewV) && "Expected constant");
586 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
587}
588
590 Instruction *InsertBefore, Context &Ctx,
591 const Twine &Name) {
592 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
593 auto &Builder = Ctx.getLLVMIRBuilder();
594 Builder.SetInsertPoint(BeforeIR);
595 return createCommon(Cond, True, False, Name, Builder, Ctx);
596}
597
599 BasicBlock *InsertAtEnd, Context &Ctx,
600 const Twine &Name) {
601 auto *IRInsertAtEnd = cast<llvm::BasicBlock>(InsertAtEnd->Val);
602 auto &Builder = Ctx.getLLVMIRBuilder();
603 Builder.SetInsertPoint(IRInsertAtEnd);
604 return createCommon(Cond, True, False, Name, Builder, Ctx);
605}
606
608 return From->getSubclassID() == ClassID::Select;
609}
610
612 Context &Ctx) {
613 auto &Builder = Ctx.getLLVMIRBuilder();
614 llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
615 Builder.SetInsertPoint(cast<llvm::Instruction>(LLVMBefore));
616 llvm::BranchInst *NewBr =
617 Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
618 return Ctx.createBranchInst(NewBr);
619}
620
622 Context &Ctx) {
623 auto &Builder = Ctx.getLLVMIRBuilder();
624 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
625 llvm::BranchInst *NewBr =
626 Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
627 return Ctx.createBranchInst(NewBr);
628}
629
631 Value *Cond, Instruction *InsertBefore,
632 Context &Ctx) {
633 auto &Builder = Ctx.getLLVMIRBuilder();
634 llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
635 Builder.SetInsertPoint(LLVMBefore);
636 llvm::BranchInst *NewBr =
637 Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
638 cast<llvm::BasicBlock>(IfFalse->Val));
639 return Ctx.createBranchInst(NewBr);
640}
641
643 Value *Cond, BasicBlock *InsertAtEnd,
644 Context &Ctx) {
645 auto &Builder = Ctx.getLLVMIRBuilder();
646 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
647 llvm::BranchInst *NewBr =
648 Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
649 cast<llvm::BasicBlock>(IfFalse->Val));
650 return Ctx.createBranchInst(NewBr);
651}
652
654 return From->getSubclassID() == ClassID::Br;
655}
656
658 assert(isConditional() && "Cannot get condition of an uncond branch!");
659 return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition());
660}
661
662BasicBlock *BranchInst::getSuccessor(unsigned SuccIdx) const {
663 assert(SuccIdx < getNumSuccessors() &&
664 "Successor # out of range for Branch!");
665 return cast_or_null<BasicBlock>(
666 Ctx.getValue(cast<llvm::BranchInst>(Val)->getSuccessor(SuccIdx)));
667}
668
669void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
670 assert((Idx == 0 || Idx == 1) && "Out of bounds!");
671 setOperand(2u - Idx, NewSucc);
672}
673
674BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
675 return cast<BasicBlock>(Ctx.getValue(BB));
676}
677const BasicBlock *
678BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
679 return cast<BasicBlock>(Ctx.getValue(BB));
680}
681
686 cast<llvm::LoadInst>(Val)->setVolatile(V);
687}
688
690 Instruction *InsertBefore, Context &Ctx,
691 const Twine &Name) {
692 return create(Ty, Ptr, Align, InsertBefore, /*IsVolatile=*/false, Ctx, Name);
693}
694
696 Instruction *InsertBefore, bool IsVolatile,
697 Context &Ctx, const Twine &Name) {
698 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
699 auto &Builder = Ctx.getLLVMIRBuilder();
700 Builder.SetInsertPoint(BeforeIR);
701 auto *NewLI =
702 Builder.CreateAlignedLoad(Ty, Ptr->Val, Align, IsVolatile, Name);
703 auto *NewSBI = Ctx.createLoadInst(NewLI);
704 return NewSBI;
705}
706
708 BasicBlock *InsertAtEnd, Context &Ctx,
709 const Twine &Name) {
710 return create(Ty, Ptr, Align, InsertAtEnd, /*IsVolatile=*/false, Ctx, Name);
711}
712
714 BasicBlock *InsertAtEnd, bool IsVolatile,
715 Context &Ctx, const Twine &Name) {
716 auto &Builder = Ctx.getLLVMIRBuilder();
717 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
718 auto *NewLI =
719 Builder.CreateAlignedLoad(Ty, Ptr->Val, Align, IsVolatile, Name);
720 auto *NewSBI = Ctx.createLoadInst(NewLI);
721 return NewSBI;
722}
723
725 return From->getSubclassID() == ClassID::Load;
726}
727
729 return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());
730}
731
736 cast<llvm::StoreInst>(Val)->setVolatile(V);
737}
738
740 Instruction *InsertBefore, Context &Ctx) {
741 return create(V, Ptr, Align, InsertBefore, /*IsVolatile=*/false, Ctx);
742}
743
745 Instruction *InsertBefore, bool IsVolatile,
746 Context &Ctx) {
747 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
748 auto &Builder = Ctx.getLLVMIRBuilder();
749 Builder.SetInsertPoint(BeforeIR);
750 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
751 auto *NewSBI = Ctx.createStoreInst(NewSI);
752 return NewSBI;
753}
754
756 BasicBlock *InsertAtEnd, Context &Ctx) {
757 return create(V, Ptr, Align, InsertAtEnd, /*IsVolatile=*/false, Ctx);
758}
759
761 BasicBlock *InsertAtEnd, bool IsVolatile,
762 Context &Ctx) {
763 auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->Val);
764 auto &Builder = Ctx.getLLVMIRBuilder();
765 Builder.SetInsertPoint(InsertAtEndIR);
766 auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
767 auto *NewSBI = Ctx.createStoreInst(NewSI);
768 return NewSBI;
769}
770
772 return From->getSubclassID() == ClassID::Store;
773}
774
776 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
777}
778
780 return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
781}
782
784 Context &Ctx) {
785 auto &Builder = Ctx.getLLVMIRBuilder();
786 llvm::Instruction *LLVMBefore = InsertBefore->getTopmostLLVMInstruction();
787 Builder.SetInsertPoint(LLVMBefore);
788 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
789 return Ctx.createUnreachableInst(NewUI);
790}
791
793 Context &Ctx) {
794 auto &Builder = Ctx.getLLVMIRBuilder();
795 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
796 llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
797 return Ctx.createUnreachableInst(NewUI);
798}
799
801 return From->getSubclassID() == ClassID::Unreachable;
802}
803
804ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
805 Context &Ctx) {
806 llvm::ReturnInst *NewRI;
807 if (RetVal != nullptr)
808 NewRI = Builder.CreateRet(RetVal->Val);
809 else
810 NewRI = Builder.CreateRetVoid();
811 return Ctx.createReturnInst(NewRI);
812}
813
815 Context &Ctx) {
816 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
817 auto &Builder = Ctx.getLLVMIRBuilder();
818 Builder.SetInsertPoint(BeforeIR);
819 return createCommon(RetVal, Builder, Ctx);
820}
821
823 Context &Ctx) {
824 auto &Builder = Ctx.getLLVMIRBuilder();
825 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
826 return createCommon(RetVal, Builder, Ctx);
827}
828
830 auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
831 return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
832}
833
835 return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());
836}
837
839 llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
840 return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
841}
842
844 return cast_or_null<Function>(
845 Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
846}
848 return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
849}
850
852 // F's function type is private, so we rely on `setCalledFunction()` to update
853 // it. But even though we are calling `setCalledFunction()` we also need to
854 // track this change at the SandboxIR level, which is why we call
855 // `setCalledOperand()` here.
856 // Note: This may break if `setCalledFunction()` early returns if `F`
857 // is already set, but we do have a unit test for it.
859 cast<llvm::CallBase>(Val)->setCalledFunction(F->getFunctionType(),
860 cast<llvm::Function>(F->Val));
861}
862
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));
873 LLVMArgs.reserve(Args.size());
874 for (Value *Arg : Args)
875 LLVMArgs.push_back(Arg->Val);
876 llvm::CallInst *NewCI = Builder.CreateCall(FTy, Func->Val, LLVMArgs, NameStr);
877 return Ctx.createCallInst(NewCI);
878}
879
881 ArrayRef<Value *> Args, Instruction *InsertBefore,
882 Context &Ctx, const Twine &NameStr) {
883 return CallInst::create(FTy, Func, Args, InsertBefore->getIterator(),
884 InsertBefore->getParent(), Ctx, NameStr);
885}
886
888 ArrayRef<Value *> Args, BasicBlock *InsertAtEnd,
889 Context &Ctx, const Twine &NameStr) {
890 return CallInst::create(FTy, Func, Args, InsertAtEnd->end(), InsertAtEnd, Ctx,
891 NameStr);
892}
893
895 BasicBlock *IfNormal, BasicBlock *IfException,
896 ArrayRef<Value *> Args, BBIterator WhereIt,
897 BasicBlock *WhereBB, Context &Ctx,
898 const Twine &NameStr) {
899 auto &Builder = Ctx.getLLVMIRBuilder();
900 if (WhereIt != WhereBB->end())
901 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
902 else
903 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
905 LLVMArgs.reserve(Args.size());
906 for (Value *Arg : Args)
907 LLVMArgs.push_back(Arg->Val);
908 llvm::InvokeInst *Invoke = Builder.CreateInvoke(
909 FTy, Func->Val, cast<llvm::BasicBlock>(IfNormal->Val),
910 cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
911 return Ctx.createInvokeInst(Invoke);
912}
913
915 BasicBlock *IfNormal, BasicBlock *IfException,
917 Instruction *InsertBefore, Context &Ctx,
918 const Twine &NameStr) {
919 return create(FTy, Func, IfNormal, IfException, Args,
920 InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
921 NameStr);
922}
923
925 BasicBlock *IfNormal, BasicBlock *IfException,
926 ArrayRef<Value *> Args, BasicBlock *InsertAtEnd,
927 Context &Ctx, const Twine &NameStr) {
928 return create(FTy, Func, IfNormal, IfException, Args, InsertAtEnd->end(),
929 InsertAtEnd, Ctx, NameStr);
930}
931
933 return cast<BasicBlock>(
934 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
935}
937 return cast<BasicBlock>(
938 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
939}
941 setOperand(1, BB);
942 assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
943}
945 setOperand(2, BB);
946 assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
947}
949 return cast<Instruction>(
950 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
951 ;
952}
953BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
954 return cast<BasicBlock>(
955 Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
956}
957
959 BasicBlock *DefaultDest,
960 ArrayRef<BasicBlock *> IndirectDests,
961 ArrayRef<Value *> Args, BBIterator WhereIt,
962 BasicBlock *WhereBB, Context &Ctx,
963 const Twine &NameStr) {
964 auto &Builder = Ctx.getLLVMIRBuilder();
965 if (WhereIt != WhereBB->end())
966 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
967 else
968 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
969
970 SmallVector<llvm::BasicBlock *> LLVMIndirectDests;
971 LLVMIndirectDests.reserve(IndirectDests.size());
972 for (BasicBlock *IndDest : IndirectDests)
973 LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
974
976 LLVMArgs.reserve(Args.size());
977 for (Value *Arg : Args)
978 LLVMArgs.push_back(Arg->Val);
979
980 llvm::CallBrInst *CallBr = Builder.CreateCallBr(
981 FTy, Func->Val, cast<llvm::BasicBlock>(DefaultDest->Val),
982 LLVMIndirectDests, LLVMArgs, NameStr);
983 return Ctx.createCallBrInst(CallBr);
984}
985
987 BasicBlock *DefaultDest,
988 ArrayRef<BasicBlock *> IndirectDests,
990 Instruction *InsertBefore, Context &Ctx,
991 const Twine &NameStr) {
992 return create(FTy, Func, DefaultDest, IndirectDests, Args,
993 InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
994 NameStr);
995}
997 BasicBlock *DefaultDest,
998 ArrayRef<BasicBlock *> IndirectDests,
999 ArrayRef<Value *> Args, BasicBlock *InsertAtEnd,
1000 Context &Ctx, const Twine &NameStr) {
1001 return create(FTy, Func, DefaultDest, IndirectDests, Args, InsertAtEnd->end(),
1002 InsertAtEnd, Ctx, NameStr);
1003}
1004
1006 return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
1007}
1009 return Ctx.getValue(
1010 cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx));
1011}
1013 return cast<BasicBlock>(
1014 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
1015}
1017 return cast<BasicBlock>(
1018 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
1019}
1022 for (llvm::BasicBlock *LLVMBB :
1023 cast<llvm::CallBrInst>(Val)->getIndirectDests())
1024 BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
1025 return BBs;
1026}
1028 Ctx.getTracker()
1031 cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
1032}
1034 Ctx.getTracker()
1037 this, Idx);
1038 cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
1039 cast<llvm::BasicBlock>(BB->Val));
1040}
1042 return cast<BasicBlock>(
1043 Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
1044}
1045
1047 ArrayRef<Value *> IdxList,
1048 BasicBlock::iterator WhereIt,
1049 BasicBlock *WhereBB, Context &Ctx,
1050 const Twine &NameStr) {
1051 auto &Builder = Ctx.getLLVMIRBuilder();
1052 if (WhereIt != WhereBB->end())
1053 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1054 else
1055 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1056 SmallVector<llvm::Value *> LLVMIdxList;
1057 LLVMIdxList.reserve(IdxList.size());
1058 for (Value *Idx : IdxList)
1059 LLVMIdxList.push_back(Idx->Val);
1060 llvm::Value *NewV = Builder.CreateGEP(Ty, Ptr->Val, LLVMIdxList, NameStr);
1061 if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
1062 return Ctx.createGetElementPtrInst(NewGEP);
1063 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1064 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1065}
1066
1068 ArrayRef<Value *> IdxList,
1069 Instruction *InsertBefore, Context &Ctx,
1070 const Twine &NameStr) {
1071 return GetElementPtrInst::create(Ty, Ptr, IdxList,
1072 InsertBefore->getIterator(),
1073 InsertBefore->getParent(), Ctx, NameStr);
1074}
1075
1077 ArrayRef<Value *> IdxList,
1078 BasicBlock *InsertAtEnd, Context &Ctx,
1079 const Twine &NameStr) {
1080 return GetElementPtrInst::create(Ty, Ptr, IdxList, InsertAtEnd->end(),
1081 InsertAtEnd, Ctx, NameStr);
1082}
1083
1085 return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand());
1086}
1087
1088BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
1089 return cast<BasicBlock>(Ctx.getValue(LLVMBB));
1090}
1091
1092PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
1093 Instruction *InsertBefore, Context &Ctx,
1094 const Twine &Name) {
1096 Ty, NumReservedValues, Name, InsertBefore->getTopmostLLVMInstruction());
1097 return Ctx.createPHINode(NewPHI);
1098}
1099
1101 return From->getSubclassID() == ClassID::PHI;
1102}
1103
1105 return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
1106}
1108 Ctx.getTracker()
1111 Idx);
1112 cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
1113}
1115 return cast<BasicBlock>(
1116 Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
1117}
1119 llvm::Use *LLVMUse = U.LLVMUse;
1120 llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
1121 return cast<BasicBlock>(Ctx.getValue(BB));
1122}
1124 // Helper to disambiguate PHINode::getIncomingBlock(unsigned).
1125 constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const =
1127 Ctx.getTracker()
1130 this, Idx);
1131 cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
1132 cast<llvm::BasicBlock>(BB->Val));
1133}
1135 auto &Tracker = Ctx.getTracker();
1137
1138 cast<llvm::PHINode>(Val)->addIncoming(V->Val,
1139 cast<llvm::BasicBlock>(BB->Val));
1140}
1142 auto &Tracker = Ctx.getTracker();
1144 llvm::Value *LLVMV =
1145 cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
1146 /*DeletePHIIfEmpty=*/false);
1147 return Ctx.getValue(LLVMV);
1148}
1150 auto &Tracker = Ctx.getTracker();
1152
1153 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
1154 llvm::Value *LLVMV =
1155 cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
1156 /*DeletePHIIfEmpty=*/false);
1157 return Ctx.getValue(LLVMV);
1158}
1160 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
1161 return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
1162}
1164 auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
1165 llvm::Value *LLVMV =
1166 cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
1167 return Ctx.getValue(LLVMV);
1168}
1170 llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
1171 return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
1172}
1174 assert(New && Old && "Sandbox IR PHI node got a null basic block!");
1175 for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
1176 Idx != NumOps; ++Idx)
1177 if (getIncomingBlock(Idx) == Old)
1178 setIncomingBlock(Idx, New);
1179}
1180void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
1181 // Avoid duplicate tracking by going through this->removeIncomingValue here at
1182 // the expense of some performance. Copy PHI::removeIncomingValueIf more
1183 // directly if performance becomes an issue.
1184
1185 // Removing the element at index X, moves the element previously at X + 1
1186 // to X. Working from the end avoids complications from that.
1187 unsigned Idx = getNumIncomingValues();
1188 while (Idx > 0) {
1189 if (Predicate(Idx - 1))
1191 --Idx;
1192 }
1193}
1194
1196 switch (Opc) {
1197 case Instruction::Opcode::ZExt:
1198 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
1199 case Instruction::Opcode::SExt:
1200 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
1201 case Instruction::Opcode::FPToUI:
1202 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
1203 case Instruction::Opcode::FPToSI:
1204 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
1205 case Instruction::Opcode::FPExt:
1206 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
1207 case Instruction::Opcode::PtrToInt:
1208 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
1209 case Instruction::Opcode::IntToPtr:
1210 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
1211 case Instruction::Opcode::SIToFP:
1212 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
1213 case Instruction::Opcode::UIToFP:
1214 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
1215 case Instruction::Opcode::Trunc:
1216 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
1217 case Instruction::Opcode::FPTrunc:
1218 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
1219 case Instruction::Opcode::BitCast:
1220 return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
1221 case Instruction::Opcode::AddrSpaceCast:
1222 return static_cast<llvm::Instruction::CastOps>(
1223 llvm::Instruction::AddrSpaceCast);
1224 default:
1225 llvm_unreachable("Opcode not suitable for CastInst!");
1226 }
1227}
1228
1229/// \Returns the LLVM opcode that corresponds to \p Opc.
1231 switch (Opc) {
1232 case Instruction::Opcode::FNeg:
1233 return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);
1234 default:
1235 llvm_unreachable("Not a unary op!");
1236 }
1237}
1238
1240 unsigned NumHandlers,
1241 BBIterator WhereIt,
1242 BasicBlock *WhereBB, Context &Ctx,
1243 const Twine &Name) {
1244 auto &Builder = Ctx.getLLVMIRBuilder();
1245 if (WhereIt != WhereBB->end())
1246 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1247 else
1248 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1249 llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(
1250 ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);
1251 return Ctx.createCatchSwitchInst(LLVMCSI);
1252}
1253
1255 return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad());
1256}
1257
1259 Ctx.getTracker()
1262 cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);
1263}
1264
1266 return cast_or_null<BasicBlock>(
1267 Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));
1268}
1269
1271 Ctx.getTracker()
1274 cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(
1275 cast<llvm::BasicBlock>(UnwindDest->Val));
1276}
1277
1280 cast<llvm::CatchSwitchInst>(Val)->addHandler(
1281 cast<llvm::BasicBlock>(Dest->Val));
1282}
1283
1284SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
1285 BasicBlock::iterator WhereIt,
1286 BasicBlock *WhereBB, Context &Ctx,
1287 const Twine &Name) {
1288 auto &Builder = Ctx.getLLVMIRBuilder();
1289 if (WhereIt != WhereBB->end())
1290 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1291 else
1292 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1294 Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
1296}
1297
1299 return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
1300}
1301
1303 Ctx.getTracker()
1306 this);
1307 cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
1308}
1309
1311 return cast<BasicBlock>(
1312 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
1313}
1314
1316 Ctx.getTracker()
1319 cast<llvm::SwitchInst>(Val)->setDefaultDest(
1320 cast<llvm::BasicBlock>(DefaultCase->Val));
1321}
1323 auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
1324 cast<llvm::BasicBlock>(BB->Val));
1325 return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
1326}
1327
1330 // TODO: Track this!
1331 cast<llvm::SwitchInst>(Val)->addCase(cast<llvm::ConstantInt>(OnVal->Val),
1332 cast<llvm::BasicBlock>(Dest->Val));
1333}
1334
1336 auto &Case = *It;
1338 this, Case.getCaseValue(), Case.getCaseSuccessor());
1339
1340 auto *LLVMSwitch = cast<llvm::SwitchInst>(Val);
1341 unsigned CaseNum = It - case_begin();
1342 llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
1343 auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
1344 unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
1345 return CaseIt(this, Num);
1346}
1347
1349 return cast<BasicBlock>(
1350 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
1351}
1352
1353void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1354 Ctx.getTracker()
1357 Idx);
1358 cast<llvm::SwitchInst>(Val)->setSuccessor(
1359 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
1360}
1361
1363 BBIterator WhereIt, BasicBlock *WhereBB,
1364 Context &Ctx, const Twine &Name) {
1365 auto &Builder = Ctx.getLLVMIRBuilder();
1366 if (WhereIt == WhereBB->end())
1367 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1368 else
1369 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1370 auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
1371 if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1372 return Ctx.createUnaryOperator(NewUnOpV);
1373 }
1374 assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
1375 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
1376}
1377
1379 Instruction *InsertBefore, Context &Ctx,
1380 const Twine &Name) {
1381 return create(Op, OpV, InsertBefore->getIterator(), InsertBefore->getParent(),
1382 Ctx, Name);
1383}
1384
1386 BasicBlock *InsertAfter, Context &Ctx,
1387 const Twine &Name) {
1388 return create(Op, OpV, InsertAfter->end(), InsertAfter, Ctx, Name);
1389}
1390
1392 Value *CopyFrom, BBIterator WhereIt,
1393 BasicBlock *WhereBB, Context &Ctx,
1394 const Twine &Name) {
1395 auto *NewV = create(Op, OpV, WhereIt, WhereBB, Ctx, Name);
1396 if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1397 UnI->copyIRFlags(CopyFrom->Val);
1398 return NewV;
1399}
1400
1402 Value *CopyFrom,
1403 Instruction *InsertBefore,
1404 Context &Ctx, const Twine &Name) {
1405 return createWithCopiedFlags(Op, OpV, CopyFrom, InsertBefore->getIterator(),
1406 InsertBefore->getParent(), Ctx, Name);
1407}
1408
1410 Value *CopyFrom,
1411 BasicBlock *InsertAtEnd,
1412 Context &Ctx, const Twine &Name) {
1413 return createWithCopiedFlags(Op, OpV, CopyFrom, InsertAtEnd->end(),
1414 InsertAtEnd, Ctx, Name);
1415}
1416
1417/// \Returns the LLVM opcode that corresponds to \p Opc.
1419 switch (Opc) {
1420 case Instruction::Opcode::Add:
1421 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
1422 case Instruction::Opcode::FAdd:
1423 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
1424 case Instruction::Opcode::Sub:
1425 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
1426 case Instruction::Opcode::FSub:
1427 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
1428 case Instruction::Opcode::Mul:
1429 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
1430 case Instruction::Opcode::FMul:
1431 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
1432 case Instruction::Opcode::UDiv:
1433 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
1434 case Instruction::Opcode::SDiv:
1435 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
1436 case Instruction::Opcode::FDiv:
1437 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
1438 case Instruction::Opcode::URem:
1439 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
1440 case Instruction::Opcode::SRem:
1441 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
1442 case Instruction::Opcode::FRem:
1443 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
1444 case Instruction::Opcode::Shl:
1445 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
1446 case Instruction::Opcode::LShr:
1447 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
1448 case Instruction::Opcode::AShr:
1449 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
1450 case Instruction::Opcode::And:
1451 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
1452 case Instruction::Opcode::Or:
1453 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
1454 case Instruction::Opcode::Xor:
1455 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
1456 default:
1457 llvm_unreachable("Not a binary op!");
1458 }
1459}
1461 BBIterator WhereIt, BasicBlock *WhereBB,
1462 Context &Ctx, const Twine &Name) {
1463 auto &Builder = Ctx.getLLVMIRBuilder();
1464 if (WhereIt == WhereBB->end())
1465 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1466 else
1467 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1468 llvm::Value *NewV =
1470 if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1471 return Ctx.createBinaryOperator(NewBinOp);
1472 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1473 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1474}
1475
1477 Instruction *InsertBefore, Context &Ctx,
1478 const Twine &Name) {
1479 return create(Op, LHS, RHS, InsertBefore->getIterator(),
1480 InsertBefore->getParent(), Ctx, Name);
1481}
1482
1484 BasicBlock *InsertAtEnd, Context &Ctx,
1485 const Twine &Name) {
1486 return create(Op, LHS, RHS, InsertAtEnd->end(), InsertAtEnd, Ctx, Name);
1487}
1488
1490 Value *RHS, Value *CopyFrom,
1491 BBIterator WhereIt,
1492 BasicBlock *WhereBB, Context &Ctx,
1493 const Twine &Name) {
1494
1495 Value *NewV = create(Op, LHS, RHS, WhereIt, WhereBB, Ctx, Name);
1496 if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1497 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
1498 return NewV;
1499}
1500
1502 Value *RHS, Value *CopyFrom,
1503 Instruction *InsertBefore,
1504 Context &Ctx, const Twine &Name) {
1505 return createWithCopiedFlags(Op, LHS, RHS, CopyFrom,
1506 InsertBefore->getIterator(),
1507 InsertBefore->getParent(), Ctx, Name);
1508}
1509
1511 Value *RHS, Value *CopyFrom,
1512 BasicBlock *InsertAtEnd,
1513 Context &Ctx, const Twine &Name) {
1514 return createWithCopiedFlags(Op, LHS, RHS, CopyFrom, InsertAtEnd->end(),
1515 InsertAtEnd, Ctx, Name);
1516}
1517
1519 Ctx.getTracker()
1522 cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
1523}
1524
1526 Ctx.getTracker()
1529 cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
1530}
1531
1533 Ctx.getTracker()
1536 cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
1537}
1538
1540 Ctx.getTracker()
1543 cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);
1544}
1545
1547 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getPointerOperand());
1548}
1549
1551 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getValOperand());
1552}
1553
1556 BBIterator WhereIt, BasicBlock *WhereBB,
1557 Context &Ctx, SyncScope::ID SSID,
1558 const Twine &Name) {
1559 auto &Builder = Ctx.getLLVMIRBuilder();
1560 if (WhereIt == WhereBB->end())
1561 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1562 else
1563 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1564 auto *LLVMAtomicRMW =
1565 Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
1566 LLVMAtomicRMW->setName(Name);
1568}
1569
1572 Instruction *InsertBefore, Context &Ctx,
1573 SyncScope::ID SSID, const Twine &Name) {
1574 return create(Op, Ptr, Val, Align, Ordering, InsertBefore->getIterator(),
1575 InsertBefore->getParent(), Ctx, SSID, Name);
1576}
1577
1580 BasicBlock *InsertAtEnd, Context &Ctx,
1581 SyncScope::ID SSID, const Twine &Name) {
1582 return create(Op, Ptr, Val, Align, Ordering, InsertAtEnd->end(), InsertAtEnd,
1583 Ctx, SSID, Name);
1584}
1585
1587 Ctx.getTracker()
1590 this);
1591 cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
1592}
1593
1595 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());
1596}
1597
1599 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());
1600}
1601
1603 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
1604}
1605
1608 AtomicOrdering SuccessOrdering,
1609 AtomicOrdering FailureOrdering, BBIterator WhereIt,
1610 BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID,
1611 const Twine &Name) {
1612 auto &Builder = Ctx.getLLVMIRBuilder();
1613 if (WhereIt == WhereBB->end())
1614 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1615 else
1616 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1617 auto *LLVMAtomicCmpXchg =
1618 Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1619 SuccessOrdering, FailureOrdering, SSID);
1620 LLVMAtomicCmpXchg->setName(Name);
1622}
1623
1626 AtomicOrdering SuccessOrdering,
1627 AtomicOrdering FailureOrdering,
1628 Instruction *InsertBefore,
1629 Context &Ctx, SyncScope::ID SSID,
1630 const Twine &Name) {
1631 return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
1632 InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
1633 SSID, Name);
1634}
1635
1638 AtomicOrdering SuccessOrdering,
1639 AtomicOrdering FailureOrdering,
1640 BasicBlock *InsertAtEnd,
1641 Context &Ctx, SyncScope::ID SSID,
1642 const Twine &Name) {
1643 return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
1644 InsertAtEnd->end(), InsertAtEnd, Ctx, SSID, Name);
1645}
1646
1648 Ctx.getTracker()
1651 cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1652}
1653
1655 Ctx.getTracker()
1658 cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1659}
1660
1662 Ctx.getTracker()
1665 cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1666}
1667
1669 Ctx.getTracker()
1672 this);
1673 cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1674}
1675
1677 Ctx.getTracker()
1680 this);
1681 cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1682}
1683
1684AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
1685 BasicBlock *WhereBB, Context &Ctx,
1686 Value *ArraySize, const Twine &Name) {
1687 auto &Builder = Ctx.getLLVMIRBuilder();
1688 if (WhereIt == WhereBB->end())
1689 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1690 else
1691 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1692 auto *NewAlloca = Builder.CreateAlloca(Ty, AddrSpace, ArraySize->Val, Name);
1693 return Ctx.createAllocaInst(NewAlloca);
1694}
1695
1696AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
1697 Instruction *InsertBefore, Context &Ctx,
1698 Value *ArraySize, const Twine &Name) {
1699 return create(Ty, AddrSpace, InsertBefore->getIterator(),
1700 InsertBefore->getParent(), Ctx, ArraySize, Name);
1701}
1702
1703AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
1704 BasicBlock *InsertAtEnd, Context &Ctx,
1705 Value *ArraySize, const Twine &Name) {
1706 return create(Ty, AddrSpace, InsertAtEnd->end(), InsertAtEnd, Ctx, ArraySize,
1707 Name);
1708}
1709
1711 Ctx.getTracker()
1714 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty);
1715}
1716
1718 Ctx.getTracker()
1721 this);
1722 cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1723}
1724
1726 Ctx.getTracker()
1729 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1730}
1731
1733 return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
1734}
1735
1737 BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
1738 const Twine &Name) {
1739 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1740 auto &Builder = Ctx.getLLVMIRBuilder();
1741 if (WhereIt == WhereBB->end())
1742 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1743 else
1744 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1745 auto *NewV =
1746 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy, Name);
1747 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1748 return Ctx.createCastInst(NewCI);
1749 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1750 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1751}
1752
1754 Instruction *InsertBefore, Context &Ctx,
1755 const Twine &Name) {
1756 return create(DestTy, Op, Operand, InsertBefore->getIterator(),
1757 InsertBefore->getParent(), Ctx, Name);
1758}
1759
1761 BasicBlock *InsertAtEnd, Context &Ctx,
1762 const Twine &Name) {
1763 return create(DestTy, Op, Operand, InsertAtEnd->end(), InsertAtEnd, Ctx,
1764 Name);
1765}
1766
1768 return From->getSubclassID() == ClassID::Cast;
1769}
1770
1772 Instruction *InsertBefore, Context &Ctx,
1773 const Twine &Name) {
1774 auto &Builder = Ctx.getLLVMIRBuilder();
1775 Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
1776 llvm::Value *NewV =
1777 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1778 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1779 return Ctx.createInsertElementInst(NewInsert);
1780 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1781 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1782}
1783
1785 BasicBlock *InsertAtEnd, Context &Ctx,
1786 const Twine &Name) {
1787 auto &Builder = Ctx.getLLVMIRBuilder();
1788 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
1789 llvm::Value *NewV =
1790 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1791 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1792 return Ctx.createInsertElementInst(NewInsert);
1793 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1794 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1795}
1796
1798 Instruction *InsertBefore, Context &Ctx,
1799 const Twine &Name) {
1800 auto &Builder = Ctx.getLLVMIRBuilder();
1801 Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
1802 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1803 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1804 return Ctx.createExtractElementInst(NewExtract);
1805 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1806 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1807}
1808
1810 BasicBlock *InsertAtEnd, Context &Ctx,
1811 const Twine &Name) {
1812 auto &Builder = Ctx.getLLVMIRBuilder();
1813 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
1814 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1815 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1816 return Ctx.createExtractElementInst(NewExtract);
1817 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1818 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1819}
1820
1821#ifndef NDEBUG
1825}
1826#endif // NDEBUG
1827
1829 bool IsSigned) {
1830 auto *LLVMC = llvm::ConstantInt::get(Ty, V, IsSigned);
1831 return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
1832}
1833
1834#ifndef NDEBUG
1836 auto *F = cast<llvm::Function>(Val);
1837 OS << *F->getReturnType() << " @" << F->getName() << "(";
1838 interleave(
1839 F->args(),
1840 [this, &OS](const llvm::Argument &LLVMArg) {
1841 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
1842 if (SBArg == nullptr)
1843 OS << "NULL";
1844 else
1845 SBArg->printAsOperand(OS);
1846 },
1847 [&] { OS << ", "; });
1848 OS << ")";
1849}
1852 OS << " {\n";
1853 auto *LLVMF = cast<llvm::Function>(Val);
1854 interleave(
1855 *LLVMF,
1856 [this, &OS](const llvm::BasicBlock &LLVMBB) {
1857 auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
1858 if (BB == nullptr)
1859 OS << "NULL";
1860 else
1861 OS << *BB;
1862 },
1863 [&OS] { OS << "\n"; });
1864 OS << "}\n";
1865}
1866#endif // NDEBUG
1867
1869BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
1870 return cast_or_null<Instruction>(Ctx->getValue(&*It));
1871}
1872
1873std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
1874 std::unique_ptr<Value> Erased;
1875 auto It = LLVMValueToValueMap.find(V);
1876 if (It != LLVMValueToValueMap.end()) {
1877 auto *Val = It->second.release();
1878 Erased = std::unique_ptr<Value>(Val);
1879 LLVMValueToValueMap.erase(It);
1880 }
1881 return Erased;
1882}
1883
1884std::unique_ptr<Value> Context::detach(Value *V) {
1885 assert(V->getSubclassID() != Value::ClassID::Constant &&
1886 "Can't detach a constant!");
1887 assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
1888 return detachLLVMValue(V->Val);
1889}
1890
1891Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
1892 assert(VPtr->getSubclassID() != Value::ClassID::User &&
1893 "Can't register a user!");
1894
1895 // Track creation of instructions.
1896 // Please note that we don't allow the creation of detached instructions,
1897 // meaning that the instructions need to be inserted into a block upon
1898 // creation. This is why the tracker class combines creation and insertion.
1899 if (auto *I = dyn_cast<Instruction>(VPtr.get()))
1901
1902 Value *V = VPtr.get();
1903 [[maybe_unused]] auto Pair =
1904 LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
1905 assert(Pair.second && "Already exists!");
1906 return V;
1907}
1908
1910 auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr});
1911 auto It = Pair.first;
1912 if (!Pair.second)
1913 return It->second.get();
1914
1915 if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
1916 if (auto *CI = dyn_cast<llvm::ConstantInt>(C)) {
1917 It->second = std::unique_ptr<ConstantInt>(new ConstantInt(CI, *this));
1918 return It->second.get();
1919 }
1920 if (auto *F = dyn_cast<llvm::Function>(LLVMV))
1921 It->second = std::unique_ptr<Function>(new Function(F, *this));
1922 else
1923 It->second = std::unique_ptr<Constant>(new Constant(C, *this));
1924 auto *NewC = It->second.get();
1925 for (llvm::Value *COp : C->operands())
1927 return NewC;
1928 }
1929 if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
1930 It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
1931 return It->second.get();
1932 }
1933 if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
1934 assert(isa<BlockAddress>(U) &&
1935 "This won't create a SBBB, don't call this function directly!");
1936 if (auto *SBBB = getValue(BB))
1937 return SBBB;
1938 return nullptr;
1939 }
1940 assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
1941
1942 switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
1943 case llvm::Instruction::Select: {
1944 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
1945 It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
1946 return It->second.get();
1947 }
1948 case llvm::Instruction::ExtractElement: {
1949 auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
1950 It->second = std::unique_ptr<ExtractElementInst>(
1951 new ExtractElementInst(LLVMIns, *this));
1952 return It->second.get();
1953 }
1954 case llvm::Instruction::InsertElement: {
1955 auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
1956 It->second = std::unique_ptr<InsertElementInst>(
1957 new InsertElementInst(LLVMIns, *this));
1958 return It->second.get();
1959 }
1960 case llvm::Instruction::Br: {
1961 auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
1962 It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
1963 return It->second.get();
1964 }
1965 case llvm::Instruction::Load: {
1966 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
1967 It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
1968 return It->second.get();
1969 }
1970 case llvm::Instruction::Store: {
1971 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
1972 It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
1973 return It->second.get();
1974 }
1975 case llvm::Instruction::Ret: {
1976 auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
1977 It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
1978 return It->second.get();
1979 }
1980 case llvm::Instruction::Call: {
1981 auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
1982 It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
1983 return It->second.get();
1984 }
1985 case llvm::Instruction::Invoke: {
1986 auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
1987 It->second = std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
1988 return It->second.get();
1989 }
1990 case llvm::Instruction::CallBr: {
1991 auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
1992 It->second = std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
1993 return It->second.get();
1994 }
1995 case llvm::Instruction::GetElementPtr: {
1996 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
1997 It->second = std::unique_ptr<GetElementPtrInst>(
1998 new GetElementPtrInst(LLVMGEP, *this));
1999 return It->second.get();
2000 }
2001 case llvm::Instruction::CatchSwitch: {
2002 auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV);
2003 It->second = std::unique_ptr<CatchSwitchInst>(
2004 new CatchSwitchInst(LLVMCatchSwitchInst, *this));
2005 return It->second.get();
2006 }
2007 case llvm::Instruction::Switch: {
2008 auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
2009 It->second =
2010 std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this));
2011 return It->second.get();
2012 }
2013 case llvm::Instruction::FNeg: {
2014 auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
2015 It->second = std::unique_ptr<UnaryOperator>(
2016 new UnaryOperator(LLVMUnaryOperator, *this));
2017 return It->second.get();
2018 }
2019 case llvm::Instruction::Add:
2020 case llvm::Instruction::FAdd:
2021 case llvm::Instruction::Sub:
2022 case llvm::Instruction::FSub:
2023 case llvm::Instruction::Mul:
2024 case llvm::Instruction::FMul:
2025 case llvm::Instruction::UDiv:
2026 case llvm::Instruction::SDiv:
2027 case llvm::Instruction::FDiv:
2028 case llvm::Instruction::URem:
2029 case llvm::Instruction::SRem:
2030 case llvm::Instruction::FRem:
2031 case llvm::Instruction::Shl:
2032 case llvm::Instruction::LShr:
2033 case llvm::Instruction::AShr:
2034 case llvm::Instruction::And:
2035 case llvm::Instruction::Or:
2036 case llvm::Instruction::Xor: {
2037 auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
2038 It->second = std::unique_ptr<BinaryOperator>(
2039 new BinaryOperator(LLVMBinaryOperator, *this));
2040 return It->second.get();
2041 }
2042 case llvm::Instruction::AtomicRMW: {
2043 auto *LLVMAtomicRMW = cast<llvm::AtomicRMWInst>(LLVMV);
2044 It->second =
2045 std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(LLVMAtomicRMW, *this));
2046 return It->second.get();
2047 }
2048 case llvm::Instruction::AtomicCmpXchg: {
2049 auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
2050 It->second = std::unique_ptr<AtomicCmpXchgInst>(
2052 return It->second.get();
2053 }
2054 case llvm::Instruction::Alloca: {
2055 auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
2056 It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
2057 return It->second.get();
2058 }
2059 case llvm::Instruction::ZExt:
2060 case llvm::Instruction::SExt:
2061 case llvm::Instruction::FPToUI:
2062 case llvm::Instruction::FPToSI:
2063 case llvm::Instruction::FPExt:
2064 case llvm::Instruction::PtrToInt:
2065 case llvm::Instruction::IntToPtr:
2066 case llvm::Instruction::SIToFP:
2067 case llvm::Instruction::UIToFP:
2068 case llvm::Instruction::Trunc:
2069 case llvm::Instruction::FPTrunc:
2070 case llvm::Instruction::BitCast:
2071 case llvm::Instruction::AddrSpaceCast: {
2072 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
2073 It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
2074 return It->second.get();
2075 }
2076 case llvm::Instruction::PHI: {
2077 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
2078 It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
2079 return It->second.get();
2080 }
2081 case llvm::Instruction::Unreachable: {
2082 auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
2083 It->second = std::unique_ptr<UnreachableInst>(
2084 new UnreachableInst(LLVMUnreachable, *this));
2085 return It->second.get();
2086 }
2087 default:
2088 break;
2089 }
2090
2091 It->second = std::unique_ptr<OpaqueInst>(
2092 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
2093 return It->second.get();
2094}
2095
2097 assert(getValue(LLVMBB) == nullptr && "Already exists!");
2098 auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
2099 auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
2100 // Create SandboxIR for BB's body.
2101 BB->buildBasicBlockFromLLVMIR(LLVMBB);
2102 return BB;
2103}
2104
2106 auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
2107 return cast<SelectInst>(registerValue(std::move(NewPtr)));
2108}
2109
2112 auto NewPtr =
2113 std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
2114 return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
2115}
2116
2119 auto NewPtr =
2120 std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
2121 return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
2122}
2123
2125 auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
2126 return cast<BranchInst>(registerValue(std::move(NewPtr)));
2127}
2128
2130 auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
2131 return cast<LoadInst>(registerValue(std::move(NewPtr)));
2132}
2133
2135 auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
2136 return cast<StoreInst>(registerValue(std::move(NewPtr)));
2137}
2138
2140 auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
2141 return cast<ReturnInst>(registerValue(std::move(NewPtr)));
2142}
2143
2145 auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
2146 return cast<CallInst>(registerValue(std::move(NewPtr)));
2147}
2148
2150 auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
2151 return cast<InvokeInst>(registerValue(std::move(NewPtr)));
2152}
2153
2155 auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
2156 return cast<CallBrInst>(registerValue(std::move(NewPtr)));
2157}
2158
2160 auto NewPtr =
2161 std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
2162 return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
2163}
2164
2167 auto NewPtr =
2168 std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
2169 return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
2170}
2172 auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
2173 return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
2174}
2176 auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
2177 return cast<SwitchInst>(registerValue(std::move(NewPtr)));
2178}
2180 auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this));
2181 return cast<UnaryOperator>(registerValue(std::move(NewPtr)));
2182}
2184 auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this));
2185 return cast<BinaryOperator>(registerValue(std::move(NewPtr)));
2186}
2188 auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this));
2189 return cast<AtomicRMWInst>(registerValue(std::move(NewPtr)));
2190}
2193 auto NewPtr =
2194 std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
2195 return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
2196}
2198 auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
2199 return cast<AllocaInst>(registerValue(std::move(NewPtr)));
2200}
2202 auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
2203 return cast<CastInst>(registerValue(std::move(NewPtr)));
2204}
2206 auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
2207 return cast<PHINode>(registerValue(std::move(NewPtr)));
2208}
2209
2211 auto It = LLVMValueToValueMap.find(V);
2212 if (It != LLVMValueToValueMap.end())
2213 return It->second.get();
2214 return nullptr;
2215}
2216
2218 assert(getValue(F) == nullptr && "Already exists!");
2219 auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
2220 auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
2221 // Create arguments.
2222 for (auto &Arg : F->args())
2223 getOrCreateArgument(&Arg);
2224 // Create BBs.
2225 for (auto &BB : *F)
2226 createBasicBlock(&BB);
2227 return SBF;
2228}
2229
2231 auto *BB = cast<llvm::BasicBlock>(Val);
2232 auto *F = BB->getParent();
2233 if (F == nullptr)
2234 // Detached
2235 return nullptr;
2236 return cast_or_null<Function>(Ctx.getValue(F));
2237}
2238
2239void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
2240 for (llvm::Instruction &IRef : reverse(*LLVMBB)) {
2241 llvm::Instruction *I = &IRef;
2243 for (auto [OpIdx, Op] : enumerate(I->operands())) {
2244 // Skip instruction's label operands
2245 if (isa<llvm::BasicBlock>(Op))
2246 continue;
2247 // Skip metadata
2248 if (isa<llvm::MetadataAsValue>(Op))
2249 continue;
2250 // Skip asm
2251 if (isa<llvm::InlineAsm>(Op))
2252 continue;
2254 }
2255 }
2256#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
2257 verify();
2258#endif
2259}
2260
2262 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
2264 if (!BB->empty()) {
2265 auto *V = Ctx.getValue(&*BB->begin());
2266 assert(V != nullptr && "No SandboxIR for BB->begin()!");
2267 auto *I = cast<Instruction>(V);
2268 unsigned Num = I->getNumOfIRInstrs();
2269 assert(Num >= 1u && "Bad getNumOfIRInstrs()");
2270 It = std::next(It, Num - 1);
2271 }
2272 return iterator(BB, It, &Ctx);
2273}
2274
2276 auto *TerminatorV =
2277 Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
2278 return cast_or_null<Instruction>(TerminatorV);
2279}
2280
2282 auto *BB = cast<llvm::BasicBlock>(Val);
2283 assert(!BB->empty() && "Empty block!");
2284 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
2285 assert(SBI != nullptr && "Expected Instr!");
2286 return *SBI;
2287}
2288
2290 auto *BB = cast<llvm::BasicBlock>(Val);
2291 assert(!BB->empty() && "Empty block!");
2292 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
2293 assert(SBI != nullptr && "Expected Instr!");
2294 return *SBI;
2295}
2296
2297#ifndef NDEBUG
2299 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
2300 const auto &Name = BB->getName();
2301 OS << Name;
2302 if (!Name.empty())
2303 OS << ":\n";
2304 // If there are Instructions in the BB that are not mapped to SandboxIR, then
2305 // use a crash-proof dump.
2306 if (any_of(*BB, [this](llvm::Instruction &I) {
2307 return Ctx.getValue(&I) == nullptr;
2308 })) {
2309 OS << "<Crash-proof mode!>\n";
2311 for (llvm::Instruction &IRef : *BB) {
2312 Value *SBV = Ctx.getValue(&IRef);
2313 if (SBV == nullptr)
2314 OS << IRef << " *** No SandboxIR ***\n";
2315 else {
2316 auto *SBI = dyn_cast<Instruction>(SBV);
2317 if (SBI == nullptr) {
2318 OS << IRef << " *** Not a SBInstruction!!! ***\n";
2319 } else {
2320 if (Visited.insert(SBI).second)
2321 OS << *SBI << "\n";
2322 }
2323 }
2324 }
2325 } else {
2326 for (auto &SBI : *this) {
2327 SBI.dumpOS(OS);
2328 OS << "\n";
2329 }
2330 }
2331}
2332#endif // NDEBUG
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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:1195
static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc)
\Returns the LLVM opcode that corresponds to Opc.
Definition: SandboxIR.cpp:1230
static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc)
\Returns the LLVM opcode that corresponds to Opc.
Definition: SandboxIR.cpp:1418
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
Value * RHS
Value * LHS
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
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:495
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:696
BinOp
This enumeration lists the possible modifications atomicrmw can make.
Definition: Instructions.h:708
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 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.
Convenience struct for specifying and reasoning about fast-math flags.
Definition: FMF.h:20
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:1214
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2492
AtomicCmpXchgInst * CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, SyncScope::ID SSID=SyncScope::System)
Definition: IRBuilder.h:1858
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition: IRBuilder.h:1790
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2480
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition: IRBuilder.h:1824
UnreachableInst * CreateUnreachable()
Definition: IRBuilder.h:1280
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:1175
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:1112
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition: IRBuilder.h:1883
CatchSwitchInst * CreateCatchSwitch(Value *ParentPad, BasicBlock *UnwindBB, unsigned NumHandlers, const Twine &Name="")
Definition: IRBuilder.h:1258
Value * CreateUnOp(Instruction::UnaryOps Opc, Value *V, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1770
SwitchInst * CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases=10, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a switch instruction with the specified value, default dest, and with a hint for the number of...
Definition: IRBuilder.h:1160
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:1137
ReturnInst * CreateRetVoid()
Create a 'ret void' instruction.
Definition: IRBuilder.h:1107
AtomicRMWInst * CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val, MaybeAlign Align, AtomicOrdering Ordering, SyncScope::ID SSID=SyncScope::System)
Definition: IRBuilder.h:1871
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1683
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
Definition: IRBuilder.h:1131
Value * CreateCast(Instruction::CastOps Op, Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2181
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:1843
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2432
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2686
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:676
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
An instruction for storing to memory.
Definition: Instructions.h:290
Multiway switch.
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:2005
Value * getArraySize()
Get the number of elements allocated.
Definition: SandboxIR.cpp:1732
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: SandboxIR.h:1987
void setAlignment(Align Align)
Definition: SandboxIR.cpp:1717
void setUsedWithInAlloca(bool V)
Specify whether this alloca is used to represent the arguments to a call.
Definition: SandboxIR.cpp:1725
static AllocaInst * create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, Value *ArraySize=nullptr, const Twine &Name="")
Definition: SandboxIR.cpp:1684
void setAllocatedType(Type *Ty)
for use only in special circumstances that need to generically transform a whole instruction (eg: IR ...
Definition: SandboxIR.cpp:1710
Argument of a sandboxir::Function.
Definition: SandboxIR.h:384
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:214
void printAsOperand(raw_ostream &OS) const
Definition: SandboxIR.cpp:211
void setSyncScopeID(SyncScope::ID SSID)
Definition: SandboxIR.cpp:1586
void setVolatile(bool V)
Specify whether this is a volatile cmpxchg.
Definition: SandboxIR.cpp:1654
void setSuccessOrdering(AtomicOrdering Ordering)
Definition: SandboxIR.cpp:1668
static AtomicCmpXchgInst * create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align, AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID=SyncScope::System, const Twine &Name="")
Definition: SandboxIR.cpp:1607
AtomicOrdering getFailureOrdering() const
Definition: SandboxIR.h:1892
bool isVolatile() const
Return true if this is a cmpxchg from a volatile memory location.
Definition: SandboxIR.h:1873
AtomicOrdering getSuccessOrdering() const
Definition: SandboxIR.h:1887
void setFailureOrdering(AtomicOrdering Ordering)
Definition: SandboxIR.cpp:1676
SyncScope::ID getSyncScopeID() const
Definition: SandboxIR.h:1899
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: SandboxIR.h:1866
bool isWeak() const
Return true if this cmpxchg may spuriously fail.
Definition: SandboxIR.h:1879
static AtomicRMWInst * create(BinOp Op, Value *Ptr, Value *Val, MaybeAlign Align, AtomicOrdering Ordering, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID=SyncScope::System, const Twine &Name="")
Definition: SandboxIR.cpp:1554
SyncScope::ID getSyncScopeID() const
Definition: SandboxIR.h:1815
void setAlignment(Align Align)
Definition: SandboxIR.cpp:1518
void setSyncScopeID(SyncScope::ID SSID)
Definition: SandboxIR.cpp:1539
void setOrdering(AtomicOrdering Ordering)
Definition: SandboxIR.cpp:1532
AtomicOrdering getOrdering() const
Definition: SandboxIR.h:1811
Iterator for Instructions in a `BasicBlock.
Definition: SandboxIR.h:561
Contains a list of sandboxir::Instruction's.
Definition: SandboxIR.h:603
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:2298
void verify() const final
Should crash if there is something wrong with the instruction.
Definition: SandboxIR.h:641
Function * getParent() const
Definition: SandboxIR.cpp:2230
Instruction & front() const
Definition: SandboxIR.cpp:2281
Instruction * getTerminator() const
Definition: SandboxIR.cpp:2275
Context & getContext() const
Definition: SandboxIR.h:634
Instruction & back() const
Definition: SandboxIR.cpp:2289
iterator end() const
Definition: SandboxIR.h:624
static Value * create(Instruction::Opcode Op, Value *LHS, Value *RHS, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1460
static Value * createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, Value *RHS, Value *CopyFrom, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1489
unsigned getNumSuccessors() const
Definition: SandboxIR.h:978
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:653
bool isConditional() const
Definition: SandboxIR.h:973
void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
Definition: SandboxIR.cpp:669
BasicBlock * getSuccessor(unsigned SuccIdx) const
Definition: SandboxIR.cpp:662
static BranchInst * create(BasicBlock *IfTrue, Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:611
Value * getCondition() const
Definition: SandboxIR.cpp:657
void setCalledFunction(Function *F)
Definition: SandboxIR.cpp:851
Function * getCalledFunction() const
Definition: SandboxIR.cpp:843
void setCalledOperand(Value *V)
Definition: SandboxIR.h:1275
Value * getCalledOperand() const
Definition: SandboxIR.cpp:834
Use getCalledOperandUse() const
Definition: SandboxIR.cpp:838
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:958
BasicBlock * getIndirectDest(unsigned Idx) const
Definition: SandboxIR.cpp:1016
void setDefaultDest(BasicBlock *BB)
Definition: SandboxIR.cpp:1027
Value * getIndirectDestLabel(unsigned Idx) const
Definition: SandboxIR.cpp:1005
Value * getIndirectDestLabelUse(unsigned Idx) const
Definition: SandboxIR.cpp:1008
SmallVector< BasicBlock *, 16 > getIndirectDests() const
Definition: SandboxIR.cpp:1020
BasicBlock * getDefaultDest() const
Definition: SandboxIR.cpp:1012
BasicBlock * getSuccessor(unsigned Idx) const
Definition: SandboxIR.cpp:1041
void setIndirectDest(unsigned Idx, BasicBlock *BB)
Definition: SandboxIR.cpp:1033
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:1736
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:1767
void setParentPad(Value *ParentPad)
Definition: SandboxIR.cpp:1258
static CatchSwitchInst * create(Value *ParentPad, BasicBlock *UnwindBB, unsigned NumHandlers, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1239
void addHandler(BasicBlock *Dest)
Definition: SandboxIR.cpp:1278
void setUnwindDest(BasicBlock *UnwindDest)
Definition: SandboxIR.cpp:1270
BasicBlock * getUnwindDest() const
Definition: SandboxIR.cpp:1265
static ConstantInt * get(Type *Ty, uint64_t V, Context &Ctx, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: SandboxIR.cpp:1828
void dumpOS(raw_ostream &OS) const override
Definition: SandboxIR.cpp:1822
CallBrInst * createCallBrInst(llvm::CallBrInst *I)
Definition: SandboxIR.cpp:2154
GetElementPtrInst * createGetElementPtrInst(llvm::GetElementPtrInst *I)
Definition: SandboxIR.cpp:2166
DenseMap< llvm::Value *, std::unique_ptr< sandboxir::Value > > LLVMValueToValueMap
Maps LLVM Value to the corresponding sandboxir::Value.
Definition: SandboxIR.h:2235
Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
Definition: SandboxIR.cpp:1891
sandboxir::Value * getValue(llvm::Value *V) const
Definition: SandboxIR.cpp:2210
Argument * getOrCreateArgument(llvm::Argument *LLVMArg)
Get or create a sandboxir::Argument for an existing LLVM IR LLVMArg.
Definition: SandboxIR.h:2250
Function * createFunction(llvm::Function *F)
Create a sandboxir::Function for an existing LLVM IR F, including all blocks and instructions.
Definition: SandboxIR.cpp:2217
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:1909
std::unique_ptr< Value > detach(Value *V)
Remove SBV from all SandboxIR maps and stop owning it.
Definition: SandboxIR.cpp:1884
SwitchInst * createSwitchInst(llvm::SwitchInst *I)
Definition: SandboxIR.cpp:2175
UnreachableInst * createUnreachableInst(llvm::UnreachableInst *UI)
Definition: SandboxIR.cpp:2159
BranchInst * createBranchInst(llvm::BranchInst *I)
Definition: SandboxIR.cpp:2124
Constant * getOrCreateConstant(llvm::Constant *LLVMC)
Get or create a sandboxir::Constant from an existing LLVM IR LLVMC.
Definition: SandboxIR.h:2264
BasicBlock * createBasicBlock(llvm::BasicBlock *BB)
Create a sandboxir::BasicBlock for an existing LLVM IR BB.
Definition: SandboxIR.cpp:2096
UnaryOperator * createUnaryOperator(llvm::UnaryOperator *I)
Definition: SandboxIR.cpp:2179
ExtractElementInst * createExtractElementInst(llvm::ExtractElementInst *EEI)
Definition: SandboxIR.cpp:2111
LoadInst * createLoadInst(llvm::LoadInst *LI)
Definition: SandboxIR.cpp:2129
AllocaInst * createAllocaInst(llvm::AllocaInst *I)
Definition: SandboxIR.cpp:2197
CallInst * createCallInst(llvm::CallInst *I)
Definition: SandboxIR.cpp:2144
AtomicRMWInst * createAtomicRMWInst(llvm::AtomicRMWInst *I)
Definition: SandboxIR.cpp:2187
std::unique_ptr< Value > detachLLVMValue(llvm::Value *V)
Remove V from the maps and returns the unique_ptr.
Definition: SandboxIR.cpp:1873
StoreInst * createStoreInst(llvm::StoreInst *SI)
Definition: SandboxIR.cpp:2134
Value * getOrCreateValue(llvm::Value *LLVMV)
Get or create a sandboxir::Value for an existing LLVM IR LLVMV.
Definition: SandboxIR.h:2260
InsertElementInst * createInsertElementInst(llvm::InsertElementInst *IEI)
Definition: SandboxIR.cpp:2118
AtomicCmpXchgInst * createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I)
Definition: SandboxIR.cpp:2192
CatchSwitchInst * createCatchSwitchInst(llvm::CatchSwitchInst *I)
Definition: SandboxIR.cpp:2171
ReturnInst * createReturnInst(llvm::ReturnInst *I)
Definition: SandboxIR.cpp:2139
friend class ConstantInt
Definition: SandboxIR.h:2267
PHINode * createPHINode(llvm::PHINode *I)
Definition: SandboxIR.cpp:2205
SelectInst * createSelectInst(llvm::SelectInst *SI)
Definition: SandboxIR.cpp:2105
CastInst * createCastInst(llvm::CastInst *I)
Definition: SandboxIR.cpp:2201
BinaryOperator * createBinaryOperator(llvm::BinaryOperator *I)
Definition: SandboxIR.cpp:2183
friend class BasicBlock
Various leaf nodes.
Definition: SandboxIR.h:2272
InvokeInst * createInvokeInst(llvm::InvokeInst *I)
Definition: SandboxIR.cpp:2149
size_t getNumValues() const
\Returns the number of values registered with Context.
Definition: SandboxIR.h:2343
static Value * create(Value *Vec, Value *Idx, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1797
void dumpNameAndArgs(raw_ostream &OS) const
Definition: SandboxIR.cpp:1835
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:1850
Similar to GenericSetter but the setters/getters have an index as their first argument.
Definition: Tracker.h:240
This class can be used for tracking most instruction setters.
Definition: Tracker.h:212
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:1771
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: SandboxIR.h:650
bool hasNoUnsignedWrap() const
Determine whether the no signed wrap flag is set.
Definition: SandboxIR.h:738
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
bool hasAllowReassoc() const
Determine whether the allow-reassociation flag is set.
Definition: SandboxIR.h:758
virtual unsigned getNumOfIRInstrs() const =0
This is used by BasicBlock::iterator.
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
Definition: SandboxIR.h:783
void copyFastMathFlags(FastMathFlags FMF)
Convenience function for transferring all fast-math flag values to this instruction,...
Definition: SandboxIR.cpp:558
void setHasNoSignedZeros(bool B)
Set or clear the no-signed-zeros flag on this instruction, which must be an operator which supports t...
Definition: SandboxIR.cpp:527
static bool classof(const sandboxir::Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:464
bool hasAllowContract() const
Determine whether the allow-contract flag is set.
Definition: SandboxIR.h:799
void setHasAllowContract(bool B)
Set or clear the allow-contract flag on this instruction, which must be an operator which supports th...
Definition: SandboxIR.cpp:543
void setIsExact(bool B=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
Definition: SandboxIR.cpp:497
bool hasApproxFunc() const
Determine whether the approximate-math-functions flag is set.
Definition: SandboxIR.h:807
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
Definition: SandboxIR.h:745
void setHasNoNaNs(bool B)
Set or clear the no-nans flag on this instruction, which must be an operator which supports this flag...
Definition: SandboxIR.cpp:511
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
Definition: SandboxIR.cpp:433
void setHasApproxFunc(bool B)
Set or clear the approximate-math-functions flag on this instruction, which must be an operator which...
Definition: SandboxIR.cpp:565
void setHasAllowReassoc(bool B)
Set or clear the reassociation flag on this instruction, which must be an operator which supports thi...
Definition: SandboxIR.cpp:504
void setFastMathFlags(FastMathFlags FMF)
Convenience function for setting multiple fast-math flags on this instruction, which must be an opera...
Definition: SandboxIR.cpp:551
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 setHasNoInfs(bool B)
Set or clear the no-infs flag on this instruction, which must be an operator which supports this flag...
Definition: SandboxIR.cpp:519
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:573
Instruction * getPrevNode() const
\Returns the previous sandboxir::Instruction in the block, or nullptr if at the beginning of the bloc...
Definition: SandboxIR.cpp:351
FastMathFlags getFastMathFlags() const
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
Definition: SandboxIR.h:817
void setHasNoSignedWrap(bool B=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
Definition: SandboxIR.cpp:483
void setHasAllowReciprocal(bool B)
Set or clear the allow-reciprocal flag on this instruction, which must be an operator which supports ...
Definition: SandboxIR.cpp:535
bool hasAllowReciprocal() const
Determine whether the allow-reciprocal flag is set.
Definition: SandboxIR.h:791
void setFast(bool B)
Set or clear all fast-math-flags on this instruction, which must be an operator which supports this f...
Definition: SandboxIR.cpp:490
void setHasNoUnsignedWrap(bool B=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
Definition: SandboxIR.cpp:475
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:948
BasicBlock * getSuccessor(unsigned SuccIdx) const
Definition: SandboxIR.cpp:953
void setNormalDest(BasicBlock *BB)
Definition: SandboxIR.cpp:940
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:894
void setUnwindDest(BasicBlock *BB)
Definition: SandboxIR.cpp:944
BasicBlock * getNormalDest() const
Definition: SandboxIR.cpp:932
BasicBlock * getUnwindDest() const
Definition: SandboxIR.cpp:936
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:724
static LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:689
void setVolatile(bool V)
Specify whether this is a volatile load or not.
Definition: SandboxIR.cpp:682
Value * getPointerOperand() const
Definition: SandboxIR.cpp:728
An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to an OpaqueInstr.
Definition: SandboxIR.h:2214
Iterator for the Use edges of a User's operands.
Definition: SandboxIR.h:143
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:1100
void setIncomingBlock(unsigned Idx, BasicBlock *BB)
Definition: SandboxIR.cpp:1123
void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New)
Definition: SandboxIR.cpp:1173
void setIncomingValue(unsigned Idx, Value *V)
Definition: SandboxIR.cpp:1107
unsigned getNumIncomingValues() const
Definition: SandboxIR.h:2175
void addIncoming(Value *V, BasicBlock *BB)
Definition: SandboxIR.cpp:1134
int getBasicBlockIndex(const BasicBlock *BB) const
Definition: SandboxIR.cpp:1159
Value * removeIncomingValue(unsigned Idx)
Definition: SandboxIR.cpp:1141
void removeIncomingValueIf(function_ref< bool(unsigned)> Predicate)
Definition: SandboxIR.cpp:1180
Value * hasConstantValue() const
Definition: SandboxIR.cpp:1169
Value * getIncomingValueForBlock(const BasicBlock *BB) const
Definition: SandboxIR.cpp:1163
BasicBlock * getIncomingBlock(unsigned Idx) const
Definition: SandboxIR.cpp:1114
static PHINode * create(Type *Ty, unsigned NumReservedValues, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1092
Value * getIncomingValue(unsigned Idx) const
Definition: SandboxIR.cpp:1104
Value * getReturnValue() const
\Returns null if there is no return value.
Definition: SandboxIR.cpp:829
static ReturnInst * create(Value *RetVal, Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:814
static Value * create(Value *Cond, Value *True, Value *False, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:589
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:607
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:771
void setVolatile(bool V)
Specify whether this is a volatile store or not.
Definition: SandboxIR.cpp:732
static StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:739
Value * getPointerOperand() const
Definition: SandboxIR.cpp:779
Value * getValueOperand() const
Definition: SandboxIR.cpp:775
BasicBlock * getSuccessor(unsigned Idx) const
Definition: SandboxIR.cpp:1348
void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
Definition: SandboxIR.cpp:1353
void setDefaultDest(BasicBlock *DefaultCase)
Definition: SandboxIR.cpp:1315
CaseIt case_begin()
Returns a read/write iterator that points to the first case in the SwitchInst.
Definition: SandboxIR.h:1611
void addCase(ConstantInt *OnVal, BasicBlock *Dest)
Definition: SandboxIR.cpp:1328
llvm::SwitchInst::CaseIteratorImpl< CaseHandle > CaseIt
Definition: SandboxIR.h:1606
BasicBlock * getDefaultDest() const
Definition: SandboxIR.cpp:1310
static SwitchInst * create(Value *V, BasicBlock *Dest, unsigned NumCases, BasicBlock::iterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1284
Value * getCondition() const
Definition: SandboxIR.cpp:1298
ConstantInt * findCaseDest(BasicBlock *BB)
Definition: SandboxIR.cpp:1322
CaseIt removeCase(CaseIt It)
This method removes the specified case and its successor from the switch instruction.
Definition: SandboxIR.cpp:1335
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition: Tracker.h:360
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition: Tracker.h:410
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition: Tracker.h:386
bool emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
Definition: Tracker.h:403
static Value * create(Instruction::Opcode Op, Value *OpV, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1362
static Value * createWithCopiedFlags(Instruction::Opcode Op, Value *OpV, Value *CopyFrom, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1391
static bool classof(const Value *From)
Definition: SandboxIR.cpp:800
static UnreachableInst * create(Instruction *InsertBefore, Context &Ctx)
Definition: SandboxIR.cpp:783
Tracks the change of the source Value of a sandboxir::Use.
Definition: Tracker.h:88
Tracks swapping a Use with another Use.
Definition: Tracker.h:133
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:179
UserUseIterator & operator++()
Definition: SandboxIR.cpp:73
A sandboxir::User has operands.
Definition: SandboxIR.h:403
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:473
Use getOperandUse(unsigned OpIdx) const
\Returns the operand edge for OpIdx.
Definition: SandboxIR.h:470
void dumpCommonHeader(raw_ostream &OS) const final
Definition: SandboxIR.cpp:274
A SandboxIR Value has users. This is the base class.
Definition: SandboxIR.h:205
mapped_iterator< sandboxir::UserUseIterator, UseToUser > user_iterator
Definition: SandboxIR.h:309
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:241
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:285
Context & Ctx
All values point to the context.
Definition: SandboxIR.h:271
ClassID SubclassID
For isa/dyn_cast.
Definition: SandboxIR.h:232
void dumpCommonSuffix(raw_ostream &OS) const
Definition: SandboxIR.cpp:195
Type * getType() const
Definition: SandboxIR.h:353
friend class Use
Definition: SandboxIR.h:245
Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
Definition: SandboxIR.cpp:108
iterator_range< user_iterator > users()
Definition: SandboxIR.h:323
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:235
virtual void dumpOS(raw_ostream &OS) const =0
iterator_range< use_iterator > uses()
Definition: SandboxIR.h:297
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:215
@ LLVMCallBr
Definition: Core.h:69
@ LLVMAtomicRMW
Definition: Core.h:136
@ 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
@ LLVMAtomicCmpXchg
Definition: Core.h:135
@ LLVMSwitch
Definition: Core.h:64
#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:2431
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:2152
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:1909
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ 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:305