xref: /freebsd-src/contrib/llvm-project/llvm/lib/SandboxIR/SandboxIR.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===- SandboxIR.cpp - A transactional overlay IR on top of LLVM IR -------===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric 
9*0fca6ea1SDimitry Andric #include "llvm/SandboxIR/SandboxIR.h"
10*0fca6ea1SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
11*0fca6ea1SDimitry Andric #include "llvm/IR/Constants.h"
12*0fca6ea1SDimitry Andric #include "llvm/Support/Debug.h"
13*0fca6ea1SDimitry Andric #include <sstream>
14*0fca6ea1SDimitry Andric 
15*0fca6ea1SDimitry Andric using namespace llvm::sandboxir;
16*0fca6ea1SDimitry Andric 
17*0fca6ea1SDimitry Andric Value *Use::get() const { return Ctx->getValue(LLVMUse->get()); }
18*0fca6ea1SDimitry Andric 
19*0fca6ea1SDimitry Andric void Use::set(Value *V) { LLVMUse->set(V->Val); }
20*0fca6ea1SDimitry Andric 
21*0fca6ea1SDimitry Andric unsigned Use::getOperandNo() const { return Usr->getUseOperandNo(*this); }
22*0fca6ea1SDimitry Andric 
23*0fca6ea1SDimitry Andric #ifndef NDEBUG
24*0fca6ea1SDimitry Andric void Use::dump(raw_ostream &OS) const {
25*0fca6ea1SDimitry Andric   Value *Def = nullptr;
26*0fca6ea1SDimitry Andric   if (LLVMUse == nullptr)
27*0fca6ea1SDimitry Andric     OS << "<null> LLVM Use! ";
28*0fca6ea1SDimitry Andric   else
29*0fca6ea1SDimitry Andric     Def = Ctx->getValue(LLVMUse->get());
30*0fca6ea1SDimitry Andric   OS << "Def:  ";
31*0fca6ea1SDimitry Andric   if (Def == nullptr)
32*0fca6ea1SDimitry Andric     OS << "NULL";
33*0fca6ea1SDimitry Andric   else
34*0fca6ea1SDimitry Andric     OS << *Def;
35*0fca6ea1SDimitry Andric   OS << "\n";
36*0fca6ea1SDimitry Andric 
37*0fca6ea1SDimitry Andric   OS << "User: ";
38*0fca6ea1SDimitry Andric   if (Usr == nullptr)
39*0fca6ea1SDimitry Andric     OS << "NULL";
40*0fca6ea1SDimitry Andric   else
41*0fca6ea1SDimitry Andric     OS << *Usr;
42*0fca6ea1SDimitry Andric   OS << "\n";
43*0fca6ea1SDimitry Andric 
44*0fca6ea1SDimitry Andric   OS << "OperandNo: ";
45*0fca6ea1SDimitry Andric   if (Usr == nullptr)
46*0fca6ea1SDimitry Andric     OS << "N/A";
47*0fca6ea1SDimitry Andric   else
48*0fca6ea1SDimitry Andric     OS << getOperandNo();
49*0fca6ea1SDimitry Andric   OS << "\n";
50*0fca6ea1SDimitry Andric }
51*0fca6ea1SDimitry Andric 
52*0fca6ea1SDimitry Andric void Use::dump() const { dump(dbgs()); }
53*0fca6ea1SDimitry Andric #endif // NDEBUG
54*0fca6ea1SDimitry Andric 
55*0fca6ea1SDimitry Andric Use OperandUseIterator::operator*() const { return Use; }
56*0fca6ea1SDimitry Andric 
57*0fca6ea1SDimitry Andric OperandUseIterator &OperandUseIterator::operator++() {
58*0fca6ea1SDimitry Andric   assert(Use.LLVMUse != nullptr && "Already at end!");
59*0fca6ea1SDimitry Andric   User *User = Use.getUser();
60*0fca6ea1SDimitry Andric   Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false);
61*0fca6ea1SDimitry Andric   return *this;
62*0fca6ea1SDimitry Andric }
63*0fca6ea1SDimitry Andric 
64*0fca6ea1SDimitry Andric UserUseIterator &UserUseIterator::operator++() {
65*0fca6ea1SDimitry Andric   // Get the corresponding llvm::Use, get the next in the list, and update the
66*0fca6ea1SDimitry Andric   // sandboxir::Use.
67*0fca6ea1SDimitry Andric   llvm::Use *&LLVMUse = Use.LLVMUse;
68*0fca6ea1SDimitry Andric   assert(LLVMUse != nullptr && "Already at end!");
69*0fca6ea1SDimitry Andric   LLVMUse = LLVMUse->getNext();
70*0fca6ea1SDimitry Andric   if (LLVMUse == nullptr) {
71*0fca6ea1SDimitry Andric     Use.Usr = nullptr;
72*0fca6ea1SDimitry Andric     return *this;
73*0fca6ea1SDimitry Andric   }
74*0fca6ea1SDimitry Andric   auto *Ctx = Use.Ctx;
75*0fca6ea1SDimitry Andric   auto *LLVMUser = LLVMUse->getUser();
76*0fca6ea1SDimitry Andric   Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser));
77*0fca6ea1SDimitry Andric   return *this;
78*0fca6ea1SDimitry Andric }
79*0fca6ea1SDimitry Andric 
80*0fca6ea1SDimitry Andric Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
81*0fca6ea1SDimitry Andric     : SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
82*0fca6ea1SDimitry Andric #ifndef NDEBUG
83*0fca6ea1SDimitry Andric   UID = Ctx.getNumValues();
84*0fca6ea1SDimitry Andric #endif
85*0fca6ea1SDimitry Andric }
86*0fca6ea1SDimitry Andric 
87*0fca6ea1SDimitry Andric Value::use_iterator Value::use_begin() {
88*0fca6ea1SDimitry Andric   llvm::Use *LLVMUse = nullptr;
89*0fca6ea1SDimitry Andric   if (Val->use_begin() != Val->use_end())
90*0fca6ea1SDimitry Andric     LLVMUse = &*Val->use_begin();
91*0fca6ea1SDimitry Andric   User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Ctx.getValue(
92*0fca6ea1SDimitry Andric                                         Val->use_begin()->getUser()))
93*0fca6ea1SDimitry Andric                                   : nullptr;
94*0fca6ea1SDimitry Andric   return use_iterator(Use(LLVMUse, User, Ctx));
95*0fca6ea1SDimitry Andric }
96*0fca6ea1SDimitry Andric 
97*0fca6ea1SDimitry Andric Value::user_iterator Value::user_begin() {
98*0fca6ea1SDimitry Andric   auto UseBegin = Val->use_begin();
99*0fca6ea1SDimitry Andric   auto UseEnd = Val->use_end();
100*0fca6ea1SDimitry Andric   bool AtEnd = UseBegin == UseEnd;
101*0fca6ea1SDimitry Andric   llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
102*0fca6ea1SDimitry Andric   User *User =
103*0fca6ea1SDimitry Andric       AtEnd ? nullptr
104*0fca6ea1SDimitry Andric             : cast_or_null<sandboxir::User>(Ctx.getValue(&*LLVMUse->getUser()));
105*0fca6ea1SDimitry Andric   return user_iterator(Use(LLVMUse, User, Ctx), UseToUser());
106*0fca6ea1SDimitry Andric }
107*0fca6ea1SDimitry Andric 
108*0fca6ea1SDimitry Andric unsigned Value::getNumUses() const { return range_size(Val->users()); }
109*0fca6ea1SDimitry Andric 
110*0fca6ea1SDimitry Andric void Value::replaceUsesWithIf(
111*0fca6ea1SDimitry Andric     Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) {
112*0fca6ea1SDimitry Andric   assert(getType() == OtherV->getType() && "Can't replace with different type");
113*0fca6ea1SDimitry Andric   llvm::Value *OtherVal = OtherV->Val;
114*0fca6ea1SDimitry Andric   // We are delegating RUWIf to LLVM IR's RUWIf.
115*0fca6ea1SDimitry Andric   Val->replaceUsesWithIf(
116*0fca6ea1SDimitry Andric       OtherVal, [&ShouldReplace, this](llvm::Use &LLVMUse) -> bool {
117*0fca6ea1SDimitry Andric         User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser()));
118*0fca6ea1SDimitry Andric         if (DstU == nullptr)
119*0fca6ea1SDimitry Andric           return false;
120*0fca6ea1SDimitry Andric         Use UseToReplace(&LLVMUse, DstU, Ctx);
121*0fca6ea1SDimitry Andric         if (!ShouldReplace(UseToReplace))
122*0fca6ea1SDimitry Andric           return false;
123*0fca6ea1SDimitry Andric         auto &Tracker = Ctx.getTracker();
124*0fca6ea1SDimitry Andric         if (Tracker.isTracking())
125*0fca6ea1SDimitry Andric           Tracker.track(std::make_unique<UseSet>(UseToReplace, Tracker));
126*0fca6ea1SDimitry Andric         return true;
127*0fca6ea1SDimitry Andric       });
128*0fca6ea1SDimitry Andric }
129*0fca6ea1SDimitry Andric 
130*0fca6ea1SDimitry Andric void Value::replaceAllUsesWith(Value *Other) {
131*0fca6ea1SDimitry Andric   assert(getType() == Other->getType() &&
132*0fca6ea1SDimitry Andric          "Replacing with Value of different type!");
133*0fca6ea1SDimitry Andric   auto &Tracker = Ctx.getTracker();
134*0fca6ea1SDimitry Andric   if (Tracker.isTracking()) {
135*0fca6ea1SDimitry Andric     for (auto Use : uses())
136*0fca6ea1SDimitry Andric       Tracker.track(std::make_unique<UseSet>(Use, Tracker));
137*0fca6ea1SDimitry Andric   }
138*0fca6ea1SDimitry Andric   // We are delegating RAUW to LLVM IR's RAUW.
139*0fca6ea1SDimitry Andric   Val->replaceAllUsesWith(Other->Val);
140*0fca6ea1SDimitry Andric }
141*0fca6ea1SDimitry Andric 
142*0fca6ea1SDimitry Andric #ifndef NDEBUG
143*0fca6ea1SDimitry Andric std::string Value::getUid() const {
144*0fca6ea1SDimitry Andric   std::stringstream SS;
145*0fca6ea1SDimitry Andric   SS << "SB" << UID << ".";
146*0fca6ea1SDimitry Andric   return SS.str();
147*0fca6ea1SDimitry Andric }
148*0fca6ea1SDimitry Andric 
149*0fca6ea1SDimitry Andric void Value::dumpCommonHeader(raw_ostream &OS) const {
150*0fca6ea1SDimitry Andric   OS << getUid() << " " << getSubclassIDStr(SubclassID) << " ";
151*0fca6ea1SDimitry Andric }
152*0fca6ea1SDimitry Andric 
153*0fca6ea1SDimitry Andric void Value::dumpCommonFooter(raw_ostream &OS) const {
154*0fca6ea1SDimitry Andric   OS.indent(2) << "Val: ";
155*0fca6ea1SDimitry Andric   if (Val)
156*0fca6ea1SDimitry Andric     OS << *Val;
157*0fca6ea1SDimitry Andric   else
158*0fca6ea1SDimitry Andric     OS << "NULL";
159*0fca6ea1SDimitry Andric   OS << "\n";
160*0fca6ea1SDimitry Andric }
161*0fca6ea1SDimitry Andric 
162*0fca6ea1SDimitry Andric void Value::dumpCommonPrefix(raw_ostream &OS) const {
163*0fca6ea1SDimitry Andric   if (Val)
164*0fca6ea1SDimitry Andric     OS << *Val;
165*0fca6ea1SDimitry Andric   else
166*0fca6ea1SDimitry Andric     OS << "NULL ";
167*0fca6ea1SDimitry Andric }
168*0fca6ea1SDimitry Andric 
169*0fca6ea1SDimitry Andric void Value::dumpCommonSuffix(raw_ostream &OS) const {
170*0fca6ea1SDimitry Andric   OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")";
171*0fca6ea1SDimitry Andric }
172*0fca6ea1SDimitry Andric 
173*0fca6ea1SDimitry Andric void Value::printAsOperandCommon(raw_ostream &OS) const {
174*0fca6ea1SDimitry Andric   if (Val)
175*0fca6ea1SDimitry Andric     Val->printAsOperand(OS);
176*0fca6ea1SDimitry Andric   else
177*0fca6ea1SDimitry Andric     OS << "NULL ";
178*0fca6ea1SDimitry Andric }
179*0fca6ea1SDimitry Andric 
180*0fca6ea1SDimitry Andric void Argument::printAsOperand(raw_ostream &OS) const {
181*0fca6ea1SDimitry Andric   printAsOperandCommon(OS);
182*0fca6ea1SDimitry Andric }
183*0fca6ea1SDimitry Andric void Argument::dump(raw_ostream &OS) const {
184*0fca6ea1SDimitry Andric   dumpCommonPrefix(OS);
185*0fca6ea1SDimitry Andric   dumpCommonSuffix(OS);
186*0fca6ea1SDimitry Andric }
187*0fca6ea1SDimitry Andric void Argument::dump() const {
188*0fca6ea1SDimitry Andric   dump(dbgs());
189*0fca6ea1SDimitry Andric   dbgs() << "\n";
190*0fca6ea1SDimitry Andric }
191*0fca6ea1SDimitry Andric #endif // NDEBUG
192*0fca6ea1SDimitry Andric 
193*0fca6ea1SDimitry Andric Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const {
194*0fca6ea1SDimitry Andric   assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!");
195*0fca6ea1SDimitry Andric   assert(isa<llvm::User>(Val) && "Non-users have no operands!");
196*0fca6ea1SDimitry Andric   llvm::Use *LLVMUse;
197*0fca6ea1SDimitry Andric   if (OpIdx != getNumOperands())
198*0fca6ea1SDimitry Andric     LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx);
199*0fca6ea1SDimitry Andric   else
200*0fca6ea1SDimitry Andric     LLVMUse = cast<llvm::User>(Val)->op_end();
201*0fca6ea1SDimitry Andric   return Use(LLVMUse, const_cast<User *>(this), Ctx);
202*0fca6ea1SDimitry Andric }
203*0fca6ea1SDimitry Andric 
204*0fca6ea1SDimitry Andric #ifndef NDEBUG
205*0fca6ea1SDimitry Andric void User::verifyUserOfLLVMUse(const llvm::Use &Use) const {
206*0fca6ea1SDimitry Andric   assert(Ctx.getValue(Use.getUser()) == this &&
207*0fca6ea1SDimitry Andric          "Use not found in this SBUser's operands!");
208*0fca6ea1SDimitry Andric }
209*0fca6ea1SDimitry Andric #endif
210*0fca6ea1SDimitry Andric 
211*0fca6ea1SDimitry Andric bool User::classof(const Value *From) {
212*0fca6ea1SDimitry Andric   switch (From->getSubclassID()) {
213*0fca6ea1SDimitry Andric #define DEF_VALUE(ID, CLASS)
214*0fca6ea1SDimitry Andric #define DEF_USER(ID, CLASS)                                                    \
215*0fca6ea1SDimitry Andric   case ClassID::ID:                                                            \
216*0fca6ea1SDimitry Andric     return true;
217*0fca6ea1SDimitry Andric #define DEF_INSTR(ID, OPC, CLASS)                                              \
218*0fca6ea1SDimitry Andric   case ClassID::ID:                                                            \
219*0fca6ea1SDimitry Andric     return true;
220*0fca6ea1SDimitry Andric #include "llvm/SandboxIR/SandboxIRValues.def"
221*0fca6ea1SDimitry Andric   default:
222*0fca6ea1SDimitry Andric     return false;
223*0fca6ea1SDimitry Andric   }
224*0fca6ea1SDimitry Andric }
225*0fca6ea1SDimitry Andric 
226*0fca6ea1SDimitry Andric void User::setOperand(unsigned OperandIdx, Value *Operand) {
227*0fca6ea1SDimitry Andric   assert(isa<llvm::User>(Val) && "No operands!");
228*0fca6ea1SDimitry Andric   auto &Tracker = Ctx.getTracker();
229*0fca6ea1SDimitry Andric   if (Tracker.isTracking())
230*0fca6ea1SDimitry Andric     Tracker.track(std::make_unique<UseSet>(getOperandUse(OperandIdx), Tracker));
231*0fca6ea1SDimitry Andric   // We are delegating to llvm::User::setOperand().
232*0fca6ea1SDimitry Andric   cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val);
233*0fca6ea1SDimitry Andric }
234*0fca6ea1SDimitry Andric 
235*0fca6ea1SDimitry Andric bool User::replaceUsesOfWith(Value *FromV, Value *ToV) {
236*0fca6ea1SDimitry Andric   auto &Tracker = Ctx.getTracker();
237*0fca6ea1SDimitry Andric   if (Tracker.isTracking()) {
238*0fca6ea1SDimitry Andric     for (auto OpIdx : seq<unsigned>(0, getNumOperands())) {
239*0fca6ea1SDimitry Andric       auto Use = getOperandUse(OpIdx);
240*0fca6ea1SDimitry Andric       if (Use.get() == FromV)
241*0fca6ea1SDimitry Andric         Tracker.track(std::make_unique<UseSet>(Use, Tracker));
242*0fca6ea1SDimitry Andric     }
243*0fca6ea1SDimitry Andric   }
244*0fca6ea1SDimitry Andric   // We are delegating RUOW to LLVM IR's RUOW.
245*0fca6ea1SDimitry Andric   return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val);
246*0fca6ea1SDimitry Andric }
247*0fca6ea1SDimitry Andric 
248*0fca6ea1SDimitry Andric #ifndef NDEBUG
249*0fca6ea1SDimitry Andric void User::dumpCommonHeader(raw_ostream &OS) const {
250*0fca6ea1SDimitry Andric   Value::dumpCommonHeader(OS);
251*0fca6ea1SDimitry Andric   // TODO: This is incomplete
252*0fca6ea1SDimitry Andric }
253*0fca6ea1SDimitry Andric #endif // NDEBUG
254*0fca6ea1SDimitry Andric 
255*0fca6ea1SDimitry Andric BBIterator &BBIterator::operator++() {
256*0fca6ea1SDimitry Andric   auto ItE = BB->end();
257*0fca6ea1SDimitry Andric   assert(It != ItE && "Already at end!");
258*0fca6ea1SDimitry Andric   ++It;
259*0fca6ea1SDimitry Andric   if (It == ItE)
260*0fca6ea1SDimitry Andric     return *this;
261*0fca6ea1SDimitry Andric   Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It));
262*0fca6ea1SDimitry Andric   unsigned Num = NextI.getNumOfIRInstrs();
263*0fca6ea1SDimitry Andric   assert(Num > 0 && "Bad getNumOfIRInstrs()");
264*0fca6ea1SDimitry Andric   It = std::next(It, Num - 1);
265*0fca6ea1SDimitry Andric   return *this;
266*0fca6ea1SDimitry Andric }
267*0fca6ea1SDimitry Andric 
268*0fca6ea1SDimitry Andric BBIterator &BBIterator::operator--() {
269*0fca6ea1SDimitry Andric   assert(It != BB->begin() && "Already at begin!");
270*0fca6ea1SDimitry Andric   if (It == BB->end()) {
271*0fca6ea1SDimitry Andric     --It;
272*0fca6ea1SDimitry Andric     return *this;
273*0fca6ea1SDimitry Andric   }
274*0fca6ea1SDimitry Andric   Instruction &CurrI = **this;
275*0fca6ea1SDimitry Andric   unsigned Num = CurrI.getNumOfIRInstrs();
276*0fca6ea1SDimitry Andric   assert(Num > 0 && "Bad getNumOfIRInstrs()");
277*0fca6ea1SDimitry Andric   assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!");
278*0fca6ea1SDimitry Andric   It = std::prev(It, Num);
279*0fca6ea1SDimitry Andric   return *this;
280*0fca6ea1SDimitry Andric }
281*0fca6ea1SDimitry Andric 
282*0fca6ea1SDimitry Andric const char *Instruction::getOpcodeName(Opcode Opc) {
283*0fca6ea1SDimitry Andric   switch (Opc) {
284*0fca6ea1SDimitry Andric #define DEF_VALUE(ID, CLASS)
285*0fca6ea1SDimitry Andric #define DEF_USER(ID, CLASS)
286*0fca6ea1SDimitry Andric #define OP(OPC)                                                                \
287*0fca6ea1SDimitry Andric   case Opcode::OPC:                                                            \
288*0fca6ea1SDimitry Andric     return #OPC;
289*0fca6ea1SDimitry Andric #define DEF_INSTR(ID, OPC, CLASS) OPC
290*0fca6ea1SDimitry Andric #include "llvm/SandboxIR/SandboxIRValues.def"
291*0fca6ea1SDimitry Andric   }
292*0fca6ea1SDimitry Andric   llvm_unreachable("Unknown Opcode");
293*0fca6ea1SDimitry Andric }
294*0fca6ea1SDimitry Andric 
295*0fca6ea1SDimitry Andric llvm::Instruction *Instruction::getTopmostLLVMInstruction() const {
296*0fca6ea1SDimitry Andric   Instruction *Prev = getPrevNode();
297*0fca6ea1SDimitry Andric   if (Prev == nullptr) {
298*0fca6ea1SDimitry Andric     // If at top of the BB, return the first BB instruction.
299*0fca6ea1SDimitry Andric     return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
300*0fca6ea1SDimitry Andric   }
301*0fca6ea1SDimitry Andric   // Else get the Previous sandbox IR instruction's bottom IR instruction and
302*0fca6ea1SDimitry Andric   // return its successor.
303*0fca6ea1SDimitry Andric   llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val);
304*0fca6ea1SDimitry Andric   return PrevBotI->getNextNode();
305*0fca6ea1SDimitry Andric }
306*0fca6ea1SDimitry Andric 
307*0fca6ea1SDimitry Andric BBIterator Instruction::getIterator() const {
308*0fca6ea1SDimitry Andric   auto *I = cast<llvm::Instruction>(Val);
309*0fca6ea1SDimitry Andric   return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
310*0fca6ea1SDimitry Andric }
311*0fca6ea1SDimitry Andric 
312*0fca6ea1SDimitry Andric Instruction *Instruction::getNextNode() const {
313*0fca6ea1SDimitry Andric   assert(getParent() != nullptr && "Detached!");
314*0fca6ea1SDimitry Andric   assert(getIterator() != getParent()->end() && "Already at end!");
315*0fca6ea1SDimitry Andric   // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
316*0fca6ea1SDimitry Andric   // and get the corresponding sandboxir Instruction that maps to it. This works
317*0fca6ea1SDimitry Andric   // even for SandboxIR Instructions that map to more than one LLVM Instruction.
318*0fca6ea1SDimitry Andric   auto *LLVMI = cast<llvm::Instruction>(Val);
319*0fca6ea1SDimitry Andric   assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
320*0fca6ea1SDimitry Andric   auto *NextLLVMI = LLVMI->getNextNode();
321*0fca6ea1SDimitry Andric   auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
322*0fca6ea1SDimitry Andric   if (NextI == nullptr)
323*0fca6ea1SDimitry Andric     return nullptr;
324*0fca6ea1SDimitry Andric   return NextI;
325*0fca6ea1SDimitry Andric }
326*0fca6ea1SDimitry Andric 
327*0fca6ea1SDimitry Andric Instruction *Instruction::getPrevNode() const {
328*0fca6ea1SDimitry Andric   assert(getParent() != nullptr && "Detached!");
329*0fca6ea1SDimitry Andric   auto It = getIterator();
330*0fca6ea1SDimitry Andric   if (It != getParent()->begin())
331*0fca6ea1SDimitry Andric     return std::prev(getIterator()).get();
332*0fca6ea1SDimitry Andric   return nullptr;
333*0fca6ea1SDimitry Andric }
334*0fca6ea1SDimitry Andric 
335*0fca6ea1SDimitry Andric void Instruction::removeFromParent() {
336*0fca6ea1SDimitry Andric   auto &Tracker = Ctx.getTracker();
337*0fca6ea1SDimitry Andric   if (Tracker.isTracking())
338*0fca6ea1SDimitry Andric     Tracker.track(std::make_unique<RemoveFromParent>(this, Tracker));
339*0fca6ea1SDimitry Andric 
340*0fca6ea1SDimitry Andric   // Detach all the LLVM IR instructions from their parent BB.
341*0fca6ea1SDimitry Andric   for (llvm::Instruction *I : getLLVMInstrs())
342*0fca6ea1SDimitry Andric     I->removeFromParent();
343*0fca6ea1SDimitry Andric }
344*0fca6ea1SDimitry Andric 
345*0fca6ea1SDimitry Andric void Instruction::eraseFromParent() {
346*0fca6ea1SDimitry Andric   assert(users().empty() && "Still connected to users, can't erase!");
347*0fca6ea1SDimitry Andric   std::unique_ptr<Value> Detached = Ctx.detach(this);
348*0fca6ea1SDimitry Andric   auto LLVMInstrs = getLLVMInstrs();
349*0fca6ea1SDimitry Andric 
350*0fca6ea1SDimitry Andric   auto &Tracker = Ctx.getTracker();
351*0fca6ea1SDimitry Andric   if (Tracker.isTracking()) {
352*0fca6ea1SDimitry Andric     Tracker.track(
353*0fca6ea1SDimitry Andric         std::make_unique<EraseFromParent>(std::move(Detached), Tracker));
354*0fca6ea1SDimitry Andric     // We don't actually delete the IR instruction, because then it would be
355*0fca6ea1SDimitry Andric     // impossible to bring it back from the dead at the same memory location.
356*0fca6ea1SDimitry Andric     // Instead we remove it from its BB and track its current location.
357*0fca6ea1SDimitry Andric     for (llvm::Instruction *I : LLVMInstrs)
358*0fca6ea1SDimitry Andric       I->removeFromParent();
359*0fca6ea1SDimitry Andric     // TODO: Multi-instructions need special treatment because some of the
360*0fca6ea1SDimitry Andric     // references are internal to the instruction.
361*0fca6ea1SDimitry Andric     for (llvm::Instruction *I : LLVMInstrs)
362*0fca6ea1SDimitry Andric       I->dropAllReferences();
363*0fca6ea1SDimitry Andric   } else {
364*0fca6ea1SDimitry Andric     // Erase in reverse to avoid erasing nstructions with attached uses.
365*0fca6ea1SDimitry Andric     for (llvm::Instruction *I : reverse(LLVMInstrs))
366*0fca6ea1SDimitry Andric       I->eraseFromParent();
367*0fca6ea1SDimitry Andric   }
368*0fca6ea1SDimitry Andric }
369*0fca6ea1SDimitry Andric 
370*0fca6ea1SDimitry Andric void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) {
371*0fca6ea1SDimitry Andric   if (std::next(getIterator()) == WhereIt)
372*0fca6ea1SDimitry Andric     // Destination is same as origin, nothing to do.
373*0fca6ea1SDimitry Andric     return;
374*0fca6ea1SDimitry Andric 
375*0fca6ea1SDimitry Andric   auto &Tracker = Ctx.getTracker();
376*0fca6ea1SDimitry Andric   if (Tracker.isTracking())
377*0fca6ea1SDimitry Andric     Tracker.track(std::make_unique<MoveInstr>(this, Tracker));
378*0fca6ea1SDimitry Andric 
379*0fca6ea1SDimitry Andric   auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
380*0fca6ea1SDimitry Andric   llvm::BasicBlock::iterator It;
381*0fca6ea1SDimitry Andric   if (WhereIt == BB.end()) {
382*0fca6ea1SDimitry Andric     It = LLVMBB->end();
383*0fca6ea1SDimitry Andric   } else {
384*0fca6ea1SDimitry Andric     Instruction *WhereI = &*WhereIt;
385*0fca6ea1SDimitry Andric     It = WhereI->getTopmostLLVMInstruction()->getIterator();
386*0fca6ea1SDimitry Andric   }
387*0fca6ea1SDimitry Andric   // TODO: Move this to the verifier of sandboxir::Instruction.
388*0fca6ea1SDimitry Andric   assert(is_sorted(getLLVMInstrs(),
389*0fca6ea1SDimitry Andric                    [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
390*0fca6ea1SDimitry Andric          "Expected program order!");
391*0fca6ea1SDimitry Andric   // Do the actual move in LLVM IR.
392*0fca6ea1SDimitry Andric   for (auto *I : getLLVMInstrs())
393*0fca6ea1SDimitry Andric     I->moveBefore(*LLVMBB, It);
394*0fca6ea1SDimitry Andric }
395*0fca6ea1SDimitry Andric 
396*0fca6ea1SDimitry Andric void Instruction::insertBefore(Instruction *BeforeI) {
397*0fca6ea1SDimitry Andric   llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
398*0fca6ea1SDimitry Andric   // TODO: Move this to the verifier of sandboxir::Instruction.
399*0fca6ea1SDimitry Andric   assert(is_sorted(getLLVMInstrs(),
400*0fca6ea1SDimitry Andric                    [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
401*0fca6ea1SDimitry Andric          "Expected program order!");
402*0fca6ea1SDimitry Andric   // Insert the LLVM IR Instructions in program order.
403*0fca6ea1SDimitry Andric   for (llvm::Instruction *I : getLLVMInstrs())
404*0fca6ea1SDimitry Andric     I->insertBefore(BeforeTopI);
405*0fca6ea1SDimitry Andric }
406*0fca6ea1SDimitry Andric 
407*0fca6ea1SDimitry Andric void Instruction::insertAfter(Instruction *AfterI) {
408*0fca6ea1SDimitry Andric   insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
409*0fca6ea1SDimitry Andric }
410*0fca6ea1SDimitry Andric 
411*0fca6ea1SDimitry Andric void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
412*0fca6ea1SDimitry Andric   llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
413*0fca6ea1SDimitry Andric   llvm::Instruction *LLVMBeforeI;
414*0fca6ea1SDimitry Andric   llvm::BasicBlock::iterator LLVMBeforeIt;
415*0fca6ea1SDimitry Andric   if (WhereIt != BB->end()) {
416*0fca6ea1SDimitry Andric     Instruction *BeforeI = &*WhereIt;
417*0fca6ea1SDimitry Andric     LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
418*0fca6ea1SDimitry Andric     LLVMBeforeIt = LLVMBeforeI->getIterator();
419*0fca6ea1SDimitry Andric   } else {
420*0fca6ea1SDimitry Andric     LLVMBeforeI = nullptr;
421*0fca6ea1SDimitry Andric     LLVMBeforeIt = LLVMBB->end();
422*0fca6ea1SDimitry Andric   }
423*0fca6ea1SDimitry Andric   // Insert the LLVM IR Instructions in program order.
424*0fca6ea1SDimitry Andric   for (llvm::Instruction *I : getLLVMInstrs())
425*0fca6ea1SDimitry Andric     I->insertInto(LLVMBB, LLVMBeforeIt);
426*0fca6ea1SDimitry Andric }
427*0fca6ea1SDimitry Andric 
428*0fca6ea1SDimitry Andric BasicBlock *Instruction::getParent() const {
429*0fca6ea1SDimitry Andric   // Get the LLVM IR Instruction that this maps to, get its parent, and get the
430*0fca6ea1SDimitry Andric   // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
431*0fca6ea1SDimitry Andric   auto *BB = cast<llvm::Instruction>(Val)->getParent();
432*0fca6ea1SDimitry Andric   if (BB == nullptr)
433*0fca6ea1SDimitry Andric     return nullptr;
434*0fca6ea1SDimitry Andric   return cast<BasicBlock>(Ctx.getValue(BB));
435*0fca6ea1SDimitry Andric }
436*0fca6ea1SDimitry Andric 
437*0fca6ea1SDimitry Andric bool Instruction::classof(const sandboxir::Value *From) {
438*0fca6ea1SDimitry Andric   switch (From->getSubclassID()) {
439*0fca6ea1SDimitry Andric #define DEF_INSTR(ID, OPC, CLASS)                                              \
440*0fca6ea1SDimitry Andric   case ClassID::ID:                                                            \
441*0fca6ea1SDimitry Andric     return true;
442*0fca6ea1SDimitry Andric #include "llvm/SandboxIR/SandboxIRValues.def"
443*0fca6ea1SDimitry Andric   default:
444*0fca6ea1SDimitry Andric     return false;
445*0fca6ea1SDimitry Andric   }
446*0fca6ea1SDimitry Andric }
447*0fca6ea1SDimitry Andric 
448*0fca6ea1SDimitry Andric #ifndef NDEBUG
449*0fca6ea1SDimitry Andric void Instruction::dump(raw_ostream &OS) const {
450*0fca6ea1SDimitry Andric   OS << "Unimplemented! Please override dump().";
451*0fca6ea1SDimitry Andric }
452*0fca6ea1SDimitry Andric void Instruction::dump() const {
453*0fca6ea1SDimitry Andric   dump(dbgs());
454*0fca6ea1SDimitry Andric   dbgs() << "\n";
455*0fca6ea1SDimitry Andric }
456*0fca6ea1SDimitry Andric #endif // NDEBUG
457*0fca6ea1SDimitry Andric 
458*0fca6ea1SDimitry Andric Value *SelectInst::createCommon(Value *Cond, Value *True, Value *False,
459*0fca6ea1SDimitry Andric                                 const Twine &Name, IRBuilder<> &Builder,
460*0fca6ea1SDimitry Andric                                 Context &Ctx) {
461*0fca6ea1SDimitry Andric   llvm::Value *NewV =
462*0fca6ea1SDimitry Andric       Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
463*0fca6ea1SDimitry Andric   if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
464*0fca6ea1SDimitry Andric     return Ctx.createSelectInst(NewSI);
465*0fca6ea1SDimitry Andric   assert(isa<llvm::Constant>(NewV) && "Expected constant");
466*0fca6ea1SDimitry Andric   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
467*0fca6ea1SDimitry Andric }
468*0fca6ea1SDimitry Andric 
469*0fca6ea1SDimitry Andric Value *SelectInst::create(Value *Cond, Value *True, Value *False,
470*0fca6ea1SDimitry Andric                           Instruction *InsertBefore, Context &Ctx,
471*0fca6ea1SDimitry Andric                           const Twine &Name) {
472*0fca6ea1SDimitry Andric   llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
473*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
474*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(BeforeIR);
475*0fca6ea1SDimitry Andric   return createCommon(Cond, True, False, Name, Builder, Ctx);
476*0fca6ea1SDimitry Andric }
477*0fca6ea1SDimitry Andric 
478*0fca6ea1SDimitry Andric Value *SelectInst::create(Value *Cond, Value *True, Value *False,
479*0fca6ea1SDimitry Andric                           BasicBlock *InsertAtEnd, Context &Ctx,
480*0fca6ea1SDimitry Andric                           const Twine &Name) {
481*0fca6ea1SDimitry Andric   auto *IRInsertAtEnd = cast<llvm::BasicBlock>(InsertAtEnd->Val);
482*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
483*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(IRInsertAtEnd);
484*0fca6ea1SDimitry Andric   return createCommon(Cond, True, False, Name, Builder, Ctx);
485*0fca6ea1SDimitry Andric }
486*0fca6ea1SDimitry Andric 
487*0fca6ea1SDimitry Andric bool SelectInst::classof(const Value *From) {
488*0fca6ea1SDimitry Andric   return From->getSubclassID() == ClassID::Select;
489*0fca6ea1SDimitry Andric }
490*0fca6ea1SDimitry Andric 
491*0fca6ea1SDimitry Andric #ifndef NDEBUG
492*0fca6ea1SDimitry Andric void SelectInst::dump(raw_ostream &OS) const {
493*0fca6ea1SDimitry Andric   dumpCommonPrefix(OS);
494*0fca6ea1SDimitry Andric   dumpCommonSuffix(OS);
495*0fca6ea1SDimitry Andric }
496*0fca6ea1SDimitry Andric 
497*0fca6ea1SDimitry Andric void SelectInst::dump() const {
498*0fca6ea1SDimitry Andric   dump(dbgs());
499*0fca6ea1SDimitry Andric   dbgs() << "\n";
500*0fca6ea1SDimitry Andric }
501*0fca6ea1SDimitry Andric #endif // NDEBUG
502*0fca6ea1SDimitry Andric 
503*0fca6ea1SDimitry Andric LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align,
504*0fca6ea1SDimitry Andric                            Instruction *InsertBefore, Context &Ctx,
505*0fca6ea1SDimitry Andric                            const Twine &Name) {
506*0fca6ea1SDimitry Andric   llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
507*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
508*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(BeforeIR);
509*0fca6ea1SDimitry Andric   auto *NewLI = Builder.CreateAlignedLoad(Ty, Ptr->Val, Align,
510*0fca6ea1SDimitry Andric                                           /*isVolatile=*/false, Name);
511*0fca6ea1SDimitry Andric   auto *NewSBI = Ctx.createLoadInst(NewLI);
512*0fca6ea1SDimitry Andric   return NewSBI;
513*0fca6ea1SDimitry Andric }
514*0fca6ea1SDimitry Andric 
515*0fca6ea1SDimitry Andric LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align,
516*0fca6ea1SDimitry Andric                            BasicBlock *InsertAtEnd, Context &Ctx,
517*0fca6ea1SDimitry Andric                            const Twine &Name) {
518*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
519*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
520*0fca6ea1SDimitry Andric   auto *NewLI = Builder.CreateAlignedLoad(Ty, Ptr->Val, Align,
521*0fca6ea1SDimitry Andric                                           /*isVolatile=*/false, Name);
522*0fca6ea1SDimitry Andric   auto *NewSBI = Ctx.createLoadInst(NewLI);
523*0fca6ea1SDimitry Andric   return NewSBI;
524*0fca6ea1SDimitry Andric }
525*0fca6ea1SDimitry Andric 
526*0fca6ea1SDimitry Andric bool LoadInst::classof(const Value *From) {
527*0fca6ea1SDimitry Andric   return From->getSubclassID() == ClassID::Load;
528*0fca6ea1SDimitry Andric }
529*0fca6ea1SDimitry Andric 
530*0fca6ea1SDimitry Andric Value *LoadInst::getPointerOperand() const {
531*0fca6ea1SDimitry Andric   return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());
532*0fca6ea1SDimitry Andric }
533*0fca6ea1SDimitry Andric 
534*0fca6ea1SDimitry Andric #ifndef NDEBUG
535*0fca6ea1SDimitry Andric void LoadInst::dump(raw_ostream &OS) const {
536*0fca6ea1SDimitry Andric   dumpCommonPrefix(OS);
537*0fca6ea1SDimitry Andric   dumpCommonSuffix(OS);
538*0fca6ea1SDimitry Andric }
539*0fca6ea1SDimitry Andric 
540*0fca6ea1SDimitry Andric void LoadInst::dump() const {
541*0fca6ea1SDimitry Andric   dump(dbgs());
542*0fca6ea1SDimitry Andric   dbgs() << "\n";
543*0fca6ea1SDimitry Andric }
544*0fca6ea1SDimitry Andric #endif // NDEBUG
545*0fca6ea1SDimitry Andric StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
546*0fca6ea1SDimitry Andric                              Instruction *InsertBefore, Context &Ctx) {
547*0fca6ea1SDimitry Andric   llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
548*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
549*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(BeforeIR);
550*0fca6ea1SDimitry Andric   auto *NewSI =
551*0fca6ea1SDimitry Andric       Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false);
552*0fca6ea1SDimitry Andric   auto *NewSBI = Ctx.createStoreInst(NewSI);
553*0fca6ea1SDimitry Andric   return NewSBI;
554*0fca6ea1SDimitry Andric }
555*0fca6ea1SDimitry Andric StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
556*0fca6ea1SDimitry Andric                              BasicBlock *InsertAtEnd, Context &Ctx) {
557*0fca6ea1SDimitry Andric   auto *InsertAtEndIR = cast<llvm::BasicBlock>(InsertAtEnd->Val);
558*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
559*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(InsertAtEndIR);
560*0fca6ea1SDimitry Andric   auto *NewSI =
561*0fca6ea1SDimitry Andric       Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, /*isVolatile=*/false);
562*0fca6ea1SDimitry Andric   auto *NewSBI = Ctx.createStoreInst(NewSI);
563*0fca6ea1SDimitry Andric   return NewSBI;
564*0fca6ea1SDimitry Andric }
565*0fca6ea1SDimitry Andric 
566*0fca6ea1SDimitry Andric bool StoreInst::classof(const Value *From) {
567*0fca6ea1SDimitry Andric   return From->getSubclassID() == ClassID::Store;
568*0fca6ea1SDimitry Andric }
569*0fca6ea1SDimitry Andric 
570*0fca6ea1SDimitry Andric Value *StoreInst::getValueOperand() const {
571*0fca6ea1SDimitry Andric   return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
572*0fca6ea1SDimitry Andric }
573*0fca6ea1SDimitry Andric 
574*0fca6ea1SDimitry Andric Value *StoreInst::getPointerOperand() const {
575*0fca6ea1SDimitry Andric   return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
576*0fca6ea1SDimitry Andric }
577*0fca6ea1SDimitry Andric 
578*0fca6ea1SDimitry Andric #ifndef NDEBUG
579*0fca6ea1SDimitry Andric void StoreInst::dump(raw_ostream &OS) const {
580*0fca6ea1SDimitry Andric   dumpCommonPrefix(OS);
581*0fca6ea1SDimitry Andric   dumpCommonSuffix(OS);
582*0fca6ea1SDimitry Andric }
583*0fca6ea1SDimitry Andric 
584*0fca6ea1SDimitry Andric void StoreInst::dump() const {
585*0fca6ea1SDimitry Andric   dump(dbgs());
586*0fca6ea1SDimitry Andric   dbgs() << "\n";
587*0fca6ea1SDimitry Andric }
588*0fca6ea1SDimitry Andric #endif // NDEBUG
589*0fca6ea1SDimitry Andric 
590*0fca6ea1SDimitry Andric ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
591*0fca6ea1SDimitry Andric                                      Context &Ctx) {
592*0fca6ea1SDimitry Andric   llvm::ReturnInst *NewRI;
593*0fca6ea1SDimitry Andric   if (RetVal != nullptr)
594*0fca6ea1SDimitry Andric     NewRI = Builder.CreateRet(RetVal->Val);
595*0fca6ea1SDimitry Andric   else
596*0fca6ea1SDimitry Andric     NewRI = Builder.CreateRetVoid();
597*0fca6ea1SDimitry Andric   return Ctx.createReturnInst(NewRI);
598*0fca6ea1SDimitry Andric }
599*0fca6ea1SDimitry Andric 
600*0fca6ea1SDimitry Andric ReturnInst *ReturnInst::create(Value *RetVal, Instruction *InsertBefore,
601*0fca6ea1SDimitry Andric                                Context &Ctx) {
602*0fca6ea1SDimitry Andric   llvm::Instruction *BeforeIR = InsertBefore->getTopmostLLVMInstruction();
603*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
604*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(BeforeIR);
605*0fca6ea1SDimitry Andric   return createCommon(RetVal, Builder, Ctx);
606*0fca6ea1SDimitry Andric }
607*0fca6ea1SDimitry Andric 
608*0fca6ea1SDimitry Andric ReturnInst *ReturnInst::create(Value *RetVal, BasicBlock *InsertAtEnd,
609*0fca6ea1SDimitry Andric                                Context &Ctx) {
610*0fca6ea1SDimitry Andric   auto &Builder = Ctx.getLLVMIRBuilder();
611*0fca6ea1SDimitry Andric   Builder.SetInsertPoint(cast<llvm::BasicBlock>(InsertAtEnd->Val));
612*0fca6ea1SDimitry Andric   return createCommon(RetVal, Builder, Ctx);
613*0fca6ea1SDimitry Andric }
614*0fca6ea1SDimitry Andric 
615*0fca6ea1SDimitry Andric Value *ReturnInst::getReturnValue() const {
616*0fca6ea1SDimitry Andric   auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
617*0fca6ea1SDimitry Andric   return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
618*0fca6ea1SDimitry Andric }
619*0fca6ea1SDimitry Andric 
620*0fca6ea1SDimitry Andric #ifndef NDEBUG
621*0fca6ea1SDimitry Andric void ReturnInst::dump(raw_ostream &OS) const {
622*0fca6ea1SDimitry Andric   dumpCommonPrefix(OS);
623*0fca6ea1SDimitry Andric   dumpCommonSuffix(OS);
624*0fca6ea1SDimitry Andric }
625*0fca6ea1SDimitry Andric 
626*0fca6ea1SDimitry Andric void ReturnInst::dump() const {
627*0fca6ea1SDimitry Andric   dump(dbgs());
628*0fca6ea1SDimitry Andric   dbgs() << "\n";
629*0fca6ea1SDimitry Andric }
630*0fca6ea1SDimitry Andric 
631*0fca6ea1SDimitry Andric void OpaqueInst::dump(raw_ostream &OS) const {
632*0fca6ea1SDimitry Andric   dumpCommonPrefix(OS);
633*0fca6ea1SDimitry Andric   dumpCommonSuffix(OS);
634*0fca6ea1SDimitry Andric }
635*0fca6ea1SDimitry Andric 
636*0fca6ea1SDimitry Andric void OpaqueInst::dump() const {
637*0fca6ea1SDimitry Andric   dump(dbgs());
638*0fca6ea1SDimitry Andric   dbgs() << "\n";
639*0fca6ea1SDimitry Andric }
640*0fca6ea1SDimitry Andric #endif // NDEBUG
641*0fca6ea1SDimitry Andric 
642*0fca6ea1SDimitry Andric Constant *Constant::createInt(Type *Ty, uint64_t V, Context &Ctx,
643*0fca6ea1SDimitry Andric                               bool IsSigned) {
644*0fca6ea1SDimitry Andric   llvm::Constant *LLVMC = llvm::ConstantInt::get(Ty, V, IsSigned);
645*0fca6ea1SDimitry Andric   return Ctx.getOrCreateConstant(LLVMC);
646*0fca6ea1SDimitry Andric }
647*0fca6ea1SDimitry Andric 
648*0fca6ea1SDimitry Andric #ifndef NDEBUG
649*0fca6ea1SDimitry Andric void Constant::dump(raw_ostream &OS) const {
650*0fca6ea1SDimitry Andric   dumpCommonPrefix(OS);
651*0fca6ea1SDimitry Andric   dumpCommonSuffix(OS);
652*0fca6ea1SDimitry Andric }
653*0fca6ea1SDimitry Andric 
654*0fca6ea1SDimitry Andric void Constant::dump() const {
655*0fca6ea1SDimitry Andric   dump(dbgs());
656*0fca6ea1SDimitry Andric   dbgs() << "\n";
657*0fca6ea1SDimitry Andric }
658*0fca6ea1SDimitry Andric 
659*0fca6ea1SDimitry Andric void Function::dumpNameAndArgs(raw_ostream &OS) const {
660*0fca6ea1SDimitry Andric   auto *F = cast<llvm::Function>(Val);
661*0fca6ea1SDimitry Andric   OS << *F->getReturnType() << " @" << F->getName() << "(";
662*0fca6ea1SDimitry Andric   interleave(
663*0fca6ea1SDimitry Andric       F->args(),
664*0fca6ea1SDimitry Andric       [this, &OS](const llvm::Argument &LLVMArg) {
665*0fca6ea1SDimitry Andric         auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
666*0fca6ea1SDimitry Andric         if (SBArg == nullptr)
667*0fca6ea1SDimitry Andric           OS << "NULL";
668*0fca6ea1SDimitry Andric         else
669*0fca6ea1SDimitry Andric           SBArg->printAsOperand(OS);
670*0fca6ea1SDimitry Andric       },
671*0fca6ea1SDimitry Andric       [&] { OS << ", "; });
672*0fca6ea1SDimitry Andric   OS << ")";
673*0fca6ea1SDimitry Andric }
674*0fca6ea1SDimitry Andric void Function::dump(raw_ostream &OS) const {
675*0fca6ea1SDimitry Andric   dumpNameAndArgs(OS);
676*0fca6ea1SDimitry Andric   OS << " {\n";
677*0fca6ea1SDimitry Andric   auto *LLVMF = cast<llvm::Function>(Val);
678*0fca6ea1SDimitry Andric   interleave(
679*0fca6ea1SDimitry Andric       *LLVMF,
680*0fca6ea1SDimitry Andric       [this, &OS](const llvm::BasicBlock &LLVMBB) {
681*0fca6ea1SDimitry Andric         auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
682*0fca6ea1SDimitry Andric         if (BB == nullptr)
683*0fca6ea1SDimitry Andric           OS << "NULL";
684*0fca6ea1SDimitry Andric         else
685*0fca6ea1SDimitry Andric           OS << *BB;
686*0fca6ea1SDimitry Andric       },
687*0fca6ea1SDimitry Andric       [&OS] { OS << "\n"; });
688*0fca6ea1SDimitry Andric   OS << "}\n";
689*0fca6ea1SDimitry Andric }
690*0fca6ea1SDimitry Andric void Function::dump() const {
691*0fca6ea1SDimitry Andric   dump(dbgs());
692*0fca6ea1SDimitry Andric   dbgs() << "\n";
693*0fca6ea1SDimitry Andric }
694*0fca6ea1SDimitry Andric #endif // NDEBUG
695*0fca6ea1SDimitry Andric 
696*0fca6ea1SDimitry Andric BasicBlock::iterator::pointer
697*0fca6ea1SDimitry Andric BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
698*0fca6ea1SDimitry Andric   return cast_or_null<Instruction>(Ctx->getValue(&*It));
699*0fca6ea1SDimitry Andric }
700*0fca6ea1SDimitry Andric 
701*0fca6ea1SDimitry Andric std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
702*0fca6ea1SDimitry Andric   std::unique_ptr<Value> Erased;
703*0fca6ea1SDimitry Andric   auto It = LLVMValueToValueMap.find(V);
704*0fca6ea1SDimitry Andric   if (It != LLVMValueToValueMap.end()) {
705*0fca6ea1SDimitry Andric     auto *Val = It->second.release();
706*0fca6ea1SDimitry Andric     Erased = std::unique_ptr<Value>(Val);
707*0fca6ea1SDimitry Andric     LLVMValueToValueMap.erase(It);
708*0fca6ea1SDimitry Andric   }
709*0fca6ea1SDimitry Andric   return Erased;
710*0fca6ea1SDimitry Andric }
711*0fca6ea1SDimitry Andric 
712*0fca6ea1SDimitry Andric std::unique_ptr<Value> Context::detach(Value *V) {
713*0fca6ea1SDimitry Andric   assert(V->getSubclassID() != Value::ClassID::Constant &&
714*0fca6ea1SDimitry Andric          "Can't detach a constant!");
715*0fca6ea1SDimitry Andric   assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
716*0fca6ea1SDimitry Andric   return detachLLVMValue(V->Val);
717*0fca6ea1SDimitry Andric }
718*0fca6ea1SDimitry Andric 
719*0fca6ea1SDimitry Andric Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
720*0fca6ea1SDimitry Andric   assert(VPtr->getSubclassID() != Value::ClassID::User &&
721*0fca6ea1SDimitry Andric          "Can't register a user!");
722*0fca6ea1SDimitry Andric   Value *V = VPtr.get();
723*0fca6ea1SDimitry Andric   [[maybe_unused]] auto Pair =
724*0fca6ea1SDimitry Andric       LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
725*0fca6ea1SDimitry Andric   assert(Pair.second && "Already exists!");
726*0fca6ea1SDimitry Andric   return V;
727*0fca6ea1SDimitry Andric }
728*0fca6ea1SDimitry Andric 
729*0fca6ea1SDimitry Andric Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
730*0fca6ea1SDimitry Andric   auto Pair = LLVMValueToValueMap.insert({LLVMV, nullptr});
731*0fca6ea1SDimitry Andric   auto It = Pair.first;
732*0fca6ea1SDimitry Andric   if (!Pair.second)
733*0fca6ea1SDimitry Andric     return It->second.get();
734*0fca6ea1SDimitry Andric 
735*0fca6ea1SDimitry Andric   if (auto *C = dyn_cast<llvm::Constant>(LLVMV)) {
736*0fca6ea1SDimitry Andric     It->second = std::unique_ptr<Constant>(new Constant(C, *this));
737*0fca6ea1SDimitry Andric     auto *NewC = It->second.get();
738*0fca6ea1SDimitry Andric     for (llvm::Value *COp : C->operands())
739*0fca6ea1SDimitry Andric       getOrCreateValueInternal(COp, C);
740*0fca6ea1SDimitry Andric     return NewC;
741*0fca6ea1SDimitry Andric   }
742*0fca6ea1SDimitry Andric   if (auto *Arg = dyn_cast<llvm::Argument>(LLVMV)) {
743*0fca6ea1SDimitry Andric     It->second = std::unique_ptr<Argument>(new Argument(Arg, *this));
744*0fca6ea1SDimitry Andric     return It->second.get();
745*0fca6ea1SDimitry Andric   }
746*0fca6ea1SDimitry Andric   if (auto *BB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
747*0fca6ea1SDimitry Andric     assert(isa<BlockAddress>(U) &&
748*0fca6ea1SDimitry Andric            "This won't create a SBBB, don't call this function directly!");
749*0fca6ea1SDimitry Andric     if (auto *SBBB = getValue(BB))
750*0fca6ea1SDimitry Andric       return SBBB;
751*0fca6ea1SDimitry Andric     return nullptr;
752*0fca6ea1SDimitry Andric   }
753*0fca6ea1SDimitry Andric   assert(isa<llvm::Instruction>(LLVMV) && "Expected Instruction");
754*0fca6ea1SDimitry Andric 
755*0fca6ea1SDimitry Andric   switch (cast<llvm::Instruction>(LLVMV)->getOpcode()) {
756*0fca6ea1SDimitry Andric   case llvm::Instruction::Select: {
757*0fca6ea1SDimitry Andric     auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
758*0fca6ea1SDimitry Andric     It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
759*0fca6ea1SDimitry Andric     return It->second.get();
760*0fca6ea1SDimitry Andric   }
761*0fca6ea1SDimitry Andric   case llvm::Instruction::Load: {
762*0fca6ea1SDimitry Andric     auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
763*0fca6ea1SDimitry Andric     It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
764*0fca6ea1SDimitry Andric     return It->second.get();
765*0fca6ea1SDimitry Andric   }
766*0fca6ea1SDimitry Andric   case llvm::Instruction::Store: {
767*0fca6ea1SDimitry Andric     auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
768*0fca6ea1SDimitry Andric     It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
769*0fca6ea1SDimitry Andric     return It->second.get();
770*0fca6ea1SDimitry Andric   }
771*0fca6ea1SDimitry Andric   case llvm::Instruction::Ret: {
772*0fca6ea1SDimitry Andric     auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
773*0fca6ea1SDimitry Andric     It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
774*0fca6ea1SDimitry Andric     return It->second.get();
775*0fca6ea1SDimitry Andric   }
776*0fca6ea1SDimitry Andric   default:
777*0fca6ea1SDimitry Andric     break;
778*0fca6ea1SDimitry Andric   }
779*0fca6ea1SDimitry Andric 
780*0fca6ea1SDimitry Andric   It->second = std::unique_ptr<OpaqueInst>(
781*0fca6ea1SDimitry Andric       new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
782*0fca6ea1SDimitry Andric   return It->second.get();
783*0fca6ea1SDimitry Andric }
784*0fca6ea1SDimitry Andric 
785*0fca6ea1SDimitry Andric BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
786*0fca6ea1SDimitry Andric   assert(getValue(LLVMBB) == nullptr && "Already exists!");
787*0fca6ea1SDimitry Andric   auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
788*0fca6ea1SDimitry Andric   auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
789*0fca6ea1SDimitry Andric   // Create SandboxIR for BB's body.
790*0fca6ea1SDimitry Andric   BB->buildBasicBlockFromLLVMIR(LLVMBB);
791*0fca6ea1SDimitry Andric   return BB;
792*0fca6ea1SDimitry Andric }
793*0fca6ea1SDimitry Andric 
794*0fca6ea1SDimitry Andric SelectInst *Context::createSelectInst(llvm::SelectInst *SI) {
795*0fca6ea1SDimitry Andric   auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
796*0fca6ea1SDimitry Andric   return cast<SelectInst>(registerValue(std::move(NewPtr)));
797*0fca6ea1SDimitry Andric }
798*0fca6ea1SDimitry Andric 
799*0fca6ea1SDimitry Andric LoadInst *Context::createLoadInst(llvm::LoadInst *LI) {
800*0fca6ea1SDimitry Andric   auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
801*0fca6ea1SDimitry Andric   return cast<LoadInst>(registerValue(std::move(NewPtr)));
802*0fca6ea1SDimitry Andric }
803*0fca6ea1SDimitry Andric 
804*0fca6ea1SDimitry Andric StoreInst *Context::createStoreInst(llvm::StoreInst *SI) {
805*0fca6ea1SDimitry Andric   auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
806*0fca6ea1SDimitry Andric   return cast<StoreInst>(registerValue(std::move(NewPtr)));
807*0fca6ea1SDimitry Andric }
808*0fca6ea1SDimitry Andric 
809*0fca6ea1SDimitry Andric ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) {
810*0fca6ea1SDimitry Andric   auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
811*0fca6ea1SDimitry Andric   return cast<ReturnInst>(registerValue(std::move(NewPtr)));
812*0fca6ea1SDimitry Andric }
813*0fca6ea1SDimitry Andric 
814*0fca6ea1SDimitry Andric Value *Context::getValue(llvm::Value *V) const {
815*0fca6ea1SDimitry Andric   auto It = LLVMValueToValueMap.find(V);
816*0fca6ea1SDimitry Andric   if (It != LLVMValueToValueMap.end())
817*0fca6ea1SDimitry Andric     return It->second.get();
818*0fca6ea1SDimitry Andric   return nullptr;
819*0fca6ea1SDimitry Andric }
820*0fca6ea1SDimitry Andric 
821*0fca6ea1SDimitry Andric Function *Context::createFunction(llvm::Function *F) {
822*0fca6ea1SDimitry Andric   assert(getValue(F) == nullptr && "Already exists!");
823*0fca6ea1SDimitry Andric   auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
824*0fca6ea1SDimitry Andric   // Create arguments.
825*0fca6ea1SDimitry Andric   for (auto &Arg : F->args())
826*0fca6ea1SDimitry Andric     getOrCreateArgument(&Arg);
827*0fca6ea1SDimitry Andric   // Create BBs.
828*0fca6ea1SDimitry Andric   for (auto &BB : *F)
829*0fca6ea1SDimitry Andric     createBasicBlock(&BB);
830*0fca6ea1SDimitry Andric   auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
831*0fca6ea1SDimitry Andric   return SBF;
832*0fca6ea1SDimitry Andric }
833*0fca6ea1SDimitry Andric 
834*0fca6ea1SDimitry Andric Function *BasicBlock::getParent() const {
835*0fca6ea1SDimitry Andric   auto *BB = cast<llvm::BasicBlock>(Val);
836*0fca6ea1SDimitry Andric   auto *F = BB->getParent();
837*0fca6ea1SDimitry Andric   if (F == nullptr)
838*0fca6ea1SDimitry Andric     // Detached
839*0fca6ea1SDimitry Andric     return nullptr;
840*0fca6ea1SDimitry Andric   return cast_or_null<Function>(Ctx.getValue(F));
841*0fca6ea1SDimitry Andric }
842*0fca6ea1SDimitry Andric 
843*0fca6ea1SDimitry Andric void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
844*0fca6ea1SDimitry Andric   for (llvm::Instruction &IRef : reverse(*LLVMBB)) {
845*0fca6ea1SDimitry Andric     llvm::Instruction *I = &IRef;
846*0fca6ea1SDimitry Andric     Ctx.getOrCreateValue(I);
847*0fca6ea1SDimitry Andric     for (auto [OpIdx, Op] : enumerate(I->operands())) {
848*0fca6ea1SDimitry Andric       // Skip instruction's label operands
849*0fca6ea1SDimitry Andric       if (isa<llvm::BasicBlock>(Op))
850*0fca6ea1SDimitry Andric         continue;
851*0fca6ea1SDimitry Andric       // Skip metadata
852*0fca6ea1SDimitry Andric       if (isa<llvm::MetadataAsValue>(Op))
853*0fca6ea1SDimitry Andric         continue;
854*0fca6ea1SDimitry Andric       // Skip asm
855*0fca6ea1SDimitry Andric       if (isa<llvm::InlineAsm>(Op))
856*0fca6ea1SDimitry Andric         continue;
857*0fca6ea1SDimitry Andric       Ctx.getOrCreateValue(Op);
858*0fca6ea1SDimitry Andric     }
859*0fca6ea1SDimitry Andric   }
860*0fca6ea1SDimitry Andric #if !defined(NDEBUG) && defined(SBVEC_EXPENSIVE_CHECKS)
861*0fca6ea1SDimitry Andric   verify();
862*0fca6ea1SDimitry Andric #endif
863*0fca6ea1SDimitry Andric }
864*0fca6ea1SDimitry Andric 
865*0fca6ea1SDimitry Andric BasicBlock::iterator BasicBlock::begin() const {
866*0fca6ea1SDimitry Andric   llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
867*0fca6ea1SDimitry Andric   llvm::BasicBlock::iterator It = BB->begin();
868*0fca6ea1SDimitry Andric   if (!BB->empty()) {
869*0fca6ea1SDimitry Andric     auto *V = Ctx.getValue(&*BB->begin());
870*0fca6ea1SDimitry Andric     assert(V != nullptr && "No SandboxIR for BB->begin()!");
871*0fca6ea1SDimitry Andric     auto *I = cast<Instruction>(V);
872*0fca6ea1SDimitry Andric     unsigned Num = I->getNumOfIRInstrs();
873*0fca6ea1SDimitry Andric     assert(Num >= 1u && "Bad getNumOfIRInstrs()");
874*0fca6ea1SDimitry Andric     It = std::next(It, Num - 1);
875*0fca6ea1SDimitry Andric   }
876*0fca6ea1SDimitry Andric   return iterator(BB, It, &Ctx);
877*0fca6ea1SDimitry Andric }
878*0fca6ea1SDimitry Andric 
879*0fca6ea1SDimitry Andric Instruction *BasicBlock::getTerminator() const {
880*0fca6ea1SDimitry Andric   auto *TerminatorV =
881*0fca6ea1SDimitry Andric       Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
882*0fca6ea1SDimitry Andric   return cast_or_null<Instruction>(TerminatorV);
883*0fca6ea1SDimitry Andric }
884*0fca6ea1SDimitry Andric 
885*0fca6ea1SDimitry Andric Instruction &BasicBlock::front() const {
886*0fca6ea1SDimitry Andric   auto *BB = cast<llvm::BasicBlock>(Val);
887*0fca6ea1SDimitry Andric   assert(!BB->empty() && "Empty block!");
888*0fca6ea1SDimitry Andric   auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
889*0fca6ea1SDimitry Andric   assert(SBI != nullptr && "Expected Instr!");
890*0fca6ea1SDimitry Andric   return *SBI;
891*0fca6ea1SDimitry Andric }
892*0fca6ea1SDimitry Andric 
893*0fca6ea1SDimitry Andric Instruction &BasicBlock::back() const {
894*0fca6ea1SDimitry Andric   auto *BB = cast<llvm::BasicBlock>(Val);
895*0fca6ea1SDimitry Andric   assert(!BB->empty() && "Empty block!");
896*0fca6ea1SDimitry Andric   auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
897*0fca6ea1SDimitry Andric   assert(SBI != nullptr && "Expected Instr!");
898*0fca6ea1SDimitry Andric   return *SBI;
899*0fca6ea1SDimitry Andric }
900*0fca6ea1SDimitry Andric 
901*0fca6ea1SDimitry Andric #ifndef NDEBUG
902*0fca6ea1SDimitry Andric void BasicBlock::dump(raw_ostream &OS) const {
903*0fca6ea1SDimitry Andric   llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
904*0fca6ea1SDimitry Andric   const auto &Name = BB->getName();
905*0fca6ea1SDimitry Andric   OS << Name;
906*0fca6ea1SDimitry Andric   if (!Name.empty())
907*0fca6ea1SDimitry Andric     OS << ":\n";
908*0fca6ea1SDimitry Andric   // If there are Instructions in the BB that are not mapped to SandboxIR, then
909*0fca6ea1SDimitry Andric   // use a crash-proof dump.
910*0fca6ea1SDimitry Andric   if (any_of(*BB, [this](llvm::Instruction &I) {
911*0fca6ea1SDimitry Andric         return Ctx.getValue(&I) == nullptr;
912*0fca6ea1SDimitry Andric       })) {
913*0fca6ea1SDimitry Andric     OS << "<Crash-proof mode!>\n";
914*0fca6ea1SDimitry Andric     DenseSet<Instruction *> Visited;
915*0fca6ea1SDimitry Andric     for (llvm::Instruction &IRef : *BB) {
916*0fca6ea1SDimitry Andric       Value *SBV = Ctx.getValue(&IRef);
917*0fca6ea1SDimitry Andric       if (SBV == nullptr)
918*0fca6ea1SDimitry Andric         OS << IRef << " *** No SandboxIR ***\n";
919*0fca6ea1SDimitry Andric       else {
920*0fca6ea1SDimitry Andric         auto *SBI = dyn_cast<Instruction>(SBV);
921*0fca6ea1SDimitry Andric         if (SBI == nullptr) {
922*0fca6ea1SDimitry Andric           OS << IRef << " *** Not a SBInstruction!!! ***\n";
923*0fca6ea1SDimitry Andric         } else {
924*0fca6ea1SDimitry Andric           if (Visited.insert(SBI).second)
925*0fca6ea1SDimitry Andric             OS << *SBI << "\n";
926*0fca6ea1SDimitry Andric         }
927*0fca6ea1SDimitry Andric       }
928*0fca6ea1SDimitry Andric     }
929*0fca6ea1SDimitry Andric   } else {
930*0fca6ea1SDimitry Andric     for (auto &SBI : *this) {
931*0fca6ea1SDimitry Andric       SBI.dump(OS);
932*0fca6ea1SDimitry Andric       OS << "\n";
933*0fca6ea1SDimitry Andric     }
934*0fca6ea1SDimitry Andric   }
935*0fca6ea1SDimitry Andric }
936*0fca6ea1SDimitry Andric void BasicBlock::dump() const {
937*0fca6ea1SDimitry Andric   dump(dbgs());
938*0fca6ea1SDimitry Andric   dbgs() << "\n";
939*0fca6ea1SDimitry Andric }
940*0fca6ea1SDimitry Andric #endif // NDEBUG
941