LLVM 19.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
11#include "llvm/IR/Constants.h"
12#include "llvm/Support/Debug.h"
13#include <sstream>
14
15using namespace llvm::sandboxir;
16
17Value *Use::get() const { return Ctx->getValue(LLVMUse->get()); }
18
19void Use::set(Value *V) { LLVMUse->set(V->Val); }
20
21unsigned Use::getOperandNo() const { return Usr->getUseOperandNo(*this); }
22
23#ifndef NDEBUG
24void Use::dump(raw_ostream &OS) const {
25 Value *Def = nullptr;
26 if (LLVMUse == nullptr)
27 OS << "<null> LLVM Use! ";
28 else
29 Def = Ctx->getValue(LLVMUse->get());
30 OS << "Def: ";
31 if (Def == nullptr)
32 OS << "NULL";
33 else
34 OS << *Def;
35 OS << "\n";
36
37 OS << "User: ";
38 if (Usr == nullptr)
39 OS << "NULL";
40 else
41 OS << *Usr;
42 OS << "\n";
43
44 OS << "OperandNo: ";
45 if (Usr == nullptr)
46 OS << "N/A";
47 else
48 OS << getOperandNo();
49 OS << "\n";
50}
51
52void Use::dump() const { dump(dbgs()); }
53#endif // NDEBUG
54
56
58 assert(Use.LLVMUse != nullptr && "Already at end!");
59 User *User = Use.getUser();
60 Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false);
61 return *this;
62}
63
65 // Get the corresponding llvm::Use, get the next in the list, and update the
66 // sandboxir::Use.
67 llvm::Use *&LLVMUse = Use.LLVMUse;
68 assert(LLVMUse != nullptr && "Already at end!");
69 LLVMUse = LLVMUse->getNext();
70 if (LLVMUse == nullptr) {
71 Use.Usr = nullptr;
72 return *this;
73 }
74 auto *Ctx = Use.Ctx;
75 auto *LLVMUser = LLVMUse->getUser();
76 Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser));
77 return *this;
78}
79
80Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
81 : SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
82#ifndef NDEBUG
84#endif
85}
86
88 llvm::Use *LLVMUse = nullptr;
89 if (Val->use_begin() != Val->use_end())
90 LLVMUse = &*Val->use_begin();
91 User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Ctx.getValue(
92 Val->use_begin()->getUser()))
93 : nullptr;
94 return use_iterator(Use(LLVMUse, User, Ctx));
95}
96
98 auto UseBegin = Val->use_begin();
99 auto UseEnd = Val->use_end();
100 bool AtEnd = UseBegin == UseEnd;
101 llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
102 User *User =
103 AtEnd ? nullptr
104 : cast_or_null<sandboxir::User>(Ctx.getValue(&*LLVMUse->getUser()));
105 return user_iterator(Use(LLVMUse, User, Ctx), UseToUser());
106}
107
108unsigned Value::getNumUses() const { return range_size(Val->users()); }
109
111 Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) {
112 assert(getType() == OtherV->getType() && "Can't replace with different type");
113 llvm::Value *OtherVal = OtherV->Val;
114 // We are delegating RUWIf to LLVM IR's RUWIf.
116 OtherVal, [&ShouldReplace, this](llvm::Use &LLVMUse) -> bool {
117 User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser()));
118 if (DstU == nullptr)
119 return false;
120 Use UseToReplace(&LLVMUse, DstU, Ctx);
121 if (!ShouldReplace(UseToReplace))
122 return false;
123 auto &Tracker = Ctx.getTracker();
124 if (Tracker.isTracking())
125 Tracker.track(std::make_unique<UseSet>(UseToReplace, Tracker));
126 return true;
127 });
128}
129
131 assert(getType() == Other->getType() &&
132 "Replacing with Value of different type!");
133 auto &Tracker = Ctx.getTracker();
134 if (Tracker.isTracking()) {
135 for (auto Use : uses())
136 Tracker.track(std::make_unique<UseSet>(Use, Tracker));
137 }
138 // We are delegating RAUW to LLVM IR's RAUW.
140}
141
142#ifndef NDEBUG
143std::string Value::getUid() const {
144 std::stringstream SS;
145 SS << "SB" << UID << ".";
146 return SS.str();
147}
148
150 OS << getUid() << " " << getSubclassIDStr(SubclassID) << " ";
151}
152
154 OS.indent(2) << "Val: ";
155 if (Val)
156 OS << *Val;
157 else
158 OS << "NULL";
159 OS << "\n";
160}
161
163 if (Val)
164 OS << *Val;
165 else
166 OS << "NULL ";
167}
168
170 OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")";
171}
172
174 if (Val)
176 else
177 OS << "NULL ";
178}
179
182}
186}
187void Argument::dump() const {
188 dump(dbgs());
189 dbgs() << "\n";
190}
191#endif // NDEBUG
192
193Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const {
194 assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!");
195 assert(isa<llvm::User>(Val) && "Non-users have no operands!");
196 llvm::Use *LLVMUse;
197 if (OpIdx != getNumOperands())
198 LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx);
199 else
200 LLVMUse = cast<llvm::User>(Val)->op_end();
201 return Use(LLVMUse, const_cast<User *>(this), Ctx);
202}
203
204#ifndef NDEBUG
206 assert(Ctx.getValue(Use.getUser()) == this &&
207 "Use not found in this SBUser's operands!");
208}
209#endif
210
212 switch (From->getSubclassID()) {
213#define DEF_VALUE(ID, CLASS)
214#define DEF_USER(ID, CLASS) \
215 case ClassID::ID: \
216 return true;
217#define DEF_INSTR(ID, OPC, CLASS) \
218 case ClassID::ID: \
219 return true;
220#include "llvm/SandboxIR/SandboxIRValues.def"
221 default:
222 return false;
223 }
224}
225
226void User::setOperand(unsigned OperandIdx, Value *Operand) {
227 assert(isa<llvm::User>(Val) && "No operands!");
228 auto &Tracker = Ctx.getTracker();
229 if (Tracker.isTracking())
230 Tracker.track(std::make_unique<UseSet>(getOperandUse(OperandIdx), Tracker));
231 // We are delegating to llvm::User::setOperand().
232 cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val);
233}
234
236 auto &Tracker = Ctx.getTracker();
237 if (Tracker.isTracking()) {
238 for (auto OpIdx : seq<unsigned>(0, getNumOperands())) {
239 auto Use = getOperandUse(OpIdx);
240 if (Use.get() == FromV)
241 Tracker.track(std::make_unique<UseSet>(Use, Tracker));
242 }
243 }
244 // We are delegating RUOW to LLVM IR's RUOW.
245 return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val);
246}
247
248#ifndef NDEBUG
251 // TODO: This is incomplete
252}
253#endif // NDEBUG
254
256 auto ItE = BB->end();
257 assert(It != ItE && "Already at end!");
258 ++It;
259 if (It == ItE)
260 return *this;
261 Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It));
262 unsigned Num = NextI.getNumOfIRInstrs();
263 assert(Num > 0 && "Bad getNumOfIRInstrs()");
264 It = std::next(It, Num - 1);
265 return *this;
266}
267
269 assert(It != BB->begin() && "Already at begin!");
270 if (It == BB->end()) {
271 --It;
272 return *this;
273 }
274 Instruction &CurrI = **this;
275 unsigned Num = CurrI.getNumOfIRInstrs();
276 assert(Num > 0 && "Bad getNumOfIRInstrs()");
277 assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!");
278 It = std::prev(It, Num);
279 return *this;
280}
281
283 switch (Opc) {
284#define DEF_VALUE(ID, CLASS)
285#define DEF_USER(ID, CLASS)
286#define OP(OPC) \
287 case Opcode::OPC: \
288 return #OPC;
289#define DEF_INSTR(ID, OPC, CLASS) OPC
290#include "llvm/SandboxIR/SandboxIRValues.def"
291 }
292 llvm_unreachable("Unknown Opcode");
293}
294
296 Instruction *Prev = getPrevNode();
297 if (Prev == nullptr) {
298 // If at top of the BB, return the first BB instruction.
299 return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
300 }
301 // Else get the Previous sandbox IR instruction's bottom IR instruction and
302 // return its successor.
303 llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val);
304 return PrevBotI->getNextNode();
305}
306
308 auto *I = cast<llvm::Instruction>(Val);
309 return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
310}
311
313 assert(getParent() != nullptr && "Detached!");
314 assert(getIterator() != getParent()->end() && "Already at end!");
315 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
316 // and get the corresponding sandboxir Instruction that maps to it. This works
317 // even for SandboxIR Instructions that map to more than one LLVM Instruction.
318 auto *LLVMI = cast<llvm::Instruction>(Val);
319 assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
320 auto *NextLLVMI = LLVMI->getNextNode();
321 auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
322 if (NextI == nullptr)
323 return nullptr;
324 return NextI;
325}
326
328 assert(getParent() != nullptr && "Detached!");
329 auto It = getIterator();
330 if (It != getParent()->begin())
331 return std::prev(getIterator()).get();
332 return nullptr;
333}
334
336 auto &Tracker = Ctx.getTracker();
337 if (Tracker.isTracking())
338 Tracker.track(std::make_unique<RemoveFromParent>(this, Tracker));
339
340 // Detach all the LLVM IR instructions from their parent BB.
342 I->removeFromParent();
343}
344
346 assert(users().empty() && "Still connected to users, can't erase!");
347 std::unique_ptr<Value> Detached = Ctx.detach(this);
348 auto LLVMInstrs = getLLVMInstrs();
349
350 auto &Tracker = Ctx.getTracker();
351 if (Tracker.isTracking()) {
353 std::make_unique<EraseFromParent>(std::move(Detached), Tracker));
354 // We don't actually delete the IR instruction, because then it would be
355 // impossible to bring it back from the dead at the same memory location.
356 // Instead we remove it from its BB and track its current location.
357 for (llvm::Instruction *I : LLVMInstrs)
358 I->removeFromParent();
359 // TODO: Multi-instructions need special treatment because some of the
360 // references are internal to the instruction.
361 for (llvm::Instruction *I : LLVMInstrs)
362 I->dropAllReferences();
363 } else {
364 // Erase in reverse to avoid erasing nstructions with attached uses.
365 for (llvm::Instruction *I : reverse(LLVMInstrs))
366 I->eraseFromParent();
367 }
368}
369
371 if (std::next(getIterator()) == WhereIt)
372 // Destination is same as origin, nothing to do.
373 return;
374
375 auto &Tracker = Ctx.getTracker();
376 if (Tracker.isTracking())
377 Tracker.track(std::make_unique<MoveInstr>(this, Tracker));
378
379 auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
381 if (WhereIt == BB.end()) {
382 It = LLVMBB->end();
383 } else {
384 Instruction *WhereI = &*WhereIt;
385 It = WhereI->getTopmostLLVMInstruction()->getIterator();
386 }
387 // TODO: Move this to the verifier of sandboxir::Instruction.
389 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
390 "Expected program order!");
391 // Do the actual move in LLVM IR.
392 for (auto *I : getLLVMInstrs())
393 I->moveBefore(*LLVMBB, It);
394}
395
397 llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
398 // TODO: Move this to the verifier of sandboxir::Instruction.
400 [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
401 "Expected program order!");
402 // Insert the LLVM IR Instructions in program order.
404 I->insertBefore(BeforeTopI);
405}
406
408 insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
409}
410
412 llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
413 llvm::Instruction *LLVMBeforeI;
414 llvm::BasicBlock::iterator LLVMBeforeIt;
415 if (WhereIt != BB->end()) {
416 Instruction *BeforeI = &*WhereIt;
417 LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
418 LLVMBeforeIt = LLVMBeforeI->getIterator();
419 } else {
420 LLVMBeforeI = nullptr;
421 LLVMBeforeIt = LLVMBB->end();
422 }
423 // Insert the LLVM IR Instructions in program order.
425 I->insertInto(LLVMBB, LLVMBeforeIt);
426}
427
429 // Get the LLVM IR Instruction that this maps to, get its parent, and get the
430 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
431 auto *BB = cast<llvm::Instruction>(Val)->getParent();
432 if (BB == nullptr)
433 return nullptr;
434 return cast<BasicBlock>(Ctx.getValue(BB));
435}
436
438 switch (From->getSubclassID()) {
439#define DEF_INSTR(ID, OPC, CLASS) \
440 case ClassID::ID: \
441 return true;
442#include "llvm/SandboxIR/SandboxIRValues.def"
443 default:
444 return false;
445 }
446}
447
448#ifndef NDEBUG
450 OS << "Unimplemented! Please override dump().";
451}
452void Instruction::dump() const {
453 dump(dbgs());
454 dbgs() << "\n";
455}
456#endif // NDEBUG
457
459 Instruction *InsertBefore, Context &Ctx,
460 const Twine &Name) {
461 llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
462 auto &Builder = Ctx.getLLVMIRBuilder();
463 Builder.SetInsertPoint(BeforeIR);
464 auto *NewLI = Builder.CreateAlignedLoad(Ty, Ptr->Val, Align,
465 /*isVolatile=*/false, Name);
466 auto *NewSBI = Ctx.createLoadInst(NewLI);
467 return NewSBI;
468}
469
471 BasicBlock *InsertAtEnd, Context &Ctx,
472 const Twine &Name) {
473 auto &Builder = Ctx.getLLVMIRBuilder();
474 Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
475 auto *NewLI = Builder.CreateAlignedLoad(Ty, Ptr->Val, Align,
476 /*isVolatile=*/false, Name);
477 auto *NewSBI = Ctx.createLoadInst(NewLI);
478 return NewSBI;
479}
480
482 return From->getSubclassID() == ClassID::Load;
483}
484
486 return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());
487}
488
489#ifndef NDEBUG
493}
494
495void LoadInst::dump() const {
496 dump(dbgs());
497 dbgs() << "\n";
498}
499
503}
504
505void OpaqueInst::dump() const {
506 dump(dbgs());
507 dbgs() << "\n";
508}
509
513}
514
515void Constant::dump() const {
516 dump(dbgs());
517 dbgs() << "\n";
518}
519
521 auto *F = cast<llvm::Function>(Val);
522 OS << *F->getReturnType() << " @" << F->getName() << "(";
524 F->args(),
525 [this, &OS](const llvm::Argument &LLVMArg) {
526 auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
527 if (SBArg == nullptr)
528 OS << "NULL";
529 else
530 SBArg->printAsOperand(OS);
531 },
532 [&] { OS << ", "; });
533 OS << ")";
534}
537 OS << " {\n";
538 auto *LLVMF = cast<llvm::Function>(Val);
540 *LLVMF,
541 [this, &OS](const llvm::BasicBlock &LLVMBB) {
542 auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
543 if (BB == nullptr)
544 OS << "NULL";
545 else
546 OS << *BB;
547 },
548 [&OS] { OS << "\n"; });
549 OS << "}\n";
550}
551void Function::dump() const {
552 dump(dbgs());
553 dbgs() << "\n";
554}
555#endif // NDEBUG
556
558BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
559 return cast_or_null<Instruction>(Ctx->getValue(&*It));
560}
561
562std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
563 std::unique_ptr<Value> Erased;
564 auto It = LLVMValueToValueMap.find(V);
565 if (It != LLVMValueToValueMap.end()) {
566 auto *Val = It->second.release();
567 Erased = std::unique_ptr<Value>(Val);
568 LLVMValueToValueMap.erase(It);
569 }
570 return Erased;
571}
572
573std::unique_ptr<Value> Context::detach(Value *V) {
574 assert(V->getSubclassID() != Value::ClassID::Constant &&
575 "Can't detach a constant!");
576 assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
577 return detachLLVMValue(V->Val);
578}
579
580Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
581 assert(VPtr->getSubclassID() != Value::ClassID::User &&
582 "Can't register a user!");
583 Value *V = VPtr.get();
584 [[maybe_unused]] auto Pair =
585 LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
586 assert(Pair.second && "Already exists!");
587 return V;
588}
589
591 auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr});
592 auto It = Pair.first;
593 if (!Pair.second)
594 return It->second.get();
595
596 if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
597 It->second = std::unique_ptr<Constant>(new Constant(C, *this));
598 auto *NewC = It->second.get();
599 for (llvm::Value *COp : C->operands())
601 return NewC;
602 }
603 if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
604 It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
605 return It->second.get();
606 }
607 if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
608 assert(isa<BlockAddress>(U) &&
609 "This won't create a SBBB, don't call this function directly!");
610 if (auto *SBBB = getValue(BB))
611 return SBBB;
612 return nullptr;
613 }
614 assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
615
616 switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
617 case llvm::Instruction::Load: {
618 auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
619 It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
620 return It->second.get();
621 }
622 default:
623 break;
624 }
625
626 It->second = std::unique_ptr<OpaqueInst>(
627 new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
628 return It->second.get();
629}
630
632 assert(getValue(LLVMBB) == nullptr && "Already exists!");
633 auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
634 auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
635 // Create SandboxIR for BB's body.
636 BB->buildBasicBlockFromLLVMIR(LLVMBB);
637 return BB;
638}
639
641 auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
642 return cast<LoadInst>(registerValue(std::move(NewPtr)));
643}
644
646 auto It = LLVMValueToValueMap.find(V);
647 if (It != LLVMValueToValueMap.end())
648 return It->second.get();
649 return nullptr;
650}
651
653 assert(getValue(F) == nullptr && "Already exists!");
654 auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
655 // Create arguments.
656 for (auto &Arg : F->args())
658 // Create BBs.
659 for (auto &BB : *F)
660 createBasicBlock(&BB);
661 auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
662 return SBF;
663}
664
666 auto *BB = cast<llvm::BasicBlock>(Val);
667 auto *F = BB->getParent();
668 if (F == nullptr)
669 // Detached
670 return nullptr;
671 return cast_or_null<Function>(Ctx.getValue(F));
672}
673
674void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
675 for (llvm::Instruction &IRef : reverse(*LLVMBB)) {
676 llvm::Instruction *I = &IRef;
678 for (auto [OpIdx, Op] : enumerate(I->operands())) {
679 // Skip instruction's label operands
680 if (isa<llvm::BasicBlock>(Op))
681 continue;
682 // Skip metadata
683 if (isa<llvm::MetadataAsValue>(Op))
684 continue;
685 // Skip asm
686 if (isa<llvm::InlineAsm>(Op))
687 continue;
689 }
690 }
691#if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
692 verify();
693#endif
694}
695
697 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
699 if (!BB->empty()) {
700 auto *V = Ctx.getValue(&*BB->begin());
701 assert(V != nullptr && "No SandboxIR for BB->begin()!");
702 auto *I = cast<Instruction>(V);
703 unsigned Num = I->getNumOfIRInstrs();
704 assert(Num >= 1u && "Bad getNumOfIRInstrs()");
705 It = std::next(It, Num - 1);
706 }
707 return iterator(BB, It, &Ctx);
708}
709
711 auto *TerminatorV =
712 Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
713 return cast_or_null<Instruction>(TerminatorV);
714}
715
717 auto *BB = cast<llvm::BasicBlock>(Val);
718 assert(!BB->empty() && "Empty block!");
719 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
720 assert(SBI != nullptr && "Expected Instr!");
721 return *SBI;
722}
723
725 auto *BB = cast<llvm::BasicBlock>(Val);
726 assert(!BB->empty() && "Empty block!");
727 auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
728 assert(SBI != nullptr && "Expected Instr!");
729 return *SBI;
730}
731
732#ifndef NDEBUG
734 llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
735 const auto &Name = BB->getName();
736 OS << Name;
737 if (!Name.empty())
738 OS << ":\n";
739 // If there are Instructions in the BB that are not mapped to SandboxIR, then
740 // use a crash-proof dump.
741 if (any_of(*BB, [this](llvm::Instruction &I) {
742 return Ctx.getValue(&I) == nullptr;
743 })) {
744 OS << "<Crash-proof mode!>\n";
746 for (llvm::Instruction &IRef : *BB) {
747 Value *SBV = Ctx.getValue(&IRef);
748 if (SBV == nullptr)
749 OS << IRef << " *** No SandboxIR ***\n";
750 else {
751 auto *SBI = dyn_cast<Instruction>(SBV);
752 if (SBI == nullptr) {
753 OS << IRef << " *** Not a SBInstruction!!! ***\n";
754 } else {
755 if (Visited.insert(SBI).second)
756 OS << *SBI << "\n";
757 }
758 }
759 }
760 } else {
761 for (auto &SBI : *this) {
762 SBI.dump(OS);
763 OS << "\n";
764 }
765 }
766}
767void BasicBlock::dump() const {
768 dump(dbgs());
769 dbgs() << "\n";
770}
771#endif // NDEBUG
BlockVerifier::State From
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallPtrSet 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
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
iterator end()
Definition: BasicBlock.h:451
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:438
bool empty() const
Definition: BasicBlock.h:460
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:167
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
const char * getOpcodeName() const
Definition: Instruction.h:276
An instruction for reading from memory.
Definition: Instructions.h:174
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
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:5105
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
Argument of a sandboxir::Function.
Definition: SandboxIR.h:291
void printAsOperand(raw_ostream &OS) const
Definition: SandboxIR.cpp:180
LLVM_DUMP_METHOD void dump() const final
Definition: SandboxIR.cpp:187
Iterator for Instructions in a `BasicBlock.
Definition: SandboxIR.h:435
Contains a list of sandboxir::Instruction's.
Definition: SandboxIR.h:640
void verify() const final
Should crash if there is something wrong with the instruction.
Definition: SandboxIR.h:678
Function * getParent() const
Definition: SandboxIR.cpp:665
Instruction & front() const
Definition: SandboxIR.cpp:716
Instruction * getTerminator() const
Definition: SandboxIR.cpp:710
Context & getContext() const
Definition: SandboxIR.h:671
Instruction & back() const
Definition: SandboxIR.cpp:724
iterator begin() const
Definition: SandboxIR.cpp:696
iterator end() const
Definition: SandboxIR.h:661
LLVM_DUMP_METHOD void dump() const final
Definition: SandboxIR.cpp:767
LLVM_DUMP_METHOD void dump() const override
Definition: SandboxIR.cpp:515
DenseMap< llvm::Value *, std::unique_ptr< sandboxir::Value > > LLVMValueToValueMap
Maps LLVM Value to the corresponding sandboxir::Value.
Definition: SandboxIR.h:698
Value * registerValue(std::unique_ptr< Value > &&VPtr)
Take ownership of VPtr and store it in LLVMValueToValueMap.
Definition: SandboxIR.cpp:580
sandboxir::Value * getValue(llvm::Value *V) const
Definition: SandboxIR.cpp:645
Argument * getOrCreateArgument(llvm::Argument *LLVMArg)
Get or create a sandboxir::Argument for an existing LLVM IR LLVMArg.
Definition: SandboxIR.h:713
Function * createFunction(llvm::Function *F)
Create a sandboxir::Function for an existing LLVM IR F, including all blocks and instructions.
Definition: SandboxIR.cpp:652
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:590
std::unique_ptr< Value > detach(Value *V)
Remove SBV from all SandboxIR maps and stop owning it.
Definition: SandboxIR.cpp:573
BasicBlock * createBasicBlock(llvm::BasicBlock *BB)
Create a sandboxir::BasicBlock for an existing LLVM IR BB.
Definition: SandboxIR.cpp:631
LoadInst * createLoadInst(llvm::LoadInst *LI)
Definition: SandboxIR.cpp:640
std::unique_ptr< Value > detachLLVMValue(llvm::Value *V)
Remove V from the maps and returns the unique_ptr.
Definition: SandboxIR.cpp:562
Value * getOrCreateValue(llvm::Value *LLVMV)
Get or create a sandboxir::Value for an existing LLVM IR LLVMV.
Definition: SandboxIR.h:723
Tracker & getTracker()
Definition: SandboxIR.h:743
friend class BasicBlock
Various leaf nodes.
Definition: SandboxIR.h:730
size_t getNumValues() const
\Returns the number of values registered with Context.
Definition: SandboxIR.h:761
void dumpNameAndArgs(raw_ostream &OS) const
Definition: SandboxIR.cpp:520
LLVM_DUMP_METHOD void dump() const final
Definition: SandboxIR.cpp:551
A sandboxir::User with operands, opcode and linked with previous/next instructions in an instruction ...
Definition: SandboxIR.h:478
BBIterator getIterator() const
\Returns a BasicBlock::iterator for this Instruction.
Definition: SandboxIR.cpp:307
void removeFromParent()
Detach this from its parent BasicBlock without deleting it.
Definition: SandboxIR.cpp:335
virtual unsigned getNumOfIRInstrs() const =0
This is used by BasicBlock::iterator.
static bool classof(const sandboxir::Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:437
void insertInto(BasicBlock *BB, const BBIterator &WhereIt)
Insert this detached instruction into BB at WhereIt.
Definition: SandboxIR.cpp:411
void eraseFromParent()
Detach this Value from its parent and delete it.
Definition: SandboxIR.cpp:345
Instruction * getNextNode() const
\Returns the next sandboxir::Instruction in the block, or nullptr if at the end of the block.
Definition: SandboxIR.cpp:312
void moveBefore(BasicBlock &BB, const BBIterator &WhereIt)
Move this instruction to WhereIt.
Definition: SandboxIR.cpp:370
llvm::Instruction * getTopmostLLVMInstruction() const
A SandboxIR Instruction may map to multiple LLVM IR Instruction.
Definition: SandboxIR.cpp:295
LLVM_DUMP_METHOD void dump() const override
Definition: SandboxIR.cpp:452
void insertAfter(Instruction *AfterI)
Insert this detached instruction after AfterI.
Definition: SandboxIR.cpp:407
virtual SmallVector< llvm::Instruction *, 1 > getLLVMInstrs() const =0
\Returns the LLVM IR Instructions that this SandboxIR maps to in program order.
Instruction * getPrevNode() const
\Returns the previous sandboxir::Instruction in the block, or nullptr if at the beginning of the bloc...
Definition: SandboxIR.cpp:327
void insertBefore(Instruction *BeforeI)
Insert this detached instruction before BeforeI.
Definition: SandboxIR.cpp:396
BasicBlock * getParent() const
\Returns the BasicBlock containing this Instruction, or null if it is detached.
Definition: SandboxIR.cpp:428
static bool classof(const Value *From)
For isa/dyn_cast.
Definition: SandboxIR.cpp:481
LLVM_DUMP_METHOD void dump() const override
Definition: SandboxIR.cpp:495
static LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, Instruction *InsertBefore, Context &Ctx, const Twine &Name="")
Definition: SandboxIR.cpp:458
Value * getPointerOperand() const
Definition: SandboxIR.cpp:485
An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to an OpaqueInstr.
Definition: SandboxIR.h:604
LLVM_DUMP_METHOD void dump() const override
Definition: SandboxIR.cpp:505
Iterator for the Use edges of a User's operands.
Definition: SandboxIR.h:84
OperandUseIterator & operator++()
Definition: SandboxIR.cpp:57
The tracker collects all the change objects and implements the main API for saving / reverting / acce...
Definition: Tracker.h:181
bool isTracking() const
\Returns true if the tracker is recording changes.
Definition: Tracker.h:212
void track(std::unique_ptr< IRChangeBase > &&Change)
Record Change and take ownership.
Definition: Tracker.cpp:151
Represents a Def-use/Use-def edge in SandboxIR.
Definition: Use.h:29
unsigned getOperandNo() const
Definition: SandboxIR.cpp:21
Value * get() const
Definition: SandboxIR.cpp:17
void set(Value *V)
Definition: SandboxIR.cpp:19
class User * getUser() const
Definition: Use.h:48
void dump() const
Definition: SandboxIR.cpp:52
Iterator for the Use edges of a Value's users.
Definition: SandboxIR.h:112
UserUseIterator & operator++()
Definition: SandboxIR.cpp:64
A sandboxir::User has operands.
Definition: SandboxIR.h:316
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:211
bool replaceUsesOfWith(Value *FromV, Value *ToV)
Replaces any operands that match FromV with ToV.
Definition: SandboxIR.cpp:235
void verifyUserOfLLVMUse(const llvm::Use &Use) const
Definition: SandboxIR.cpp:205
Use getOperandUseDefault(unsigned OpIdx, bool Verify) const
\Returns the Use edge that corresponds to OpIdx.
Definition: SandboxIR.cpp:193
virtual void setOperand(unsigned OperandIdx, Value *Operand)
Definition: SandboxIR.cpp:226
virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const =0
\Returns the Use for the OpIdx'th operand.
virtual unsigned getNumOperands() const
Definition: SandboxIR.h:378
Use getOperandUse(unsigned OpIdx) const
\Returns the operand edge for OpIdx.
Definition: SandboxIR.h:375
void dumpCommonHeader(raw_ostream &OS) const final
Definition: SandboxIR.cpp:249
A SandboxIR Value has users. This is the base class.
Definition: SandboxIR.h:137
mapped_iterator< sandboxir::UserUseIterator, UseToUser > user_iterator
Definition: SandboxIR.h:216
use_iterator use_begin()
Definition: SandboxIR.cpp:87
llvm::Value * Val
The LLVM Value that corresponds to this SandboxIR Value.
Definition: SandboxIR.h:173
std::string getUid() const
Returns the unique id in the form 'SB<number>.' like 'SB1.'.
Definition: SandboxIR.cpp:143
user_iterator user_begin()
Definition: SandboxIR.cpp:97
void replaceAllUsesWith(Value *Other)
Definition: SandboxIR.cpp:130
void dumpCommonFooter(raw_ostream &OS) const
Definition: SandboxIR.cpp:153
virtual void dumpCommonHeader(raw_ostream &OS) const
Definition: SandboxIR.cpp:149
UserUseIterator use_iterator
Definition: SandboxIR.h:192
Context & Ctx
All values point to the context.
Definition: SandboxIR.h:181
ClassID SubclassID
For isa/dyn_cast.
Definition: SandboxIR.h:164
void dumpCommonSuffix(raw_ostream &OS) const
Definition: SandboxIR.cpp:169
Type * getType() const
Definition: SandboxIR.h:260
friend class Use
Definition: SandboxIR.h:177
Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
Definition: SandboxIR.cpp:80
iterator_range< user_iterator > users()
Definition: SandboxIR.h:230
void replaceUsesWithIf(Value *OtherV, llvm::function_ref< bool(const Use &)> ShouldReplace)
Definition: SandboxIR.cpp:110
unsigned getNumUses() const
\Returns the number of user edges (not necessarily to unique users).
Definition: SandboxIR.cpp:108
unsigned UID
A unique ID used for forming the name (used for debugging).
Definition: SandboxIR.h:167
iterator_range< use_iterator > uses()
Definition: SandboxIR.h:204
void dumpCommonPrefix(raw_ostream &OS) const
Definition: SandboxIR.cpp:162
void printAsOperandCommon(raw_ostream &OS) const
Definition: SandboxIR.cpp:173
static const char * getSubclassIDStr(ClassID ID)
Definition: SandboxIR.h:147
#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 are tuples (A,...
Definition: STLExtras.h:2400
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:2121
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:419
constexpr size_t range_size(R &&Range)
Returns the size of the Range, i.e., the number of elements.
Definition: STLExtras.h:1705
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
Definition: STLExtras.h:1902
@ Other
Any other memory.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
Helper for mapped_iterator.
Definition: SandboxIR.h:212