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
1239SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
1240 BasicBlock::iterator WhereIt,
1241 BasicBlock *WhereBB, Context &Ctx,
1242 const Twine &Name) {
1243 auto &Builder = Ctx.getLLVMIRBuilder();
1244 if (WhereIt != WhereBB->end())
1245 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1246 else
1247 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1249 Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
1251}
1252
1254 return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
1255}
1256
1258 Ctx.getTracker()
1261 this);
1262 cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
1263}
1264
1266 return cast<BasicBlock>(
1267 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
1268}
1269
1271 Ctx.getTracker()
1274 cast<llvm::SwitchInst>(Val)->setDefaultDest(
1275 cast<llvm::BasicBlock>(DefaultCase->Val));
1276}
1278 auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
1279 cast<llvm::BasicBlock>(BB->Val));
1280 return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
1281}
1282
1285 // TODO: Track this!
1286 cast<llvm::SwitchInst>(Val)->addCase(cast<llvm::ConstantInt>(OnVal->Val),
1287 cast<llvm::BasicBlock>(Dest->Val));
1288}
1289
1291 auto &Case = *It;
1293 this, Case.getCaseValue(), Case.getCaseSuccessor());
1294
1295 auto *LLVMSwitch = cast<llvm::SwitchInst>(Val);
1296 unsigned CaseNum = It - case_begin();
1297 llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
1298 auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
1299 unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
1300 return CaseIt(this, Num);
1301}
1302
1304 return cast<BasicBlock>(
1305 Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
1306}
1307
1308void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1309 Ctx.getTracker()
1312 Idx);
1313 cast<llvm::SwitchInst>(Val)->setSuccessor(
1314 Idx, cast<llvm::BasicBlock>(NewSucc->Val));
1315}
1316
1318 BBIterator WhereIt, BasicBlock *WhereBB,
1319 Context &Ctx, const Twine &Name) {
1320 auto &Builder = Ctx.getLLVMIRBuilder();
1321 if (WhereIt == WhereBB->end())
1322 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1323 else
1324 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1325 auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
1326 if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1327 return Ctx.createUnaryOperator(NewUnOpV);
1328 }
1329 assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
1330 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
1331}
1332
1334 Instruction *InsertBefore, Context &Ctx,
1335 const Twine &Name) {
1336 return create(Op, OpV, InsertBefore->getIterator(), InsertBefore->getParent(),
1337 Ctx, Name);
1338}
1339
1341 BasicBlock *InsertAfter, Context &Ctx,
1342 const Twine &Name) {
1343 return create(Op, OpV, InsertAfter->end(), InsertAfter, Ctx, Name);
1344}
1345
1347 Value *CopyFrom, BBIterator WhereIt,
1348 BasicBlock *WhereBB, Context &Ctx,
1349 const Twine &Name) {
1350 auto *NewV = create(Op, OpV, WhereIt, WhereBB, Ctx, Name);
1351 if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1352 UnI->copyIRFlags(CopyFrom->Val);
1353 return NewV;
1354}
1355
1357 Value *CopyFrom,
1358 Instruction *InsertBefore,
1359 Context &Ctx, const Twine &Name) {
1360 return createWithCopiedFlags(Op, OpV, CopyFrom, InsertBefore->getIterator(),
1361 InsertBefore->getParent(), Ctx, Name);
1362}
1363
1365 Value *CopyFrom,
1366 BasicBlock *InsertAtEnd,
1367 Context &Ctx, const Twine &Name) {
1368 return createWithCopiedFlags(Op, OpV, CopyFrom, InsertAtEnd->end(),
1369 InsertAtEnd, Ctx, Name);
1370}
1371
1372/// \Returns the LLVM opcode that corresponds to \p Opc.
1374 switch (Opc) {
1375 case Instruction::Opcode::Add:
1376 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
1377 case Instruction::Opcode::FAdd:
1378 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
1379 case Instruction::Opcode::Sub:
1380 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
1381 case Instruction::Opcode::FSub:
1382 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
1383 case Instruction::Opcode::Mul:
1384 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
1385 case Instruction::Opcode::FMul:
1386 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
1387 case Instruction::Opcode::UDiv:
1388 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
1389 case Instruction::Opcode::SDiv:
1390 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
1391 case Instruction::Opcode::FDiv:
1392 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
1393 case Instruction::Opcode::URem:
1394 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
1395 case Instruction::Opcode::SRem:
1396 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
1397 case Instruction::Opcode::FRem:
1398 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
1399 case Instruction::Opcode::Shl:
1400 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
1401 case Instruction::Opcode::LShr:
1402 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
1403 case Instruction::Opcode::AShr:
1404 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
1405 case Instruction::Opcode::And:
1406 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
1407 case Instruction::Opcode::Or:
1408 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
1409 case Instruction::Opcode::Xor:
1410 return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
1411 default:
1412 llvm_unreachable("Not a binary op!");
1413 }
1414}
1416 BBIterator WhereIt, BasicBlock *WhereBB,
1417 Context &Ctx, const Twine &Name) {
1418 auto &Builder = Ctx.getLLVMIRBuilder();
1419 if (WhereIt == WhereBB->end())
1420 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1421 else
1422 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1423 llvm::Value *NewV =
1425 if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1426 return Ctx.createBinaryOperator(NewBinOp);
1427 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1428 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1429}
1430
1432 Instruction *InsertBefore, Context &Ctx,
1433 const Twine &Name) {
1434 return create(Op, LHS, RHS, InsertBefore->getIterator(),
1435 InsertBefore->getParent(), Ctx, Name);
1436}
1437
1439 BasicBlock *InsertAtEnd, Context &Ctx,
1440 const Twine &Name) {
1441 return create(Op, LHS, RHS, InsertAtEnd->end(), InsertAtEnd, Ctx, Name);
1442}
1443
1445 Value *RHS, Value *CopyFrom,
1446 BBIterator WhereIt,
1447 BasicBlock *WhereBB, Context &Ctx,
1448 const Twine &Name) {
1449
1450 Value *NewV = create(Op, LHS, RHS, WhereIt, WhereBB, Ctx, Name);
1451 if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1452 cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
1453 return NewV;
1454}
1455
1457 Value *RHS, Value *CopyFrom,
1458 Instruction *InsertBefore,
1459 Context &Ctx, const Twine &Name) {
1460 return createWithCopiedFlags(Op, LHS, RHS, CopyFrom,
1461 InsertBefore->getIterator(),
1462 InsertBefore->getParent(), Ctx, Name);
1463}
1464
1466 Value *RHS, Value *CopyFrom,
1467 BasicBlock *InsertAtEnd,
1468 Context &Ctx, const Twine &Name) {
1469 return createWithCopiedFlags(Op, LHS, RHS, CopyFrom, InsertAtEnd->end(),
1470 InsertAtEnd, Ctx, Name);
1471}
1472
1474 Ctx.getTracker()
1477 cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
1478}
1479
1481 Ctx.getTracker()
1484 cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
1485}
1486
1488 Ctx.getTracker()
1491 cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
1492}
1493
1495 Ctx.getTracker()
1498 cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);
1499}
1500
1502 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getPointerOperand());
1503}
1504
1506 return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getValOperand());
1507}
1508
1511 BBIterator WhereIt, BasicBlock *WhereBB,
1512 Context &Ctx, SyncScope::ID SSID,
1513 const Twine &Name) {
1514 auto &Builder = Ctx.getLLVMIRBuilder();
1515 if (WhereIt == WhereBB->end())
1516 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1517 else
1518 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1519 auto *LLVMAtomicRMW =
1520 Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
1521 LLVMAtomicRMW->setName(Name);
1523}
1524
1527 Instruction *InsertBefore, Context &Ctx,
1528 SyncScope::ID SSID, const Twine &Name) {
1529 return create(Op, Ptr, Val, Align, Ordering, InsertBefore->getIterator(),
1530 InsertBefore->getParent(), Ctx, SSID, Name);
1531}
1532
1535 BasicBlock *InsertAtEnd, Context &Ctx,
1536 SyncScope::ID SSID, const Twine &Name) {
1537 return create(Op, Ptr, Val, Align, Ordering, InsertAtEnd->end(), InsertAtEnd,
1538 Ctx, SSID, Name);
1539}
1540
1542 Ctx.getTracker()
1545 this);
1546 cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
1547}
1548
1550 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());
1551}
1552
1554 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());
1555}
1556
1558 return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
1559}
1560
1563 AtomicOrdering SuccessOrdering,
1564 AtomicOrdering FailureOrdering, BBIterator WhereIt,
1565 BasicBlock *WhereBB, Context &Ctx, SyncScope::ID SSID,
1566 const Twine &Name) {
1567 auto &Builder = Ctx.getLLVMIRBuilder();
1568 if (WhereIt == WhereBB->end())
1569 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1570 else
1571 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1572 auto *LLVMAtomicCmpXchg =
1573 Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1574 SuccessOrdering, FailureOrdering, SSID);
1575 LLVMAtomicCmpXchg->setName(Name);
1577}
1578
1581 AtomicOrdering SuccessOrdering,
1582 AtomicOrdering FailureOrdering,
1583 Instruction *InsertBefore,
1584 Context &Ctx, SyncScope::ID SSID,
1585 const Twine &Name) {
1586 return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
1587 InsertBefore->getIterator(), InsertBefore->getParent(), Ctx,
1588 SSID, Name);
1589}
1590
1593 AtomicOrdering SuccessOrdering,
1594 AtomicOrdering FailureOrdering,
1595 BasicBlock *InsertAtEnd,
1596 Context &Ctx, SyncScope::ID SSID,
1597 const Twine &Name) {
1598 return create(Ptr, Cmp, New, Align, SuccessOrdering, FailureOrdering,
1599 InsertAtEnd->end(), InsertAtEnd, Ctx, SSID, Name);
1600}
1601
1603 Ctx.getTracker()
1606 cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1607}
1608
1610 Ctx.getTracker()
1613 cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1614}
1615
1617 Ctx.getTracker()
1620 cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1621}
1622
1624 Ctx.getTracker()
1627 this);
1628 cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1629}
1630
1632 Ctx.getTracker()
1635 this);
1636 cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1637}
1638
1639AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt,
1640 BasicBlock *WhereBB, Context &Ctx,
1641 Value *ArraySize, const Twine &Name) {
1642 auto &Builder = Ctx.getLLVMIRBuilder();
1643 if (WhereIt == WhereBB->end())
1644 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1645 else
1646 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1647 auto *NewAlloca = Builder.CreateAlloca(Ty, AddrSpace, ArraySize->Val, Name);
1648 return Ctx.createAllocaInst(NewAlloca);
1649}
1650
1651AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
1652 Instruction *InsertBefore, Context &Ctx,
1653 Value *ArraySize, const Twine &Name) {
1654 return create(Ty, AddrSpace, InsertBefore->getIterator(),
1655 InsertBefore->getParent(), Ctx, ArraySize, Name);
1656}
1657
1658AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace,
1659 BasicBlock *InsertAtEnd, Context &Ctx,
1660 Value *ArraySize, const Twine &Name) {
1661 return create(Ty, AddrSpace, InsertAtEnd->end(), InsertAtEnd, Ctx, ArraySize,
1662 Name);
1663}
1664
1666 Ctx.getTracker()
1669 cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty);
1670}
1671
1673 Ctx.getTracker()
1676 this);
1677 cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1678}
1679
1681 Ctx.getTracker()
1684 cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1685}
1686
1688 return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
1689}
1690
1692 BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx,
1693 const Twine &Name) {
1694 assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1695 auto &Builder = Ctx.getLLVMIRBuilder();
1696 if (WhereIt == WhereBB->end())
1697 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
1698 else
1699 Builder.SetInsertPoint((*WhereIt).getTopmostLLVMInstruction());
1700 auto *NewV =
1701 Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy, Name);
1702 if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1703 return Ctx.createCastInst(NewCI);
1704 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1705 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1706}
1707
1709 Instruction *InsertBefore, Context &Ctx,
1710 const Twine &Name) {
1711 return create(DestTy, Op, Operand, InsertBefore->getIterator(),
1712 InsertBefore->getParent(), Ctx, Name);
1713}
1714
1716 BasicBlock *InsertAtEnd, Context &Ctx,
1717 const Twine &Name) {
1718 return create(DestTy, Op, Operand, InsertAtEnd->end(), InsertAtEnd, Ctx,
1719 Name);
1720}
1721
1723 return From->getSubclassID() == ClassID::Cast;
1724}
1725
1727 Instruction *InsertBefore, Context &Ctx,
1728 const Twine &Name) {
1729 auto &Builder = Ctx.getLLVMIRBuilder();
1730 Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
1731 llvm::Value *NewV =
1732 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1733 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1734 return Ctx.createInsertElementInst(NewInsert);
1735 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1736 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1737}
1738
1740 BasicBlock *InsertAtEnd, Context &Ctx,
1741 const Twine &Name) {
1742 auto &Builder = Ctx.getLLVMIRBuilder();
1743 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
1744 llvm::Value *NewV =
1745 Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1746 if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1747 return Ctx.createInsertElementInst(NewInsert);
1748 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1749 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1750}
1751
1753 Instruction *InsertBefore, Context &Ctx,
1754 const Twine &Name) {
1755 auto &Builder = Ctx.getLLVMIRBuilder();
1756 Builder.SetInsertPoint(InsertBefore->getTopmostLLVMInstruction());
1757 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1758 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1759 return Ctx.createExtractElementInst(NewExtract);
1760 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1761 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1762}
1763
1765 BasicBlock *InsertAtEnd, Context &Ctx,
1766 const Twine &Name) {
1767 auto &Builder = Ctx.getLLVMIRBuilder();
1768 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
1769 llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1770 if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1771 return Ctx.createExtractElementInst(NewExtract);
1772 assert(isa<llvm::Constant>(NewV) && "Expected constant");
1773 return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1774}
1775
1776#ifndef NDEBUG
1780}
1781#endif // NDEBUG
1782
1784 bool IsSigned) {
1785 auto *LLVMC = llvm::ConstantInt::get(Ty, V, IsSigned);
1786 return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
1787}
1788
1789#ifndef NDEBUG
1791 auto *F = cast<llvm::Function>(Val);
1792 OS << *F->getReturnType() << " @" << F->getName() << "(";
1793 interleave(
1794 F->args(),
1795 [this, &OS](const llvm::Argument &LLVMArg) {
1796 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
1797 if (SBArg == nullptr)
1798 OS << "NULL";
1799 else
1800 SBArg->printAsOperand(OS);
1801 },
1802 [&] { OS << ", "; });
1803 OS << ")";
1804}
1807 OS << " {\n";
1808 auto *LLVMF = cast<llvm::Function>(Val);
1809 interleave(
1810 *LLVMF,
1811 [this, &OS](const llvm::BasicBlock &LLVMBB) {
1812 auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
1813 if (BB == nullptr)
1814 OS << "NULL";
1815 else
1816 OS << *BB;
1817 },
1818 [&OS] { OS << "\n"; });
1819 OS << "}\n";
1820}
1821#endif // NDEBUG
1822
1824BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
1825 return cast_or_null<Instruction>(Ctx->getValue(&*It));
1826}
1827
1828std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
1829 std::unique_ptr<Value> Erased;
1830 auto It = LLVMValueToValueMap.find(V);
1831 if (It != LLVMValueToValueMap.end()) {
1832 auto *Val = It->second.release();
1833 Erased = std::unique_ptr<Value>(Val);
1834 LLVMValueToValueMap.erase(It);
1835 }
1836 return Erased;
1837}
1838
1839std::unique_ptr<Value> Context::detach(Value *V) {
1840 assert(V->getSubclassID() != Value::ClassID::Constant &&
1841 "Can't detach a constant!");
1842 assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
1843 return detachLLVMValue(V->Val);
1844}
1845
1846Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
1847 assert(VPtr->getSubclassID() != Value::ClassID::User &&
1848 "Can't register a user!");
1849
1850 // Track creation of instructions.
1851 // Please note that we don't allow the creation of detached instructions,
1852 // meaning that the instructions need to be inserted into a block upon
1853 // creation. This is why the tracker class combines creation and insertion.
1854 if (auto *I = dyn_cast<Instruction>(VPtr.get()))
1856
1857 Value *V = VPtr.get();
1858 [[maybe_unused]] auto Pair =
1859 LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
1860 assert(Pair.second && "Already exists!");
1861 return V;
1862}
1863
1865 auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr});
1866 auto It = Pair.first;
1867 if (!Pair.second)
1868 return It->second.get();
1869
1870 if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
1871 if (auto *CI = dyn_cast<llvm::ConstantInt>(C)) {
1872 It->second = std::unique_ptr<ConstantInt>(new ConstantInt(CI, *this));
1873 return It->second.get();
1874 }
1875 if (auto *F = dyn_cast<llvm::Function>(LLVMV))
1876 It->second = std::unique_ptr<Function>(new Function(F, *this));
1877 else
1878 It->second = std::unique_ptr<Constant>(new Constant(C, *this));
1879 auto *NewC = It->second.get();
1880 for (llvm::Value *COp : C->operands())
1882 return NewC;
1883 }
1884 if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
1885 It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
1886 return It->second.get();
1887 }
1888 if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
1889 assert(isa<BlockAddress>(U) &&
1890 "This won't create a SBBB, don't call this function directly!");
1891 if (auto *SBBB = getValue(BB))
1892 return SBBB;
1893 return nullptr;
1894 }
1895 assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
1896
1897 switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
1898 case llvm::Instruction::Select: {
1899 auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
1900 It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
1901 return It->second.get();
1902 }
1903 case llvm::Instruction::ExtractElement: {
1904 auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
1905 It->second = std::unique_ptr<ExtractElementInst>(
1906 new ExtractElementInst(LLVMIns, *this));
1907 return It->second.get();
1908 }
1909 case llvm::Instruction::InsertElement: {
1910 auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
1911 It->second = std::unique_ptr<InsertElementInst>(
1912 new InsertElementInst(LLVMIns, *this));
1913 return It->second.get();
1914 }
1915 case llvm::Instruction::Br: {
1916 auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
1917 It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
1918 return It->second.get();
1919 }
1920 case llvm::Instruction::Load: {
1921 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
1922 It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
1923 return It->second.get();
1924 }
1925 case llvm::Instruction::Store: {
1926 auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
1927 It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
1928 return It->second.get();
1929 }
1930 case llvm::Instruction::Ret: {
1931 auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
1932 It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
1933 return It->second.get();
1934 }
1935 case llvm::Instruction::Call: {
1936 auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
1937 It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
1938 return It->second.get();
1939 }
1940 case llvm::Instruction::Invoke: {
1941 auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
1942 It->second = std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
1943 return It->second.get();
1944 }
1945 case llvm::Instruction::CallBr: {
1946 auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
1947 It->second = std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
1948 return It->second.get();
1949 }
1950 case llvm::Instruction::GetElementPtr: {
1951 auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
1952 It->second = std::unique_ptr<GetElementPtrInst>(
1953 new GetElementPtrInst(LLVMGEP, *this));
1954 return It->second.get();
1955 }
1956 case llvm::Instruction::Switch: {
1957 auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
1958 It->second =
1959 std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this));
1960 return It->second.get();
1961 }
1962 case llvm::Instruction::FNeg: {
1963 auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
1964 It->second = std::unique_ptr<UnaryOperator>(
1965 new UnaryOperator(LLVMUnaryOperator, *this));
1966 return It->second.get();
1967 }
1968 case llvm::Instruction::Add:
1969 case llvm::Instruction::FAdd:
1970 case llvm::Instruction::Sub:
1971 case llvm::Instruction::FSub:
1972 case llvm::Instruction::Mul:
1973 case llvm::Instruction::FMul:
1974 case llvm::Instruction::UDiv:
1975 case llvm::Instruction::SDiv:
1976 case llvm::Instruction::FDiv:
1977 case llvm::Instruction::URem:
1978 case llvm::Instruction::SRem:
1979 case llvm::Instruction::FRem:
1980 case llvm::Instruction::Shl:
1981 case llvm::Instruction::LShr:
1982 case llvm::Instruction::AShr:
1983 case llvm::Instruction::And:
1984 case llvm::Instruction::Or:
1985 case llvm::Instruction::Xor: {
1986 auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
1987 It->second = std::unique_ptr<BinaryOperator>(
1988 new BinaryOperator(LLVMBinaryOperator, *this));
1989 return It->second.get();
1990 }
1991 case llvm::Instruction::AtomicRMW: {
1992 auto *LLVMAtomicRMW = cast<llvm::AtomicRMWInst>(LLVMV);
1993 It->second =
1994 std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(LLVMAtomicRMW, *this));
1995 return It->second.get();
1996 }
1997 case llvm::Instruction::AtomicCmpXchg: {
1998 auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
1999 It->second = std::unique_ptr<AtomicCmpXchgInst>(
2001 return It->second.get();
2002 }
2003 case llvm::Instruction::Alloca: {
2004 auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
2005 It->second = std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
2006 return It->second.get();
2007 }
2008 case llvm::Instruction::ZExt:
2009 case llvm::Instruction::SExt:
2010 case llvm::Instruction::FPToUI:
2011 case llvm::Instruction::FPToSI:
2012 case llvm::Instruction::FPExt:
2013 case llvm::Instruction::PtrToInt:
2014 case llvm::Instruction::IntToPtr:
2015 case llvm::Instruction::SIToFP:
2016 case llvm::Instruction::UIToFP:
2017 case llvm::Instruction::Trunc:
2018 case llvm::Instruction::FPTrunc:
2019 case llvm::Instruction::BitCast:
2020 case llvm::Instruction::AddrSpaceCast: {
2021 auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
2022 It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
2023 return It->second.get();
2024 }
2025 case llvm::Instruction::PHI: {
2026 auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
2027 It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
2028 return It->second.get();
2029 }
2030 case llvm::Instruction::Unreachable: {
2031 auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
2032 It->second = std::unique_ptr<UnreachableInst>(
2033 new UnreachableInst(LLVMUnreachable, *this));
2034 return It->second.get();
2035 }
2036 default:
2037 break;
2038 }
2039
2040 It->second = std::unique_ptr<OpaqueInst>(
2041 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
2042 return It->second.get();
2043}
2044
2046 assert(getValue(LLVMBB) == nullptr && "Already exists!");
2047 auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
2048 auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
2049 // Create SandboxIR for BB's body.
2050 BB->buildBasicBlockFromLLVMIR(LLVMBB);
2051 return BB;
2052}
2053
2055 auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
2056 return cast<SelectInst>(registerValue(std::move(NewPtr)));
2057}
2058
2061 auto NewPtr =
2062 std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
2063 return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
2064}
2065
2068 auto NewPtr =
2069 std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
2070 return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
2071}
2072
2074 auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
2075 return cast<BranchInst>(registerValue(std::move(NewPtr)));
2076}
2077
2079 auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
2080 return cast<LoadInst>(registerValue(std::move(NewPtr)));
2081}
2082
2084 auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
2085 return cast<StoreInst>(registerValue(std::move(NewPtr)));
2086}
2087
2089 auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
2090 return cast<ReturnInst>(registerValue(std::move(NewPtr)));
2091}
2092
2094 auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
2095 return cast<CallInst>(registerValue(std::move(NewPtr)));
2096}
2097
2099 auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
2100 return cast<InvokeInst>(registerValue(std::move(NewPtr)));
2101}
2102
2104 auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
2105 return cast<CallBrInst>(registerValue(std::move(NewPtr)));
2106}
2107
2109 auto NewPtr =
2110 std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
2111 return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
2112}
2113
2116 auto NewPtr =
2117 std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
2118 return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
2119}
2121 auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
2122 return cast<SwitchInst>(registerValue(std::move(NewPtr)));
2123}
2125 auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this));
2126 return cast<UnaryOperator>(registerValue(std::move(NewPtr)));
2127}
2129 auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this));
2130 return cast<BinaryOperator>(registerValue(std::move(NewPtr)));
2131}
2133 auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this));
2134 return cast<AtomicRMWInst>(registerValue(std::move(NewPtr)));
2135}
2138 auto NewPtr =
2139 std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
2140 return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
2141}
2143 auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
2144 return cast<AllocaInst>(registerValue(std::move(NewPtr)));
2145}
2147 auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
2148 return cast<CastInst>(registerValue(std::move(NewPtr)));
2149}
2151 auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
2152 return cast<PHINode>(registerValue(std::move(NewPtr)));
2153}
2154
2156 auto It = LLVMValueToValueMap.find(V);
2157 if (It != LLVMValueToValueMap.end())
2158 return It->second.get();
2159 return nullptr;
2160}
2161
2163 assert(getValue(F) == nullptr && "Already exists!");
2164 auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
2165 auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
2166 // Create arguments.
2167 for (auto &Arg : F->args())
2168 getOrCreateArgument(&Arg);
2169 // Create BBs.
2170 for (auto &BB : *F)
2171 createBasicBlock(&BB);
2172 return SBF;
2173}
2174
2176 auto *BB = cast<llvm::BasicBlock>(Val);
2177 auto *F = BB->getParent();
2178 if (F == nullptr)
2179 // Detached
2180 return nullptr;
2181 return cast_or_null<Function>(Ctx.getValue(F));
2182}
2183
2184void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
2185 for (llvm::Instruction &IRef : reverse(*LLVMBB)) {
2186 llvm::Instruction *I = &IRef;
2188 for (auto [OpIdx, Op] : enumerate(I->operands())) {
2189 // Skip instruction's label operands
2190 if (isa<llvm::BasicBlock>(Op))
2191 continue;
2192 // Skip metadata
2193 if (isa<llvm::MetadataAsValue>(Op))
2194 continue;
2195 // Skip asm
2196 if (isa<llvm::InlineAsm>(Op))
2197 continue;
2199 }
2200 }
2201#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
2202 verify();
2203#endif
2204}
2205
2207 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
2209 if (!BB->empty()) {
2210 auto *V = Ctx.getValue(&*BB->begin());
2211 assert(V != nullptr && "No SandboxIR for BB->begin()!");
2212 auto *I = cast<Instruction>(V);
2213 unsigned Num = I->getNumOfIRInstrs();
2214 assert(Num >= 1u && "Bad getNumOfIRInstrs()");
2215 It = std::next(It, Num - 1);
2216 }
2217 return iterator(BB, It, &Ctx);
2218}
2219
2221 auto *TerminatorV =
2222 Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
2223 return cast_or_null<Instruction>(TerminatorV);
2224}
2225
2227 auto *BB = cast<llvm::BasicBlock>(Val);
2228 assert(!BB->empty() && "Empty block!");
2229 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
2230 assert(SBI != nullptr && "Expected Instr!");
2231 return *SBI;
2232}
2233
2235 auto *BB = cast<llvm::BasicBlock>(Val);
2236 assert(!BB->empty() && "Empty block!");
2237 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
2238 assert(SBI != nullptr && "Expected Instr!");
2239 return *SBI;
2240}
2241
2242#ifndef NDEBUG
2244 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
2245 const auto &Name = BB->getName();
2246 OS << Name;
2247 if (!Name.empty())
2248 OS << ":\n";
2249 // If there are Instructions in the BB that are not mapped to SandboxIR, then
2250 // use a crash-proof dump.
2251 if (any_of(*BB, [this](llvm::Instruction &I) {
2252 return Ctx.getValue(&I) == nullptr;
2253 })) {
2254 OS << "<Crash-proof mode!>\n";
2256 for (llvm::Instruction &IRef : *BB) {
2257 Value *SBV = Ctx.getValue(&IRef);
2258 if (SBV == nullptr)
2259 OS << IRef << " *** No SandboxIR ***\n";
2260 else {
2261 auto *SBI = dyn_cast<Instruction>(SBV);
2262 if (SBI == nullptr) {
2263 OS << IRef << " *** Not a SBInstruction!!! ***\n";
2264 } else {
2265 if (Visited.insert(SBI).second)
2266 OS << *SBI << "\n";
2267 }
2268 }
2269 }
2270 } else {
2271 for (auto &SBI : *this) {
2272 SBI.dumpOS(OS);
2273 OS << "\n";
2274 }
2275 }
2276}
2277#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:1373
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
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:1910
Value * getArraySize()
Get the number of elements allocated.
Definition: SandboxIR.cpp:1687
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: SandboxIR.h:1892
void setAlignment(Align Align)
Definition: SandboxIR.cpp:1672
void setUsedWithInAlloca(bool V)
Specify whether this alloca is used to represent the arguments to a call.
Definition: SandboxIR.cpp:1680
static AllocaInst * create(Type *Ty, unsigned AddrSpace, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, Value *ArraySize=nullptr, const Twine &Name="")
Definition: SandboxIR.cpp:1639
void setAllocatedType(Type *Ty)
for use only in special circumstances that need to generically transform a whole instruction (eg: IR ...
Definition: SandboxIR.cpp:1665
Argument of a sandboxir::Function.
Definition: SandboxIR.h:381
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:1541
void setVolatile(bool V)
Specify whether this is a volatile cmpxchg.
Definition: SandboxIR.cpp:1609
void setSuccessOrdering(AtomicOrdering Ordering)
Definition: SandboxIR.cpp:1623
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:1562
AtomicOrdering getFailureOrdering() const
Definition: SandboxIR.h:1797
bool isVolatile() const
Return true if this is a cmpxchg from a volatile memory location.
Definition: SandboxIR.h:1778
AtomicOrdering getSuccessOrdering() const
Definition: SandboxIR.h:1792
void setFailureOrdering(AtomicOrdering Ordering)
Definition: SandboxIR.cpp:1631
SyncScope::ID getSyncScopeID() const
Definition: SandboxIR.h:1804
Align getAlign() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: SandboxIR.h:1771
bool isWeak() const
Return true if this cmpxchg may spuriously fail.
Definition: SandboxIR.h:1784
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:1509
SyncScope::ID getSyncScopeID() const
Definition: SandboxIR.h:1720
void setAlignment(Align Align)
Definition: SandboxIR.cpp:1473
void setSyncScopeID(SyncScope::ID SSID)
Definition: SandboxIR.cpp:1494
void setOrdering(AtomicOrdering Ordering)
Definition: SandboxIR.cpp:1487
AtomicOrdering getOrdering() const
Definition: SandboxIR.h:1716
Iterator for Instructions in a `BasicBlock.
Definition: SandboxIR.h:558
Contains a list of sandboxir::Instruction's.
Definition: SandboxIR.h:600
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:2243
void verify() const final
Should crash if there is something wrong with the instruction.
Definition: SandboxIR.h:638
Function * getParent() const
Definition: SandboxIR.cpp:2175
Instruction & front() const
Definition: SandboxIR.cpp:2226
Instruction * getTerminator() const
Definition: SandboxIR.cpp:2220
Context & getContext() const
Definition: SandboxIR.h:631
Instruction & back() const
Definition: SandboxIR.cpp:2234
iterator end() const
Definition: SandboxIR.h:621
static Value * create(Instruction::Opcode Op, Value *LHS, Value *RHS, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1415
static Value * createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, Value *RHS, Value *CopyFrom, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1444
unsigned getNumSuccessors() const
Definition: SandboxIR.h:974
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:653
bool isConditional() const
Definition: SandboxIR.h:969
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:1271
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:1691
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:1722
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:1783
void dumpOS(raw_ostream &OS) const override
Definition: SandboxIR.cpp:1777
CallBrInst * createCallBrInst(llvm::CallBrInst *I)
Definition: SandboxIR.cpp:2103
GetElementPtrInst * createGetElementPtrInst(llvm::GetElementPtrInst *I)
Definition: SandboxIR.cpp:2115
DenseMap< llvm::Value *, std::unique_ptr< sandboxir::Value > > LLVMValueToValueMap
Maps LLVM Value to the corresponding sandboxir::Value.
Definition: SandboxIR.h:2140
Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
Definition: SandboxIR.cpp:1846
sandboxir::Value * getValue(llvm::Value *V) const
Definition: SandboxIR.cpp:2155
Argument * getOrCreateArgument(llvm::Argument *LLVMArg)
Get or create a sandboxir::Argument for an existing LLVM IR LLVMArg.
Definition: SandboxIR.h:2155
Function * createFunction(llvm::Function *F)
Create a sandboxir::Function for an existing LLVM IR F, including all blocks and instructions.
Definition: SandboxIR.cpp:2162
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:1864
std::unique_ptr< Value > detach(Value *V)
Remove SBV from all SandboxIR maps and stop owning it.
Definition: SandboxIR.cpp:1839
SwitchInst * createSwitchInst(llvm::SwitchInst *I)
Definition: SandboxIR.cpp:2120
UnreachableInst * createUnreachableInst(llvm::UnreachableInst *UI)
Definition: SandboxIR.cpp:2108
BranchInst * createBranchInst(llvm::BranchInst *I)
Definition: SandboxIR.cpp:2073
Constant * getOrCreateConstant(llvm::Constant *LLVMC)
Get or create a sandboxir::Constant from an existing LLVM IR LLVMC.
Definition: SandboxIR.h:2169
BasicBlock * createBasicBlock(llvm::BasicBlock *BB)
Create a sandboxir::BasicBlock for an existing LLVM IR BB.
Definition: SandboxIR.cpp:2045
UnaryOperator * createUnaryOperator(llvm::UnaryOperator *I)
Definition: SandboxIR.cpp:2124
ExtractElementInst * createExtractElementInst(llvm::ExtractElementInst *EEI)
Definition: SandboxIR.cpp:2060
LoadInst * createLoadInst(llvm::LoadInst *LI)
Definition: SandboxIR.cpp:2078
AllocaInst * createAllocaInst(llvm::AllocaInst *I)
Definition: SandboxIR.cpp:2142
CallInst * createCallInst(llvm::CallInst *I)
Definition: SandboxIR.cpp:2093
AtomicRMWInst * createAtomicRMWInst(llvm::AtomicRMWInst *I)
Definition: SandboxIR.cpp:2132
std::unique_ptr< Value > detachLLVMValue(llvm::Value *V)
Remove V from the maps and returns the unique_ptr.
Definition: SandboxIR.cpp:1828
StoreInst * createStoreInst(llvm::StoreInst *SI)
Definition: SandboxIR.cpp:2083
Value * getOrCreateValue(llvm::Value *LLVMV)
Get or create a sandboxir::Value for an existing LLVM IR LLVMV.
Definition: SandboxIR.h:2165
InsertElementInst * createInsertElementInst(llvm::InsertElementInst *IEI)
Definition: SandboxIR.cpp:2067
AtomicCmpXchgInst * createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I)
Definition: SandboxIR.cpp:2137
ReturnInst * createReturnInst(llvm::ReturnInst *I)
Definition: SandboxIR.cpp:2088
friend class ConstantInt
Definition: SandboxIR.h:2172
PHINode * createPHINode(llvm::PHINode *I)
Definition: SandboxIR.cpp:2150
SelectInst * createSelectInst(llvm::SelectInst *SI)
Definition: SandboxIR.cpp:2054
CastInst * createCastInst(llvm::CastInst *I)
Definition: SandboxIR.cpp:2146
BinaryOperator * createBinaryOperator(llvm::BinaryOperator *I)
Definition: SandboxIR.cpp:2128
friend class BasicBlock
Various leaf nodes.
Definition: SandboxIR.h:2177
InvokeInst * createInvokeInst(llvm::InvokeInst *I)
Definition: SandboxIR.cpp:2098
size_t getNumValues() const
\Returns the number of values registered with Context.
Definition: SandboxIR.h:2246
static Value * create(Value *Vec, Value *Idx, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1752
void dumpNameAndArgs(raw_ostream &OS) const
Definition: SandboxIR.cpp:1790
void dumpOS(raw_ostream &OS) const final
Definition: SandboxIR.cpp:1805
Similar to GenericSetter but the setters/getters have an index as their first argument.
Definition: Tracker.h:239
This class can be used for tracking most instruction setters.
Definition: Tracker.h:211
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:1726
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: SandboxIR.h:647
bool hasNoUnsignedWrap() const
Determine whether the no signed wrap flag is set.
Definition: SandboxIR.h:734
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:754
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:779
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:795
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:803
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
Definition: SandboxIR.h:741
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:813
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:787
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:2119
Iterator for the Use edges of a User's operands.
Definition: SandboxIR.h:142
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:2080
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:1303
void setSuccessor(unsigned Idx, BasicBlock *NewSucc)
Definition: SandboxIR.cpp:1308
void setDefaultDest(BasicBlock *DefaultCase)
Definition: SandboxIR.cpp:1270
CaseIt case_begin()
Returns a read/write iterator that points to the first case in the SwitchInst.
Definition: SandboxIR.h:1516
void addCase(ConstantInt *OnVal, BasicBlock *Dest)
Definition: SandboxIR.cpp:1283
llvm::SwitchInst::CaseIteratorImpl< CaseHandle > CaseIt
Definition: SandboxIR.h:1511
BasicBlock * getDefaultDest() const
Definition: SandboxIR.cpp:1265
static SwitchInst * create(Value *V, BasicBlock *Dest, unsigned NumCases, BasicBlock::iterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1239
Value * getCondition() const
Definition: SandboxIR.cpp:1253
ConstantInt * findCaseDest(BasicBlock *BB)
Definition: SandboxIR.cpp:1277
CaseIt removeCase(CaseIt It)
This method removes the specified case and its successor from the switch instruction.
Definition: SandboxIR.cpp:1290
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition: Tracker.h:342
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition: Tracker.h:392
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition: Tracker.h:368
bool emplaceIfTracking(ArgsT... Args)
A convenience wrapper for track() that constructs and tracks the Change object if tracking is enabled...
Definition: Tracker.h:385
static Value * create(Instruction::Opcode Op, Value *OpV, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1317
static Value * createWithCopiedFlags(Instruction::Opcode Op, Value *OpV, Value *CopyFrom, BBIterator WhereIt, BasicBlock *WhereBB, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:1346
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:87
Tracks swapping a Use with another Use.
Definition: Tracker.h:132
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:178
UserUseIterator & operator++()
Definition: SandboxIR.cpp:73
A sandboxir::User has operands.
Definition: SandboxIR.h:400
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:470
Use getOperandUse(unsigned OpIdx) const
\Returns the operand edge for OpIdx.
Definition: SandboxIR.h:467
void dumpCommonHeader(raw_ostream &OS) const final
Definition: SandboxIR.cpp:274
A SandboxIR Value has users. This is the base class.
Definition: SandboxIR.h:204
mapped_iterator< sandboxir::UserUseIterator, UseToUser > user_iterator
Definition: SandboxIR.h:306
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:240
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:282
Context & Ctx
All values point to the context.
Definition: SandboxIR.h:268
ClassID SubclassID
For isa/dyn_cast.
Definition: SandboxIR.h:231
void dumpCommonSuffix(raw_ostream &OS) const
Definition: SandboxIR.cpp:195
Type * getType() const
Definition: SandboxIR.h:350
friend class Use
Definition: SandboxIR.h:244
Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
Definition: SandboxIR.cpp:108
iterator_range< user_iterator > users()
Definition: SandboxIR.h:320
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:234
virtual void dumpOS(raw_ostream &OS) const =0
iterator_range< use_iterator > uses()
Definition: SandboxIR.h:294
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:214
@ 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:302