xref: /llvm-project/llvm/lib/SandboxIR/Instruction.cpp (revision 749443a307e8e47a25a5552cbeb27f69845e6ce8)
1eba106d4Svporpo //===- Instruction.cpp - The Instructions of Sandbox IR -------------------===//
2eba106d4Svporpo //
3eba106d4Svporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4eba106d4Svporpo // See https://llvm.org/LICENSE.txt for license information.
5eba106d4Svporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6eba106d4Svporpo //
7eba106d4Svporpo //===----------------------------------------------------------------------===//
8eba106d4Svporpo 
9eba106d4Svporpo #include "llvm/SandboxIR/Instruction.h"
10e22b07e7Svporpo #include "llvm/SandboxIR/Function.h"
11eba106d4Svporpo 
12eba106d4Svporpo namespace llvm::sandboxir {
13eba106d4Svporpo 
14eba106d4Svporpo const char *Instruction::getOpcodeName(Opcode Opc) {
15eba106d4Svporpo   switch (Opc) {
16eba106d4Svporpo #define OP(OPC)                                                                \
17eba106d4Svporpo   case Opcode::OPC:                                                            \
18eba106d4Svporpo     return #OPC;
19eba106d4Svporpo #define OPCODES(...) __VA_ARGS__
20eba106d4Svporpo #define DEF_INSTR(ID, OPC, CLASS) OPC
219e85937bSvporpo #include "llvm/SandboxIR/Values.def"
22eba106d4Svporpo   }
23eba106d4Svporpo   llvm_unreachable("Unknown Opcode");
24eba106d4Svporpo }
25eba106d4Svporpo 
26eba106d4Svporpo llvm::Instruction *Instruction::getTopmostLLVMInstruction() const {
27eba106d4Svporpo   Instruction *Prev = getPrevNode();
28eba106d4Svporpo   if (Prev == nullptr) {
29eba106d4Svporpo     // If at top of the BB, return the first BB instruction.
30eba106d4Svporpo     return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
31eba106d4Svporpo   }
32eba106d4Svporpo   // Else get the Previous sandbox IR instruction's bottom IR instruction and
33eba106d4Svporpo   // return its successor.
34eba106d4Svporpo   llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val);
35eba106d4Svporpo   return PrevBotI->getNextNode();
36eba106d4Svporpo }
37eba106d4Svporpo 
38eba106d4Svporpo BBIterator Instruction::getIterator() const {
39eba106d4Svporpo   auto *I = cast<llvm::Instruction>(Val);
40eba106d4Svporpo   return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
41eba106d4Svporpo }
42eba106d4Svporpo 
43eba106d4Svporpo Instruction *Instruction::getNextNode() const {
44eba106d4Svporpo   assert(getParent() != nullptr && "Detached!");
45eba106d4Svporpo   assert(getIterator() != getParent()->end() && "Already at end!");
46eba106d4Svporpo   // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
47eba106d4Svporpo   // and get the corresponding sandboxir Instruction that maps to it. This works
48eba106d4Svporpo   // even for SandboxIR Instructions that map to more than one LLVM Instruction.
49eba106d4Svporpo   auto *LLVMI = cast<llvm::Instruction>(Val);
50eba106d4Svporpo   assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
51eba106d4Svporpo   auto *NextLLVMI = LLVMI->getNextNode();
52eba106d4Svporpo   auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
53eba106d4Svporpo   if (NextI == nullptr)
54eba106d4Svporpo     return nullptr;
55eba106d4Svporpo   return NextI;
56eba106d4Svporpo }
57eba106d4Svporpo 
58eba106d4Svporpo Instruction *Instruction::getPrevNode() const {
59eba106d4Svporpo   assert(getParent() != nullptr && "Detached!");
60eba106d4Svporpo   auto It = getIterator();
61eba106d4Svporpo   if (It != getParent()->begin())
62eba106d4Svporpo     return std::prev(getIterator()).get();
63eba106d4Svporpo   return nullptr;
64eba106d4Svporpo }
65eba106d4Svporpo 
66eba106d4Svporpo void Instruction::removeFromParent() {
67eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<RemoveFromParent>(this);
68eba106d4Svporpo 
69eba106d4Svporpo   // Detach all the LLVM IR instructions from their parent BB.
70eba106d4Svporpo   for (llvm::Instruction *I : getLLVMInstrs())
71eba106d4Svporpo     I->removeFromParent();
72eba106d4Svporpo }
73eba106d4Svporpo 
74eba106d4Svporpo void Instruction::eraseFromParent() {
75eba106d4Svporpo   assert(users().empty() && "Still connected to users, can't erase!");
764df71ab7SJorge Gorbe Moya 
774df71ab7SJorge Gorbe Moya   Ctx.runEraseInstrCallbacks(this);
78eba106d4Svporpo   std::unique_ptr<Value> Detached = Ctx.detach(this);
79eba106d4Svporpo   auto LLVMInstrs = getLLVMInstrs();
80eba106d4Svporpo 
81eba106d4Svporpo   auto &Tracker = Ctx.getTracker();
82eba106d4Svporpo   if (Tracker.isTracking()) {
83eba106d4Svporpo     Tracker.track(std::make_unique<EraseFromParent>(std::move(Detached)));
84eba106d4Svporpo     // We don't actually delete the IR instruction, because then it would be
85eba106d4Svporpo     // impossible to bring it back from the dead at the same memory location.
86eba106d4Svporpo     // Instead we remove it from its BB and track its current location.
87eba106d4Svporpo     for (llvm::Instruction *I : LLVMInstrs)
88eba106d4Svporpo       I->removeFromParent();
89eba106d4Svporpo     // TODO: Multi-instructions need special treatment because some of the
90eba106d4Svporpo     // references are internal to the instruction.
91eba106d4Svporpo     for (llvm::Instruction *I : LLVMInstrs)
92eba106d4Svporpo       I->dropAllReferences();
93eba106d4Svporpo   } else {
94eba106d4Svporpo     // Erase in reverse to avoid erasing nstructions with attached uses.
95eba106d4Svporpo     for (llvm::Instruction *I : reverse(LLVMInstrs))
96eba106d4Svporpo       I->eraseFromParent();
97eba106d4Svporpo   }
98eba106d4Svporpo }
99eba106d4Svporpo 
100eba106d4Svporpo void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) {
101eba106d4Svporpo   if (std::next(getIterator()) == WhereIt)
102eba106d4Svporpo     // Destination is same as origin, nothing to do.
103eba106d4Svporpo     return;
104eba106d4Svporpo 
1054df71ab7SJorge Gorbe Moya   Ctx.runMoveInstrCallbacks(this, WhereIt);
106eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<MoveInstr>(this);
107eba106d4Svporpo 
108eba106d4Svporpo   auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
109eba106d4Svporpo   llvm::BasicBlock::iterator It;
110eba106d4Svporpo   if (WhereIt == BB.end()) {
111eba106d4Svporpo     It = LLVMBB->end();
112eba106d4Svporpo   } else {
113eba106d4Svporpo     Instruction *WhereI = &*WhereIt;
114eba106d4Svporpo     It = WhereI->getTopmostLLVMInstruction()->getIterator();
115eba106d4Svporpo   }
116eba106d4Svporpo   // TODO: Move this to the verifier of sandboxir::Instruction.
117eba106d4Svporpo   assert(is_sorted(getLLVMInstrs(),
118eba106d4Svporpo                    [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
119eba106d4Svporpo          "Expected program order!");
120eba106d4Svporpo   // Do the actual move in LLVM IR.
121eba106d4Svporpo   for (auto *I : getLLVMInstrs())
122eba106d4Svporpo     I->moveBefore(*LLVMBB, It);
123eba106d4Svporpo }
124eba106d4Svporpo 
125eba106d4Svporpo void Instruction::insertBefore(Instruction *BeforeI) {
126eba106d4Svporpo   llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
127eba106d4Svporpo 
128eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
129eba106d4Svporpo 
130eba106d4Svporpo   // Insert the LLVM IR Instructions in program order.
131eba106d4Svporpo   for (llvm::Instruction *I : getLLVMInstrs())
132*749443a3SJeremy Morse     I->insertBefore(BeforeTopI->getIterator());
133eba106d4Svporpo }
134eba106d4Svporpo 
135eba106d4Svporpo void Instruction::insertAfter(Instruction *AfterI) {
136eba106d4Svporpo   insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
137eba106d4Svporpo }
138eba106d4Svporpo 
139eba106d4Svporpo void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
140eba106d4Svporpo   llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
141eba106d4Svporpo   llvm::Instruction *LLVMBeforeI;
142eba106d4Svporpo   llvm::BasicBlock::iterator LLVMBeforeIt;
143eba106d4Svporpo   Instruction *BeforeI;
144eba106d4Svporpo   if (WhereIt != BB->end()) {
145eba106d4Svporpo     BeforeI = &*WhereIt;
146eba106d4Svporpo     LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
147eba106d4Svporpo     LLVMBeforeIt = LLVMBeforeI->getIterator();
148eba106d4Svporpo   } else {
149eba106d4Svporpo     BeforeI = nullptr;
150eba106d4Svporpo     LLVMBeforeI = nullptr;
151eba106d4Svporpo     LLVMBeforeIt = LLVMBB->end();
152eba106d4Svporpo   }
153eba106d4Svporpo 
154eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
155eba106d4Svporpo 
156eba106d4Svporpo   // Insert the LLVM IR Instructions in program order.
157eba106d4Svporpo   for (llvm::Instruction *I : getLLVMInstrs())
158eba106d4Svporpo     I->insertInto(LLVMBB, LLVMBeforeIt);
159eba106d4Svporpo }
160eba106d4Svporpo 
161eba106d4Svporpo BasicBlock *Instruction::getParent() const {
162eba106d4Svporpo   // Get the LLVM IR Instruction that this maps to, get its parent, and get the
163eba106d4Svporpo   // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
164eba106d4Svporpo   auto *BB = cast<llvm::Instruction>(Val)->getParent();
165eba106d4Svporpo   if (BB == nullptr)
166eba106d4Svporpo     return nullptr;
167eba106d4Svporpo   return cast<BasicBlock>(Ctx.getValue(BB));
168eba106d4Svporpo }
169eba106d4Svporpo 
170eba106d4Svporpo bool Instruction::classof(const sandboxir::Value *From) {
171eba106d4Svporpo   switch (From->getSubclassID()) {
172eba106d4Svporpo #define DEF_INSTR(ID, OPC, CLASS)                                              \
173eba106d4Svporpo   case ClassID::ID:                                                            \
174eba106d4Svporpo     return true;
1759e85937bSvporpo #include "llvm/SandboxIR/Values.def"
176eba106d4Svporpo   default:
177eba106d4Svporpo     return false;
178eba106d4Svporpo   }
179eba106d4Svporpo }
180eba106d4Svporpo 
181eba106d4Svporpo void Instruction::setHasNoUnsignedWrap(bool B) {
182eba106d4Svporpo   Ctx.getTracker()
183eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::hasNoUnsignedWrap,
184eba106d4Svporpo                                        &Instruction::setHasNoUnsignedWrap>>(
185eba106d4Svporpo           this);
186eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B);
187eba106d4Svporpo }
188eba106d4Svporpo 
189eba106d4Svporpo void Instruction::setHasNoSignedWrap(bool B) {
190eba106d4Svporpo   Ctx.getTracker()
191eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedWrap,
192eba106d4Svporpo                                        &Instruction::setHasNoSignedWrap>>(this);
193eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B);
194eba106d4Svporpo }
195eba106d4Svporpo 
196eba106d4Svporpo void Instruction::setFast(bool B) {
197eba106d4Svporpo   Ctx.getTracker()
198eba106d4Svporpo       .emplaceIfTracking<
199eba106d4Svporpo           GenericSetter<&Instruction::isFast, &Instruction::setFast>>(this);
200eba106d4Svporpo   cast<llvm::Instruction>(Val)->setFast(B);
201eba106d4Svporpo }
202eba106d4Svporpo 
203eba106d4Svporpo void Instruction::setIsExact(bool B) {
204eba106d4Svporpo   Ctx.getTracker()
205eba106d4Svporpo       .emplaceIfTracking<
206eba106d4Svporpo           GenericSetter<&Instruction::isExact, &Instruction::setIsExact>>(this);
207eba106d4Svporpo   cast<llvm::Instruction>(Val)->setIsExact(B);
208eba106d4Svporpo }
209eba106d4Svporpo 
210eba106d4Svporpo void Instruction::setHasAllowReassoc(bool B) {
211eba106d4Svporpo   Ctx.getTracker()
212eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReassoc,
213eba106d4Svporpo                                        &Instruction::setHasAllowReassoc>>(this);
214eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasAllowReassoc(B);
215eba106d4Svporpo }
216eba106d4Svporpo 
217eba106d4Svporpo void Instruction::setHasNoNaNs(bool B) {
218eba106d4Svporpo   Ctx.getTracker()
219eba106d4Svporpo       .emplaceIfTracking<
220eba106d4Svporpo           GenericSetter<&Instruction::hasNoNaNs, &Instruction::setHasNoNaNs>>(
221eba106d4Svporpo           this);
222eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasNoNaNs(B);
223eba106d4Svporpo }
224eba106d4Svporpo 
225eba106d4Svporpo void Instruction::setHasNoInfs(bool B) {
226eba106d4Svporpo   Ctx.getTracker()
227eba106d4Svporpo       .emplaceIfTracking<
228eba106d4Svporpo           GenericSetter<&Instruction::hasNoInfs, &Instruction::setHasNoInfs>>(
229eba106d4Svporpo           this);
230eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasNoInfs(B);
231eba106d4Svporpo }
232eba106d4Svporpo 
233eba106d4Svporpo void Instruction::setHasNoSignedZeros(bool B) {
234eba106d4Svporpo   Ctx.getTracker()
235eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedZeros,
236eba106d4Svporpo                                        &Instruction::setHasNoSignedZeros>>(
237eba106d4Svporpo           this);
238eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B);
239eba106d4Svporpo }
240eba106d4Svporpo 
241eba106d4Svporpo void Instruction::setHasAllowReciprocal(bool B) {
242eba106d4Svporpo   Ctx.getTracker()
243eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReciprocal,
244eba106d4Svporpo                                        &Instruction::setHasAllowReciprocal>>(
245eba106d4Svporpo           this);
246eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B);
247eba106d4Svporpo }
248eba106d4Svporpo 
249eba106d4Svporpo void Instruction::setHasAllowContract(bool B) {
250eba106d4Svporpo   Ctx.getTracker()
251eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::hasAllowContract,
252eba106d4Svporpo                                        &Instruction::setHasAllowContract>>(
253eba106d4Svporpo           this);
254eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasAllowContract(B);
255eba106d4Svporpo }
256eba106d4Svporpo 
257eba106d4Svporpo void Instruction::setFastMathFlags(FastMathFlags FMF) {
258eba106d4Svporpo   Ctx.getTracker()
259eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags,
260eba106d4Svporpo                                        &Instruction::copyFastMathFlags>>(this);
261eba106d4Svporpo   cast<llvm::Instruction>(Val)->setFastMathFlags(FMF);
262eba106d4Svporpo }
263eba106d4Svporpo 
264eba106d4Svporpo void Instruction::copyFastMathFlags(FastMathFlags FMF) {
265eba106d4Svporpo   Ctx.getTracker()
266eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags,
267eba106d4Svporpo                                        &Instruction::copyFastMathFlags>>(this);
268eba106d4Svporpo   cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF);
269eba106d4Svporpo }
270eba106d4Svporpo 
271eba106d4Svporpo Type *Instruction::getAccessType() const {
272eba106d4Svporpo   return Ctx.getType(cast<llvm::Instruction>(Val)->getAccessType());
273eba106d4Svporpo }
274eba106d4Svporpo 
275eba106d4Svporpo void Instruction::setHasApproxFunc(bool B) {
276eba106d4Svporpo   Ctx.getTracker()
277eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&Instruction::hasApproxFunc,
278eba106d4Svporpo                                        &Instruction::setHasApproxFunc>>(this);
279eba106d4Svporpo   cast<llvm::Instruction>(Val)->setHasApproxFunc(B);
280eba106d4Svporpo }
281eba106d4Svporpo 
282eba106d4Svporpo #ifndef NDEBUG
283eba106d4Svporpo void Instruction::dumpOS(raw_ostream &OS) const {
284eba106d4Svporpo   OS << "Unimplemented! Please override dump().";
285eba106d4Svporpo }
286eba106d4Svporpo #endif // NDEBUG
287eba106d4Svporpo 
288e1434a87Svporpo VAArgInst *VAArgInst::create(Value *List, Type *Ty, InsertPosition Pos,
289e1434a87Svporpo                              Context &Ctx, const Twine &Name) {
290e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
291eba106d4Svporpo   auto *LLVMI =
292eba106d4Svporpo       cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty->LLVMTy, Name));
293eba106d4Svporpo   return Ctx.createVAArgInst(LLVMI);
294eba106d4Svporpo }
295eba106d4Svporpo 
296eba106d4Svporpo Value *VAArgInst::getPointerOperand() {
297eba106d4Svporpo   return Ctx.getValue(cast<llvm::VAArgInst>(Val)->getPointerOperand());
298eba106d4Svporpo }
299eba106d4Svporpo 
300e1434a87Svporpo FreezeInst *FreezeInst::create(Value *V, InsertPosition Pos, Context &Ctx,
301eba106d4Svporpo                                const Twine &Name) {
302e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
303eba106d4Svporpo   auto *LLVMI = cast<llvm::FreezeInst>(Builder.CreateFreeze(V->Val, Name));
304eba106d4Svporpo   return Ctx.createFreezeInst(LLVMI);
305eba106d4Svporpo }
306eba106d4Svporpo 
307635db5eeSvporpo FenceInst *FenceInst::create(AtomicOrdering Ordering, InsertPosition Pos,
308635db5eeSvporpo                              Context &Ctx, SyncScope::ID SSID) {
309635db5eeSvporpo   auto &Builder = Instruction::setInsertPos(Pos);
310eba106d4Svporpo   llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID);
311eba106d4Svporpo   return Ctx.createFenceInst(LLVMI);
312eba106d4Svporpo }
313eba106d4Svporpo 
314eba106d4Svporpo void FenceInst::setOrdering(AtomicOrdering Ordering) {
315eba106d4Svporpo   Ctx.getTracker()
316eba106d4Svporpo       .emplaceIfTracking<
317eba106d4Svporpo           GenericSetter<&FenceInst::getOrdering, &FenceInst::setOrdering>>(
318eba106d4Svporpo           this);
319eba106d4Svporpo   cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
320eba106d4Svporpo }
321eba106d4Svporpo 
322eba106d4Svporpo void FenceInst::setSyncScopeID(SyncScope::ID SSID) {
323eba106d4Svporpo   Ctx.getTracker()
324eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
325eba106d4Svporpo                                        &FenceInst::setSyncScopeID>>(this);
326eba106d4Svporpo   cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
327eba106d4Svporpo }
328eba106d4Svporpo 
329635db5eeSvporpo Value *SelectInst::create(Value *Cond, Value *True, Value *False,
330635db5eeSvporpo                           InsertPosition Pos, Context &Ctx, const Twine &Name) {
331635db5eeSvporpo   auto &Builder = Instruction::setInsertPos(Pos);
332eba106d4Svporpo   llvm::Value *NewV =
333eba106d4Svporpo       Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
334eba106d4Svporpo   if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
335eba106d4Svporpo     return Ctx.createSelectInst(NewSI);
336eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
337eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
338eba106d4Svporpo }
339eba106d4Svporpo 
340eba106d4Svporpo void SelectInst::swapValues() {
341eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1),
342eba106d4Svporpo                                               getOperandUse(2));
343eba106d4Svporpo   cast<llvm::SelectInst>(Val)->swapValues();
344eba106d4Svporpo }
345eba106d4Svporpo 
346eba106d4Svporpo bool SelectInst::classof(const Value *From) {
347eba106d4Svporpo   return From->getSubclassID() == ClassID::Select;
348eba106d4Svporpo }
349eba106d4Svporpo 
350e1434a87Svporpo BranchInst *BranchInst::create(BasicBlock *IfTrue, InsertPosition Pos,
351eba106d4Svporpo                                Context &Ctx) {
352e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
353eba106d4Svporpo   llvm::BranchInst *NewBr =
354eba106d4Svporpo       Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
355eba106d4Svporpo   return Ctx.createBranchInst(NewBr);
356eba106d4Svporpo }
357eba106d4Svporpo 
358eba106d4Svporpo BranchInst *BranchInst::create(BasicBlock *IfTrue, BasicBlock *IfFalse,
359e1434a87Svporpo                                Value *Cond, InsertPosition Pos, Context &Ctx) {
360e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
361eba106d4Svporpo   llvm::BranchInst *NewBr =
362eba106d4Svporpo       Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
363eba106d4Svporpo                            cast<llvm::BasicBlock>(IfFalse->Val));
364eba106d4Svporpo   return Ctx.createBranchInst(NewBr);
365eba106d4Svporpo }
366eba106d4Svporpo 
367eba106d4Svporpo bool BranchInst::classof(const Value *From) {
368eba106d4Svporpo   return From->getSubclassID() == ClassID::Br;
369eba106d4Svporpo }
370eba106d4Svporpo 
371eba106d4Svporpo Value *BranchInst::getCondition() const {
372eba106d4Svporpo   assert(isConditional() && "Cannot get condition of an uncond branch!");
373eba106d4Svporpo   return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition());
374eba106d4Svporpo }
375eba106d4Svporpo 
376eba106d4Svporpo BasicBlock *BranchInst::getSuccessor(unsigned SuccIdx) const {
377eba106d4Svporpo   assert(SuccIdx < getNumSuccessors() &&
378eba106d4Svporpo          "Successor # out of range for Branch!");
379eba106d4Svporpo   return cast_or_null<BasicBlock>(
380eba106d4Svporpo       Ctx.getValue(cast<llvm::BranchInst>(Val)->getSuccessor(SuccIdx)));
381eba106d4Svporpo }
382eba106d4Svporpo 
383eba106d4Svporpo void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
384eba106d4Svporpo   assert((Idx == 0 || Idx == 1) && "Out of bounds!");
385eba106d4Svporpo   setOperand(2u - Idx, NewSucc);
386eba106d4Svporpo }
387eba106d4Svporpo 
388eba106d4Svporpo BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
389eba106d4Svporpo   return cast<BasicBlock>(Ctx.getValue(BB));
390eba106d4Svporpo }
391eba106d4Svporpo const BasicBlock *
392eba106d4Svporpo BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
393eba106d4Svporpo   return cast<BasicBlock>(Ctx.getValue(BB));
394eba106d4Svporpo }
395eba106d4Svporpo 
396eba106d4Svporpo void LoadInst::setVolatile(bool V) {
397eba106d4Svporpo   Ctx.getTracker()
398eba106d4Svporpo       .emplaceIfTracking<
399eba106d4Svporpo           GenericSetter<&LoadInst::isVolatile, &LoadInst::setVolatile>>(this);
400eba106d4Svporpo   cast<llvm::LoadInst>(Val)->setVolatile(V);
401eba106d4Svporpo }
402eba106d4Svporpo 
403eba106d4Svporpo LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align,
404e1434a87Svporpo                            InsertPosition Pos, bool IsVolatile, Context &Ctx,
405eba106d4Svporpo                            const Twine &Name) {
406e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
407eba106d4Svporpo   auto *NewLI =
408eba106d4Svporpo       Builder.CreateAlignedLoad(Ty->LLVMTy, Ptr->Val, Align, IsVolatile, Name);
409eba106d4Svporpo   auto *NewSBI = Ctx.createLoadInst(NewLI);
410eba106d4Svporpo   return NewSBI;
411eba106d4Svporpo }
412eba106d4Svporpo 
413eba106d4Svporpo bool LoadInst::classof(const Value *From) {
414eba106d4Svporpo   return From->getSubclassID() == ClassID::Load;
415eba106d4Svporpo }
416eba106d4Svporpo 
417eba106d4Svporpo Value *LoadInst::getPointerOperand() const {
418eba106d4Svporpo   return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());
419eba106d4Svporpo }
420eba106d4Svporpo 
421eba106d4Svporpo void StoreInst::setVolatile(bool V) {
422eba106d4Svporpo   Ctx.getTracker()
423eba106d4Svporpo       .emplaceIfTracking<
424eba106d4Svporpo           GenericSetter<&StoreInst::isVolatile, &StoreInst::setVolatile>>(this);
425eba106d4Svporpo   cast<llvm::StoreInst>(Val)->setVolatile(V);
426eba106d4Svporpo }
427eba106d4Svporpo 
428eba106d4Svporpo StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
429e1434a87Svporpo                              InsertPosition Pos, bool IsVolatile,
430eba106d4Svporpo                              Context &Ctx) {
431e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
432eba106d4Svporpo   auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
433eba106d4Svporpo   auto *NewSBI = Ctx.createStoreInst(NewSI);
434eba106d4Svporpo   return NewSBI;
435eba106d4Svporpo }
436eba106d4Svporpo 
437eba106d4Svporpo bool StoreInst::classof(const Value *From) {
438eba106d4Svporpo   return From->getSubclassID() == ClassID::Store;
439eba106d4Svporpo }
440eba106d4Svporpo 
441eba106d4Svporpo Value *StoreInst::getValueOperand() const {
442eba106d4Svporpo   return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
443eba106d4Svporpo }
444eba106d4Svporpo 
445eba106d4Svporpo Value *StoreInst::getPointerOperand() const {
446eba106d4Svporpo   return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
447eba106d4Svporpo }
448eba106d4Svporpo 
4493a47bf63Svporpo UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) {
4503a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
451eba106d4Svporpo   llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
452eba106d4Svporpo   return Ctx.createUnreachableInst(NewUI);
453eba106d4Svporpo }
454eba106d4Svporpo 
455eba106d4Svporpo bool UnreachableInst::classof(const Value *From) {
456eba106d4Svporpo   return From->getSubclassID() == ClassID::Unreachable;
457eba106d4Svporpo }
458eba106d4Svporpo 
459eba106d4Svporpo ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
460eba106d4Svporpo                                      Context &Ctx) {
461eba106d4Svporpo   llvm::ReturnInst *NewRI;
462eba106d4Svporpo   if (RetVal != nullptr)
463eba106d4Svporpo     NewRI = Builder.CreateRet(RetVal->Val);
464eba106d4Svporpo   else
465eba106d4Svporpo     NewRI = Builder.CreateRetVoid();
466eba106d4Svporpo   return Ctx.createReturnInst(NewRI);
467eba106d4Svporpo }
468eba106d4Svporpo 
4693a47bf63Svporpo ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos,
470eba106d4Svporpo                                Context &Ctx) {
4713a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
472eba106d4Svporpo   return createCommon(RetVal, Builder, Ctx);
473eba106d4Svporpo }
474eba106d4Svporpo 
475eba106d4Svporpo Value *ReturnInst::getReturnValue() const {
476eba106d4Svporpo   auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
477eba106d4Svporpo   return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
478eba106d4Svporpo }
479eba106d4Svporpo 
480eba106d4Svporpo FunctionType *CallBase::getFunctionType() const {
481eba106d4Svporpo   return cast<FunctionType>(
482eba106d4Svporpo       Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType()));
483eba106d4Svporpo }
484eba106d4Svporpo 
485eba106d4Svporpo Value *CallBase::getCalledOperand() const {
486eba106d4Svporpo   return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());
487eba106d4Svporpo }
488eba106d4Svporpo 
489eba106d4Svporpo Use CallBase::getCalledOperandUse() const {
490eba106d4Svporpo   llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
491eba106d4Svporpo   return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
492eba106d4Svporpo }
493eba106d4Svporpo 
494eba106d4Svporpo Function *CallBase::getCalledFunction() const {
495eba106d4Svporpo   return cast_or_null<Function>(
496eba106d4Svporpo       Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
497eba106d4Svporpo }
498eba106d4Svporpo Function *CallBase::getCaller() {
499eba106d4Svporpo   return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
500eba106d4Svporpo }
501eba106d4Svporpo 
502eba106d4Svporpo void CallBase::setCalledFunction(Function *F) {
503eba106d4Svporpo   // F's function type is private, so we rely on `setCalledFunction()` to update
504eba106d4Svporpo   // it. But even though we are calling `setCalledFunction()` we also need to
505eba106d4Svporpo   // track this change at the SandboxIR level, which is why we call
506eba106d4Svporpo   // `setCalledOperand()` here.
507eba106d4Svporpo   // Note: This may break if `setCalledFunction()` early returns if `F`
508eba106d4Svporpo   // is already set, but we do have a unit test for it.
509eba106d4Svporpo   setCalledOperand(F);
510eba106d4Svporpo   cast<llvm::CallBase>(Val)->setCalledFunction(
511eba106d4Svporpo       cast<llvm::FunctionType>(F->getFunctionType()->LLVMTy),
512eba106d4Svporpo       cast<llvm::Function>(F->Val));
513eba106d4Svporpo }
514eba106d4Svporpo 
515eba106d4Svporpo CallInst *CallInst::create(FunctionType *FTy, Value *Func,
5163a47bf63Svporpo                            ArrayRef<Value *> Args, InsertPosition Pos,
5173a47bf63Svporpo                            Context &Ctx, const Twine &NameStr) {
5183a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
519eba106d4Svporpo   SmallVector<llvm::Value *> LLVMArgs;
520eba106d4Svporpo   LLVMArgs.reserve(Args.size());
521eba106d4Svporpo   for (Value *Arg : Args)
522eba106d4Svporpo     LLVMArgs.push_back(Arg->Val);
523eba106d4Svporpo   llvm::CallInst *NewCI = Builder.CreateCall(
524eba106d4Svporpo       cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, LLVMArgs, NameStr);
525eba106d4Svporpo   return Ctx.createCallInst(NewCI);
526eba106d4Svporpo }
527eba106d4Svporpo 
528eba106d4Svporpo InvokeInst *InvokeInst::create(FunctionType *FTy, Value *Func,
529eba106d4Svporpo                                BasicBlock *IfNormal, BasicBlock *IfException,
5303a47bf63Svporpo                                ArrayRef<Value *> Args, InsertPosition Pos,
5313a47bf63Svporpo                                Context &Ctx, const Twine &NameStr) {
5323a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
533eba106d4Svporpo   SmallVector<llvm::Value *> LLVMArgs;
534eba106d4Svporpo   LLVMArgs.reserve(Args.size());
535eba106d4Svporpo   for (Value *Arg : Args)
536eba106d4Svporpo     LLVMArgs.push_back(Arg->Val);
537eba106d4Svporpo   llvm::InvokeInst *Invoke = Builder.CreateInvoke(
538eba106d4Svporpo       cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
539eba106d4Svporpo       cast<llvm::BasicBlock>(IfNormal->Val),
540eba106d4Svporpo       cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
541eba106d4Svporpo   return Ctx.createInvokeInst(Invoke);
542eba106d4Svporpo }
543eba106d4Svporpo 
544eba106d4Svporpo BasicBlock *InvokeInst::getNormalDest() const {
545eba106d4Svporpo   return cast<BasicBlock>(
546eba106d4Svporpo       Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
547eba106d4Svporpo }
548eba106d4Svporpo BasicBlock *InvokeInst::getUnwindDest() const {
549eba106d4Svporpo   return cast<BasicBlock>(
550eba106d4Svporpo       Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
551eba106d4Svporpo }
552eba106d4Svporpo void InvokeInst::setNormalDest(BasicBlock *BB) {
553eba106d4Svporpo   setOperand(1, BB);
554eba106d4Svporpo   assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
555eba106d4Svporpo }
556eba106d4Svporpo void InvokeInst::setUnwindDest(BasicBlock *BB) {
557eba106d4Svporpo   setOperand(2, BB);
558eba106d4Svporpo   assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
559eba106d4Svporpo }
560eba106d4Svporpo LandingPadInst *InvokeInst::getLandingPadInst() const {
561eba106d4Svporpo   return cast<LandingPadInst>(
562eba106d4Svporpo       Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
563eba106d4Svporpo   ;
564eba106d4Svporpo }
565eba106d4Svporpo BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
566eba106d4Svporpo   return cast<BasicBlock>(
567eba106d4Svporpo       Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
568eba106d4Svporpo }
569eba106d4Svporpo 
570eba106d4Svporpo CallBrInst *CallBrInst::create(FunctionType *FTy, Value *Func,
571eba106d4Svporpo                                BasicBlock *DefaultDest,
572eba106d4Svporpo                                ArrayRef<BasicBlock *> IndirectDests,
5733a47bf63Svporpo                                ArrayRef<Value *> Args, InsertPosition Pos,
5743a47bf63Svporpo                                Context &Ctx, const Twine &NameStr) {
5753a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
576eba106d4Svporpo   SmallVector<llvm::BasicBlock *> LLVMIndirectDests;
577eba106d4Svporpo   LLVMIndirectDests.reserve(IndirectDests.size());
578eba106d4Svporpo   for (BasicBlock *IndDest : IndirectDests)
579eba106d4Svporpo     LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
580eba106d4Svporpo 
581eba106d4Svporpo   SmallVector<llvm::Value *> LLVMArgs;
582eba106d4Svporpo   LLVMArgs.reserve(Args.size());
583eba106d4Svporpo   for (Value *Arg : Args)
584eba106d4Svporpo     LLVMArgs.push_back(Arg->Val);
585eba106d4Svporpo 
586eba106d4Svporpo   llvm::CallBrInst *CallBr =
587eba106d4Svporpo       Builder.CreateCallBr(cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
588eba106d4Svporpo                            cast<llvm::BasicBlock>(DefaultDest->Val),
589eba106d4Svporpo                            LLVMIndirectDests, LLVMArgs, NameStr);
590eba106d4Svporpo   return Ctx.createCallBrInst(CallBr);
591eba106d4Svporpo }
592eba106d4Svporpo 
593eba106d4Svporpo Value *CallBrInst::getIndirectDestLabel(unsigned Idx) const {
594eba106d4Svporpo   return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
595eba106d4Svporpo }
596eba106d4Svporpo Value *CallBrInst::getIndirectDestLabelUse(unsigned Idx) const {
597eba106d4Svporpo   return Ctx.getValue(
598eba106d4Svporpo       cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx));
599eba106d4Svporpo }
600eba106d4Svporpo BasicBlock *CallBrInst::getDefaultDest() const {
601eba106d4Svporpo   return cast<BasicBlock>(
602eba106d4Svporpo       Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
603eba106d4Svporpo }
604eba106d4Svporpo BasicBlock *CallBrInst::getIndirectDest(unsigned Idx) const {
605eba106d4Svporpo   return cast<BasicBlock>(
606eba106d4Svporpo       Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
607eba106d4Svporpo }
608eba106d4Svporpo llvm::SmallVector<BasicBlock *, 16> CallBrInst::getIndirectDests() const {
609eba106d4Svporpo   SmallVector<BasicBlock *, 16> BBs;
610eba106d4Svporpo   for (llvm::BasicBlock *LLVMBB :
611eba106d4Svporpo        cast<llvm::CallBrInst>(Val)->getIndirectDests())
612eba106d4Svporpo     BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
613eba106d4Svporpo   return BBs;
614eba106d4Svporpo }
615eba106d4Svporpo void CallBrInst::setDefaultDest(BasicBlock *BB) {
616eba106d4Svporpo   Ctx.getTracker()
617eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&CallBrInst::getDefaultDest,
618eba106d4Svporpo                                        &CallBrInst::setDefaultDest>>(this);
619eba106d4Svporpo   cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
620eba106d4Svporpo }
621eba106d4Svporpo void CallBrInst::setIndirectDest(unsigned Idx, BasicBlock *BB) {
622eba106d4Svporpo   Ctx.getTracker()
623eba106d4Svporpo       .emplaceIfTracking<GenericSetterWithIdx<&CallBrInst::getIndirectDest,
624eba106d4Svporpo                                               &CallBrInst::setIndirectDest>>(
625eba106d4Svporpo           this, Idx);
626eba106d4Svporpo   cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
627eba106d4Svporpo                                                cast<llvm::BasicBlock>(BB->Val));
628eba106d4Svporpo }
629eba106d4Svporpo BasicBlock *CallBrInst::getSuccessor(unsigned Idx) const {
630eba106d4Svporpo   return cast<BasicBlock>(
631eba106d4Svporpo       Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
632eba106d4Svporpo }
633eba106d4Svporpo 
634eba106d4Svporpo LandingPadInst *LandingPadInst::create(Type *RetTy, unsigned NumReservedClauses,
6353a47bf63Svporpo                                        InsertPosition Pos, Context &Ctx,
6363a47bf63Svporpo                                        const Twine &Name) {
6373a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
638eba106d4Svporpo   llvm::LandingPadInst *LLVMI =
639eba106d4Svporpo       Builder.CreateLandingPad(RetTy->LLVMTy, NumReservedClauses, Name);
640eba106d4Svporpo   return Ctx.createLandingPadInst(LLVMI);
641eba106d4Svporpo }
642eba106d4Svporpo 
643eba106d4Svporpo void LandingPadInst::setCleanup(bool V) {
644eba106d4Svporpo   Ctx.getTracker()
645eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&LandingPadInst::isCleanup,
646eba106d4Svporpo                                        &LandingPadInst::setCleanup>>(this);
647eba106d4Svporpo   cast<llvm::LandingPadInst>(Val)->setCleanup(V);
648eba106d4Svporpo }
649eba106d4Svporpo 
650eba106d4Svporpo Constant *LandingPadInst::getClause(unsigned Idx) const {
651eba106d4Svporpo   return cast<Constant>(
652eba106d4Svporpo       Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx)));
653eba106d4Svporpo }
654eba106d4Svporpo 
655eba106d4Svporpo Value *FuncletPadInst::getParentPad() const {
656eba106d4Svporpo   return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getParentPad());
657eba106d4Svporpo }
658eba106d4Svporpo 
659eba106d4Svporpo void FuncletPadInst::setParentPad(Value *ParentPad) {
660eba106d4Svporpo   Ctx.getTracker()
661eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&FuncletPadInst::getParentPad,
662eba106d4Svporpo                                        &FuncletPadInst::setParentPad>>(this);
663eba106d4Svporpo   cast<llvm::FuncletPadInst>(Val)->setParentPad(ParentPad->Val);
664eba106d4Svporpo }
665eba106d4Svporpo 
666eba106d4Svporpo Value *FuncletPadInst::getArgOperand(unsigned Idx) const {
667eba106d4Svporpo   return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx));
668eba106d4Svporpo }
669eba106d4Svporpo 
670eba106d4Svporpo void FuncletPadInst::setArgOperand(unsigned Idx, Value *V) {
671eba106d4Svporpo   Ctx.getTracker()
672eba106d4Svporpo       .emplaceIfTracking<GenericSetterWithIdx<&FuncletPadInst::getArgOperand,
673eba106d4Svporpo                                               &FuncletPadInst::setArgOperand>>(
674eba106d4Svporpo           this, Idx);
675eba106d4Svporpo   cast<llvm::FuncletPadInst>(Val)->setArgOperand(Idx, V->Val);
676eba106d4Svporpo }
677eba106d4Svporpo 
678eba106d4Svporpo CatchSwitchInst *CatchPadInst::getCatchSwitch() const {
679eba106d4Svporpo   return cast<CatchSwitchInst>(
680eba106d4Svporpo       Ctx.getValue(cast<llvm::CatchPadInst>(Val)->getCatchSwitch()));
681eba106d4Svporpo }
682eba106d4Svporpo 
683eba106d4Svporpo CatchPadInst *CatchPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
6843a47bf63Svporpo                                    InsertPosition Pos, Context &Ctx,
6853a47bf63Svporpo                                    const Twine &Name) {
6863a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
687eba106d4Svporpo   SmallVector<llvm::Value *> LLVMArgs;
688eba106d4Svporpo   LLVMArgs.reserve(Args.size());
689eba106d4Svporpo   for (auto *Arg : Args)
690eba106d4Svporpo     LLVMArgs.push_back(Arg->Val);
691eba106d4Svporpo   llvm::CatchPadInst *LLVMI =
692eba106d4Svporpo       Builder.CreateCatchPad(ParentPad->Val, LLVMArgs, Name);
693eba106d4Svporpo   return Ctx.createCatchPadInst(LLVMI);
694eba106d4Svporpo }
695eba106d4Svporpo 
696eba106d4Svporpo CleanupPadInst *CleanupPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
6973a47bf63Svporpo                                        InsertPosition Pos, Context &Ctx,
6983a47bf63Svporpo                                        const Twine &Name) {
6993a47bf63Svporpo   auto &Builder = setInsertPos(Pos);
700eba106d4Svporpo   SmallVector<llvm::Value *> LLVMArgs;
701eba106d4Svporpo   LLVMArgs.reserve(Args.size());
702eba106d4Svporpo   for (auto *Arg : Args)
703eba106d4Svporpo     LLVMArgs.push_back(Arg->Val);
704eba106d4Svporpo   llvm::CleanupPadInst *LLVMI =
705eba106d4Svporpo       Builder.CreateCleanupPad(ParentPad->Val, LLVMArgs, Name);
706eba106d4Svporpo   return Ctx.createCleanupPadInst(LLVMI);
707eba106d4Svporpo }
708eba106d4Svporpo 
709eba106d4Svporpo CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB,
7104f3a0959Svporpo                                          InsertPosition Pos, Context &Ctx) {
7114f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
712eba106d4Svporpo   llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet(
713eba106d4Svporpo       cast<llvm::CatchPadInst>(CatchPad->Val), cast<llvm::BasicBlock>(BB->Val));
714eba106d4Svporpo   return Ctx.createCatchReturnInst(LLVMI);
715eba106d4Svporpo }
716eba106d4Svporpo 
717eba106d4Svporpo CatchPadInst *CatchReturnInst::getCatchPad() const {
718eba106d4Svporpo   return cast<CatchPadInst>(
719eba106d4Svporpo       Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));
720eba106d4Svporpo }
721eba106d4Svporpo 
722eba106d4Svporpo void CatchReturnInst::setCatchPad(CatchPadInst *CatchPad) {
723eba106d4Svporpo   Ctx.getTracker()
724eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&CatchReturnInst::getCatchPad,
725eba106d4Svporpo                                        &CatchReturnInst::setCatchPad>>(this);
726eba106d4Svporpo   cast<llvm::CatchReturnInst>(Val)->setCatchPad(
727eba106d4Svporpo       cast<llvm::CatchPadInst>(CatchPad->Val));
728eba106d4Svporpo }
729eba106d4Svporpo 
730eba106d4Svporpo BasicBlock *CatchReturnInst::getSuccessor() const {
731eba106d4Svporpo   return cast<BasicBlock>(
732eba106d4Svporpo       Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));
733eba106d4Svporpo }
734eba106d4Svporpo 
735eba106d4Svporpo void CatchReturnInst::setSuccessor(BasicBlock *NewSucc) {
736eba106d4Svporpo   Ctx.getTracker()
737eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&CatchReturnInst::getSuccessor,
738eba106d4Svporpo                                        &CatchReturnInst::setSuccessor>>(this);
739eba106d4Svporpo   cast<llvm::CatchReturnInst>(Val)->setSuccessor(
740eba106d4Svporpo       cast<llvm::BasicBlock>(NewSucc->Val));
741eba106d4Svporpo }
742eba106d4Svporpo 
743eba106d4Svporpo Value *CatchReturnInst::getCatchSwitchParentPad() const {
744eba106d4Svporpo   return Ctx.getValue(
745eba106d4Svporpo       cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());
746eba106d4Svporpo }
747eba106d4Svporpo 
748eba106d4Svporpo CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
749eba106d4Svporpo                                              BasicBlock *UnwindBB,
7504f3a0959Svporpo                                              InsertPosition Pos, Context &Ctx) {
7514f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
752eba106d4Svporpo   auto *LLVMUnwindBB =
753eba106d4Svporpo       UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
754eba106d4Svporpo   llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
755eba106d4Svporpo       cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
756eba106d4Svporpo   return Ctx.createCleanupReturnInst(LLVMI);
757eba106d4Svporpo }
758eba106d4Svporpo 
759eba106d4Svporpo CleanupPadInst *CleanupReturnInst::getCleanupPad() const {
760eba106d4Svporpo   return cast<CleanupPadInst>(
761eba106d4Svporpo       Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getCleanupPad()));
762eba106d4Svporpo }
763eba106d4Svporpo 
764eba106d4Svporpo void CleanupReturnInst::setCleanupPad(CleanupPadInst *CleanupPad) {
765eba106d4Svporpo   Ctx.getTracker()
766eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getCleanupPad,
767eba106d4Svporpo                                        &CleanupReturnInst::setCleanupPad>>(
768eba106d4Svporpo           this);
769eba106d4Svporpo   cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
770eba106d4Svporpo       cast<llvm::CleanupPadInst>(CleanupPad->Val));
771eba106d4Svporpo }
772eba106d4Svporpo 
773eba106d4Svporpo BasicBlock *CleanupReturnInst::getUnwindDest() const {
774eba106d4Svporpo   return cast_or_null<BasicBlock>(
775eba106d4Svporpo       Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getUnwindDest()));
776eba106d4Svporpo }
777eba106d4Svporpo 
778eba106d4Svporpo void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
779eba106d4Svporpo   Ctx.getTracker()
780eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getUnwindDest,
781eba106d4Svporpo                                        &CleanupReturnInst::setUnwindDest>>(
782eba106d4Svporpo           this);
783eba106d4Svporpo   cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
784eba106d4Svporpo       cast<llvm::BasicBlock>(NewDest->Val));
785eba106d4Svporpo }
786eba106d4Svporpo 
787eba106d4Svporpo Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
7884f3a0959Svporpo                                  ArrayRef<Value *> IdxList, InsertPosition Pos,
7894f3a0959Svporpo                                  Context &Ctx, const Twine &NameStr) {
7904f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
791eba106d4Svporpo   SmallVector<llvm::Value *> LLVMIdxList;
792eba106d4Svporpo   LLVMIdxList.reserve(IdxList.size());
793eba106d4Svporpo   for (Value *Idx : IdxList)
794eba106d4Svporpo     LLVMIdxList.push_back(Idx->Val);
795eba106d4Svporpo   llvm::Value *NewV =
796eba106d4Svporpo       Builder.CreateGEP(Ty->LLVMTy, Ptr->Val, LLVMIdxList, NameStr);
797eba106d4Svporpo   if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
798eba106d4Svporpo     return Ctx.createGetElementPtrInst(NewGEP);
799eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
800eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
801eba106d4Svporpo }
802eba106d4Svporpo 
803eba106d4Svporpo Type *GetElementPtrInst::getSourceElementType() const {
804eba106d4Svporpo   return Ctx.getType(
805eba106d4Svporpo       cast<llvm::GetElementPtrInst>(Val)->getSourceElementType());
806eba106d4Svporpo }
807eba106d4Svporpo 
808eba106d4Svporpo Type *GetElementPtrInst::getResultElementType() const {
809eba106d4Svporpo   return Ctx.getType(
810eba106d4Svporpo       cast<llvm::GetElementPtrInst>(Val)->getResultElementType());
811eba106d4Svporpo }
812eba106d4Svporpo 
813eba106d4Svporpo Value *GetElementPtrInst::getPointerOperand() const {
814eba106d4Svporpo   return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand());
815eba106d4Svporpo }
816eba106d4Svporpo 
817eba106d4Svporpo Type *GetElementPtrInst::getPointerOperandType() const {
818eba106d4Svporpo   return Ctx.getType(
819eba106d4Svporpo       cast<llvm::GetElementPtrInst>(Val)->getPointerOperandType());
820eba106d4Svporpo }
821eba106d4Svporpo 
822eba106d4Svporpo BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
823eba106d4Svporpo   return cast<BasicBlock>(Ctx.getValue(LLVMBB));
824eba106d4Svporpo }
825eba106d4Svporpo 
826eba106d4Svporpo PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
827c029702fSvporpo                          InsertPosition Pos, Context &Ctx, const Twine &Name) {
828c029702fSvporpo   auto &Builder = setInsertPos(Pos);
829c029702fSvporpo   llvm::PHINode *NewPHI =
830c029702fSvporpo       Builder.CreatePHI(Ty->LLVMTy, NumReservedValues, Name);
831eba106d4Svporpo   return Ctx.createPHINode(NewPHI);
832eba106d4Svporpo }
833eba106d4Svporpo 
834eba106d4Svporpo bool PHINode::classof(const Value *From) {
835eba106d4Svporpo   return From->getSubclassID() == ClassID::PHI;
836eba106d4Svporpo }
837eba106d4Svporpo 
838eba106d4Svporpo Value *PHINode::getIncomingValue(unsigned Idx) const {
839eba106d4Svporpo   return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
840eba106d4Svporpo }
841eba106d4Svporpo void PHINode::setIncomingValue(unsigned Idx, Value *V) {
842eba106d4Svporpo   Ctx.getTracker()
843eba106d4Svporpo       .emplaceIfTracking<GenericSetterWithIdx<&PHINode::getIncomingValue,
844eba106d4Svporpo                                               &PHINode::setIncomingValue>>(this,
845eba106d4Svporpo                                                                            Idx);
846eba106d4Svporpo   cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
847eba106d4Svporpo }
848eba106d4Svporpo BasicBlock *PHINode::getIncomingBlock(unsigned Idx) const {
849eba106d4Svporpo   return cast<BasicBlock>(
850eba106d4Svporpo       Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
851eba106d4Svporpo }
852eba106d4Svporpo BasicBlock *PHINode::getIncomingBlock(const Use &U) const {
853eba106d4Svporpo   llvm::Use *LLVMUse = U.LLVMUse;
854eba106d4Svporpo   llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
855eba106d4Svporpo   return cast<BasicBlock>(Ctx.getValue(BB));
856eba106d4Svporpo }
857eba106d4Svporpo void PHINode::setIncomingBlock(unsigned Idx, BasicBlock *BB) {
858eba106d4Svporpo   // Helper to disambiguate PHINode::getIncomingBlock(unsigned).
859eba106d4Svporpo   constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const =
860eba106d4Svporpo       &PHINode::getIncomingBlock;
861eba106d4Svporpo   Ctx.getTracker()
862eba106d4Svporpo       .emplaceIfTracking<
863eba106d4Svporpo           GenericSetterWithIdx<GetIncomingBlockFn, &PHINode::setIncomingBlock>>(
864eba106d4Svporpo           this, Idx);
865eba106d4Svporpo   cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
866eba106d4Svporpo                                              cast<llvm::BasicBlock>(BB->Val));
867eba106d4Svporpo }
868eba106d4Svporpo void PHINode::addIncoming(Value *V, BasicBlock *BB) {
869eba106d4Svporpo   auto &Tracker = Ctx.getTracker();
870eba106d4Svporpo   Tracker.emplaceIfTracking<PHIAddIncoming>(this);
871eba106d4Svporpo 
872eba106d4Svporpo   cast<llvm::PHINode>(Val)->addIncoming(V->Val,
873eba106d4Svporpo                                         cast<llvm::BasicBlock>(BB->Val));
874eba106d4Svporpo }
875eba106d4Svporpo Value *PHINode::removeIncomingValue(unsigned Idx) {
876eba106d4Svporpo   auto &Tracker = Ctx.getTracker();
877eba106d4Svporpo   Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, Idx);
878eba106d4Svporpo   llvm::Value *LLVMV =
879eba106d4Svporpo       cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
880eba106d4Svporpo                                                     /*DeletePHIIfEmpty=*/false);
881eba106d4Svporpo   return Ctx.getValue(LLVMV);
882eba106d4Svporpo }
883eba106d4Svporpo Value *PHINode::removeIncomingValue(BasicBlock *BB) {
884eba106d4Svporpo   auto &Tracker = Ctx.getTracker();
885eba106d4Svporpo   Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, getBasicBlockIndex(BB));
886eba106d4Svporpo 
887eba106d4Svporpo   auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
888eba106d4Svporpo   llvm::Value *LLVMV =
889eba106d4Svporpo       cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
890eba106d4Svporpo                                                     /*DeletePHIIfEmpty=*/false);
891eba106d4Svporpo   return Ctx.getValue(LLVMV);
892eba106d4Svporpo }
893eba106d4Svporpo int PHINode::getBasicBlockIndex(const BasicBlock *BB) const {
894eba106d4Svporpo   auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
895eba106d4Svporpo   return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
896eba106d4Svporpo }
897eba106d4Svporpo Value *PHINode::getIncomingValueForBlock(const BasicBlock *BB) const {
898eba106d4Svporpo   auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
899eba106d4Svporpo   llvm::Value *LLVMV =
900eba106d4Svporpo       cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
901eba106d4Svporpo   return Ctx.getValue(LLVMV);
902eba106d4Svporpo }
903eba106d4Svporpo Value *PHINode::hasConstantValue() const {
904eba106d4Svporpo   llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
905eba106d4Svporpo   return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
906eba106d4Svporpo }
907eba106d4Svporpo void PHINode::replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) {
908eba106d4Svporpo   assert(New && Old && "Sandbox IR PHI node got a null basic block!");
909eba106d4Svporpo   for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
910eba106d4Svporpo        Idx != NumOps; ++Idx)
911eba106d4Svporpo     if (getIncomingBlock(Idx) == Old)
912eba106d4Svporpo       setIncomingBlock(Idx, New);
913eba106d4Svporpo }
914eba106d4Svporpo void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
915eba106d4Svporpo   // Avoid duplicate tracking by going through this->removeIncomingValue here at
916eba106d4Svporpo   // the expense of some performance. Copy PHI::removeIncomingValueIf more
917eba106d4Svporpo   // directly if performance becomes an issue.
918eba106d4Svporpo 
919eba106d4Svporpo   // Removing the element at index X, moves the element previously at X + 1
920eba106d4Svporpo   // to X. Working from the end avoids complications from that.
921eba106d4Svporpo   unsigned Idx = getNumIncomingValues();
922eba106d4Svporpo   while (Idx > 0) {
923eba106d4Svporpo     if (Predicate(Idx - 1))
924eba106d4Svporpo       removeIncomingValue(Idx - 1);
925eba106d4Svporpo     --Idx;
926eba106d4Svporpo   }
927eba106d4Svporpo }
928eba106d4Svporpo 
92922d4ff15Svporpo Value *CmpInst::create(Predicate P, Value *S1, Value *S2, InsertPosition Pos,
930ed5088a2Svporpo                        Context &Ctx, const Twine &Name) {
931ed5088a2Svporpo   auto &Builder = setInsertPos(Pos);
93222d4ff15Svporpo   auto *LLVMV = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
93322d4ff15Svporpo   // It may have been folded into a constant.
93422d4ff15Svporpo   if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV))
93522d4ff15Svporpo     return Ctx.getOrCreateConstant(LLVMC);
93622d4ff15Svporpo   if (isa<llvm::ICmpInst>(LLVMV))
93722d4ff15Svporpo     return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMV));
93822d4ff15Svporpo   return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMV));
939ed5088a2Svporpo }
94022d4ff15Svporpo 
94122d4ff15Svporpo Value *CmpInst::createWithCopiedFlags(Predicate P, Value *S1, Value *S2,
94222d4ff15Svporpo                                       const Instruction *F, InsertPosition Pos,
94322d4ff15Svporpo                                       Context &Ctx, const Twine &Name) {
94422d4ff15Svporpo   Value *V = create(P, S1, S2, Pos, Ctx, Name);
94522d4ff15Svporpo   if (auto *C = dyn_cast<Constant>(V))
94622d4ff15Svporpo     return C;
94722d4ff15Svporpo   cast<llvm::CmpInst>(V->Val)->copyIRFlags(F->Val);
94822d4ff15Svporpo   return V;
949ed5088a2Svporpo }
950ed5088a2Svporpo 
951ed5088a2Svporpo Type *CmpInst::makeCmpResultType(Type *OpndType) {
952ed5088a2Svporpo   if (auto *VT = dyn_cast<VectorType>(OpndType)) {
953ed5088a2Svporpo     // TODO: Cleanup when we have more complete support for
954ed5088a2Svporpo     // sandboxir::VectorType
955ed5088a2Svporpo     return OpndType->getContext().getType(llvm::VectorType::get(
956ed5088a2Svporpo         llvm::Type::getInt1Ty(OpndType->getContext().LLVMCtx),
957ed5088a2Svporpo         cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
958ed5088a2Svporpo   }
959ed5088a2Svporpo   return Type::getInt1Ty(OpndType->getContext());
960ed5088a2Svporpo }
961ed5088a2Svporpo 
962ed5088a2Svporpo void CmpInst::setPredicate(Predicate P) {
963ed5088a2Svporpo   Ctx.getTracker()
964ed5088a2Svporpo       .emplaceIfTracking<
965ed5088a2Svporpo           GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this);
966ed5088a2Svporpo   cast<llvm::CmpInst>(Val)->setPredicate(P);
967ed5088a2Svporpo }
968ed5088a2Svporpo 
969ed5088a2Svporpo void CmpInst::swapOperands() {
970ed5088a2Svporpo   if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
971ed5088a2Svporpo     IC->swapOperands();
972ed5088a2Svporpo   else
973ed5088a2Svporpo     cast<FCmpInst>(this)->swapOperands();
974ed5088a2Svporpo }
975ed5088a2Svporpo 
976ed5088a2Svporpo void ICmpInst::swapOperands() {
977ed5088a2Svporpo   Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
978ed5088a2Svporpo   cast<llvm::ICmpInst>(Val)->swapOperands();
979ed5088a2Svporpo }
980ed5088a2Svporpo 
981ed5088a2Svporpo void FCmpInst::swapOperands() {
982ed5088a2Svporpo   Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
983ed5088a2Svporpo   cast<llvm::FCmpInst>(Val)->swapOperands();
984ed5088a2Svporpo }
985ed5088a2Svporpo 
986ed5088a2Svporpo #ifndef NDEBUG
987ed5088a2Svporpo void CmpInst::dumpOS(raw_ostream &OS) const {
988ed5088a2Svporpo   dumpCommonPrefix(OS);
989ed5088a2Svporpo   dumpCommonSuffix(OS);
990ed5088a2Svporpo }
991ed5088a2Svporpo 
992ed5088a2Svporpo void CmpInst::dump() const {
993ed5088a2Svporpo   dumpOS(dbgs());
994ed5088a2Svporpo   dbgs() << "\n";
995ed5088a2Svporpo }
996ed5088a2Svporpo #endif // NDEBUG
997ed5088a2Svporpo 
998eba106d4Svporpo static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) {
999eba106d4Svporpo   switch (Opc) {
1000eba106d4Svporpo   case Instruction::Opcode::ZExt:
1001eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
1002eba106d4Svporpo   case Instruction::Opcode::SExt:
1003eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
1004eba106d4Svporpo   case Instruction::Opcode::FPToUI:
1005eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
1006eba106d4Svporpo   case Instruction::Opcode::FPToSI:
1007eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
1008eba106d4Svporpo   case Instruction::Opcode::FPExt:
1009eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
1010eba106d4Svporpo   case Instruction::Opcode::PtrToInt:
1011eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
1012eba106d4Svporpo   case Instruction::Opcode::IntToPtr:
1013eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
1014eba106d4Svporpo   case Instruction::Opcode::SIToFP:
1015eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
1016eba106d4Svporpo   case Instruction::Opcode::UIToFP:
1017eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
1018eba106d4Svporpo   case Instruction::Opcode::Trunc:
1019eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
1020eba106d4Svporpo   case Instruction::Opcode::FPTrunc:
1021eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
1022eba106d4Svporpo   case Instruction::Opcode::BitCast:
1023eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
1024eba106d4Svporpo   case Instruction::Opcode::AddrSpaceCast:
1025eba106d4Svporpo     return static_cast<llvm::Instruction::CastOps>(
1026eba106d4Svporpo         llvm::Instruction::AddrSpaceCast);
1027eba106d4Svporpo   default:
1028eba106d4Svporpo     llvm_unreachable("Opcode not suitable for CastInst!");
1029eba106d4Svporpo   }
1030eba106d4Svporpo }
1031eba106d4Svporpo 
1032eba106d4Svporpo /// \Returns the LLVM opcode that corresponds to \p Opc.
1033eba106d4Svporpo static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc) {
1034eba106d4Svporpo   switch (Opc) {
1035eba106d4Svporpo   case Instruction::Opcode::FNeg:
1036eba106d4Svporpo     return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);
1037eba106d4Svporpo   default:
1038eba106d4Svporpo     llvm_unreachable("Not a unary op!");
1039eba106d4Svporpo   }
1040eba106d4Svporpo }
1041eba106d4Svporpo 
1042eba106d4Svporpo CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB,
1043eba106d4Svporpo                                          unsigned NumHandlers,
10444f3a0959Svporpo                                          InsertPosition Pos, Context &Ctx,
1045eba106d4Svporpo                                          const Twine &Name) {
10464f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
1047eba106d4Svporpo   llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(
1048eba106d4Svporpo       ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);
1049eba106d4Svporpo   return Ctx.createCatchSwitchInst(LLVMCSI);
1050eba106d4Svporpo }
1051eba106d4Svporpo 
1052eba106d4Svporpo Value *CatchSwitchInst::getParentPad() const {
1053eba106d4Svporpo   return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad());
1054eba106d4Svporpo }
1055eba106d4Svporpo 
1056eba106d4Svporpo void CatchSwitchInst::setParentPad(Value *ParentPad) {
1057eba106d4Svporpo   Ctx.getTracker()
1058eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad,
1059eba106d4Svporpo                                        &CatchSwitchInst::setParentPad>>(this);
1060eba106d4Svporpo   cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);
1061eba106d4Svporpo }
1062eba106d4Svporpo 
1063eba106d4Svporpo BasicBlock *CatchSwitchInst::getUnwindDest() const {
1064eba106d4Svporpo   return cast_or_null<BasicBlock>(
1065eba106d4Svporpo       Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));
1066eba106d4Svporpo }
1067eba106d4Svporpo 
1068eba106d4Svporpo void CatchSwitchInst::setUnwindDest(BasicBlock *UnwindDest) {
1069eba106d4Svporpo   Ctx.getTracker()
1070eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getUnwindDest,
1071eba106d4Svporpo                                        &CatchSwitchInst::setUnwindDest>>(this);
1072eba106d4Svporpo   cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(
1073eba106d4Svporpo       cast<llvm::BasicBlock>(UnwindDest->Val));
1074eba106d4Svporpo }
1075eba106d4Svporpo 
1076eba106d4Svporpo void CatchSwitchInst::addHandler(BasicBlock *Dest) {
1077eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this);
1078eba106d4Svporpo   cast<llvm::CatchSwitchInst>(Val)->addHandler(
1079eba106d4Svporpo       cast<llvm::BasicBlock>(Dest->Val));
1080eba106d4Svporpo }
1081eba106d4Svporpo 
10824f3a0959Svporpo ResumeInst *ResumeInst::create(Value *Exn, InsertPosition Pos, Context &Ctx) {
10834f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
1084eba106d4Svporpo   auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
1085eba106d4Svporpo   return Ctx.createResumeInst(LLVMI);
1086eba106d4Svporpo }
1087eba106d4Svporpo 
1088eba106d4Svporpo Value *ResumeInst::getValue() const {
1089eba106d4Svporpo   return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
1090eba106d4Svporpo }
1091eba106d4Svporpo 
1092eba106d4Svporpo SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
10934f3a0959Svporpo                                InsertPosition Pos, Context &Ctx,
1094eba106d4Svporpo                                const Twine &Name) {
10954f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
1096eba106d4Svporpo   llvm::SwitchInst *LLVMSwitch =
1097eba106d4Svporpo       Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
1098eba106d4Svporpo   return Ctx.createSwitchInst(LLVMSwitch);
1099eba106d4Svporpo }
1100eba106d4Svporpo 
1101eba106d4Svporpo Value *SwitchInst::getCondition() const {
1102eba106d4Svporpo   return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
1103eba106d4Svporpo }
1104eba106d4Svporpo 
1105eba106d4Svporpo void SwitchInst::setCondition(Value *V) {
1106eba106d4Svporpo   Ctx.getTracker()
1107eba106d4Svporpo       .emplaceIfTracking<
1108eba106d4Svporpo           GenericSetter<&SwitchInst::getCondition, &SwitchInst::setCondition>>(
1109eba106d4Svporpo           this);
1110eba106d4Svporpo   cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
1111eba106d4Svporpo }
1112eba106d4Svporpo 
1113eba106d4Svporpo BasicBlock *SwitchInst::getDefaultDest() const {
1114eba106d4Svporpo   return cast<BasicBlock>(
1115eba106d4Svporpo       Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
1116eba106d4Svporpo }
1117eba106d4Svporpo 
1118eba106d4Svporpo void SwitchInst::setDefaultDest(BasicBlock *DefaultCase) {
1119eba106d4Svporpo   Ctx.getTracker()
1120eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest,
1121eba106d4Svporpo                                        &SwitchInst::setDefaultDest>>(this);
1122eba106d4Svporpo   cast<llvm::SwitchInst>(Val)->setDefaultDest(
1123eba106d4Svporpo       cast<llvm::BasicBlock>(DefaultCase->Val));
1124eba106d4Svporpo }
1125eba106d4Svporpo ConstantInt *SwitchInst::findCaseDest(BasicBlock *BB) {
1126eba106d4Svporpo   auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
1127eba106d4Svporpo       cast<llvm::BasicBlock>(BB->Val));
1128eba106d4Svporpo   return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
1129eba106d4Svporpo }
1130eba106d4Svporpo 
1131eba106d4Svporpo void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
1132eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal);
1133eba106d4Svporpo   // TODO: Track this!
1134eba106d4Svporpo   cast<llvm::SwitchInst>(Val)->addCase(cast<llvm::ConstantInt>(OnVal->Val),
1135eba106d4Svporpo                                        cast<llvm::BasicBlock>(Dest->Val));
1136eba106d4Svporpo }
1137eba106d4Svporpo 
1138eba106d4Svporpo SwitchInst::CaseIt SwitchInst::removeCase(CaseIt It) {
11399d85ba57SJorge Gorbe Moya   Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this);
1140eba106d4Svporpo 
1141eba106d4Svporpo   auto *LLVMSwitch = cast<llvm::SwitchInst>(Val);
1142eba106d4Svporpo   unsigned CaseNum = It - case_begin();
1143eba106d4Svporpo   llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
1144eba106d4Svporpo   auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
1145eba106d4Svporpo   unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
1146eba106d4Svporpo   return CaseIt(this, Num);
1147eba106d4Svporpo }
1148eba106d4Svporpo 
1149eba106d4Svporpo BasicBlock *SwitchInst::getSuccessor(unsigned Idx) const {
1150eba106d4Svporpo   return cast<BasicBlock>(
1151eba106d4Svporpo       Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
1152eba106d4Svporpo }
1153eba106d4Svporpo 
1154eba106d4Svporpo void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1155eba106d4Svporpo   Ctx.getTracker()
1156eba106d4Svporpo       .emplaceIfTracking<GenericSetterWithIdx<&SwitchInst::getSuccessor,
1157eba106d4Svporpo                                               &SwitchInst::setSuccessor>>(this,
1158eba106d4Svporpo                                                                           Idx);
1159eba106d4Svporpo   cast<llvm::SwitchInst>(Val)->setSuccessor(
1160eba106d4Svporpo       Idx, cast<llvm::BasicBlock>(NewSucc->Val));
1161eba106d4Svporpo }
1162eba106d4Svporpo 
1163eba106d4Svporpo Value *UnaryOperator::create(Instruction::Opcode Op, Value *OpV,
11644f3a0959Svporpo                              InsertPosition Pos, Context &Ctx,
11654f3a0959Svporpo                              const Twine &Name) {
11664f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
1167eba106d4Svporpo   auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
1168eba106d4Svporpo   if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
1169eba106d4Svporpo     return Ctx.createUnaryOperator(NewUnOpV);
1170eba106d4Svporpo   }
1171eba106d4Svporpo   assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
1172eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
1173eba106d4Svporpo }
1174eba106d4Svporpo 
1175eba106d4Svporpo Value *UnaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *OpV,
11764f3a0959Svporpo                                             Value *CopyFrom, InsertPosition Pos,
11774f3a0959Svporpo                                             Context &Ctx, const Twine &Name) {
11784f3a0959Svporpo   auto *NewV = create(Op, OpV, Pos, Ctx, Name);
1179eba106d4Svporpo   if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
1180eba106d4Svporpo     UnI->copyIRFlags(CopyFrom->Val);
1181eba106d4Svporpo   return NewV;
1182eba106d4Svporpo }
1183eba106d4Svporpo 
1184eba106d4Svporpo /// \Returns the LLVM opcode that corresponds to \p Opc.
1185eba106d4Svporpo static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc) {
1186eba106d4Svporpo   switch (Opc) {
1187eba106d4Svporpo   case Instruction::Opcode::Add:
1188eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
1189eba106d4Svporpo   case Instruction::Opcode::FAdd:
1190eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
1191eba106d4Svporpo   case Instruction::Opcode::Sub:
1192eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
1193eba106d4Svporpo   case Instruction::Opcode::FSub:
1194eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
1195eba106d4Svporpo   case Instruction::Opcode::Mul:
1196eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
1197eba106d4Svporpo   case Instruction::Opcode::FMul:
1198eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
1199eba106d4Svporpo   case Instruction::Opcode::UDiv:
1200eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
1201eba106d4Svporpo   case Instruction::Opcode::SDiv:
1202eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
1203eba106d4Svporpo   case Instruction::Opcode::FDiv:
1204eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
1205eba106d4Svporpo   case Instruction::Opcode::URem:
1206eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
1207eba106d4Svporpo   case Instruction::Opcode::SRem:
1208eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
1209eba106d4Svporpo   case Instruction::Opcode::FRem:
1210eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
1211eba106d4Svporpo   case Instruction::Opcode::Shl:
1212eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
1213eba106d4Svporpo   case Instruction::Opcode::LShr:
1214eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
1215eba106d4Svporpo   case Instruction::Opcode::AShr:
1216eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
1217eba106d4Svporpo   case Instruction::Opcode::And:
1218eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
1219eba106d4Svporpo   case Instruction::Opcode::Or:
1220eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
1221eba106d4Svporpo   case Instruction::Opcode::Xor:
1222eba106d4Svporpo     return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
1223eba106d4Svporpo   default:
1224eba106d4Svporpo     llvm_unreachable("Not a binary op!");
1225eba106d4Svporpo   }
1226eba106d4Svporpo }
1227eba106d4Svporpo Value *BinaryOperator::create(Instruction::Opcode Op, Value *LHS, Value *RHS,
12284f3a0959Svporpo                               InsertPosition Pos, Context &Ctx,
12294f3a0959Svporpo                               const Twine &Name) {
12304f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
1231eba106d4Svporpo   llvm::Value *NewV =
1232eba106d4Svporpo       Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name);
1233eba106d4Svporpo   if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
1234eba106d4Svporpo     return Ctx.createBinaryOperator(NewBinOp);
1235eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1236eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1237eba106d4Svporpo }
1238eba106d4Svporpo 
1239eba106d4Svporpo Value *BinaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *LHS,
1240eba106d4Svporpo                                              Value *RHS, Value *CopyFrom,
12414f3a0959Svporpo                                              InsertPosition Pos, Context &Ctx,
1242eba106d4Svporpo                                              const Twine &Name) {
1243eba106d4Svporpo 
12444f3a0959Svporpo   Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name);
1245eba106d4Svporpo   if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
1246eba106d4Svporpo     cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
1247eba106d4Svporpo   return NewV;
1248eba106d4Svporpo }
1249eba106d4Svporpo 
1250eba106d4Svporpo void PossiblyDisjointInst::setIsDisjoint(bool B) {
1251eba106d4Svporpo   Ctx.getTracker()
1252eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&PossiblyDisjointInst::isDisjoint,
1253eba106d4Svporpo                                        &PossiblyDisjointInst::setIsDisjoint>>(
1254eba106d4Svporpo           this);
1255eba106d4Svporpo   cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B);
1256eba106d4Svporpo }
1257eba106d4Svporpo 
1258eba106d4Svporpo void AtomicRMWInst::setAlignment(Align Align) {
1259eba106d4Svporpo   Ctx.getTracker()
1260eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign,
1261eba106d4Svporpo                                        &AtomicRMWInst::setAlignment>>(this);
1262eba106d4Svporpo   cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
1263eba106d4Svporpo }
1264eba106d4Svporpo 
1265eba106d4Svporpo void AtomicRMWInst::setVolatile(bool V) {
1266eba106d4Svporpo   Ctx.getTracker()
1267eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile,
1268eba106d4Svporpo                                        &AtomicRMWInst::setVolatile>>(this);
1269eba106d4Svporpo   cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
1270eba106d4Svporpo }
1271eba106d4Svporpo 
1272eba106d4Svporpo void AtomicRMWInst::setOrdering(AtomicOrdering Ordering) {
1273eba106d4Svporpo   Ctx.getTracker()
1274eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering,
1275eba106d4Svporpo                                        &AtomicRMWInst::setOrdering>>(this);
1276eba106d4Svporpo   cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
1277eba106d4Svporpo }
1278eba106d4Svporpo 
1279eba106d4Svporpo void AtomicRMWInst::setSyncScopeID(SyncScope::ID SSID) {
1280eba106d4Svporpo   Ctx.getTracker()
1281eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getSyncScopeID,
1282eba106d4Svporpo                                        &AtomicRMWInst::setSyncScopeID>>(this);
1283eba106d4Svporpo   cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);
1284eba106d4Svporpo }
1285eba106d4Svporpo 
1286eba106d4Svporpo Value *AtomicRMWInst::getPointerOperand() {
1287eba106d4Svporpo   return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getPointerOperand());
1288eba106d4Svporpo }
1289eba106d4Svporpo 
1290eba106d4Svporpo Value *AtomicRMWInst::getValOperand() {
1291eba106d4Svporpo   return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getValOperand());
1292eba106d4Svporpo }
1293eba106d4Svporpo 
1294eba106d4Svporpo AtomicRMWInst *AtomicRMWInst::create(BinOp Op, Value *Ptr, Value *Val,
1295eba106d4Svporpo                                      MaybeAlign Align, AtomicOrdering Ordering,
12964f3a0959Svporpo                                      InsertPosition Pos, Context &Ctx,
12974f3a0959Svporpo                                      SyncScope::ID SSID, const Twine &Name) {
12984f3a0959Svporpo   auto &Builder = setInsertPos(Pos);
1299eba106d4Svporpo   auto *LLVMAtomicRMW =
1300eba106d4Svporpo       Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
1301eba106d4Svporpo   LLVMAtomicRMW->setName(Name);
1302eba106d4Svporpo   return Ctx.createAtomicRMWInst(LLVMAtomicRMW);
1303eba106d4Svporpo }
1304eba106d4Svporpo 
1305eba106d4Svporpo void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID) {
1306eba106d4Svporpo   Ctx.getTracker()
1307eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID,
1308eba106d4Svporpo                                        &AtomicCmpXchgInst::setSyncScopeID>>(
1309eba106d4Svporpo           this);
1310eba106d4Svporpo   cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
1311eba106d4Svporpo }
1312eba106d4Svporpo 
1313eba106d4Svporpo Value *AtomicCmpXchgInst::getPointerOperand() {
1314eba106d4Svporpo   return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());
1315eba106d4Svporpo }
1316eba106d4Svporpo 
1317eba106d4Svporpo Value *AtomicCmpXchgInst::getCompareOperand() {
1318eba106d4Svporpo   return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());
1319eba106d4Svporpo }
1320eba106d4Svporpo 
1321eba106d4Svporpo Value *AtomicCmpXchgInst::getNewValOperand() {
1322eba106d4Svporpo   return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
1323eba106d4Svporpo }
1324eba106d4Svporpo 
1325eba106d4Svporpo AtomicCmpXchgInst *
1326eba106d4Svporpo AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
1327eba106d4Svporpo                           AtomicOrdering SuccessOrdering,
1328c029702fSvporpo                           AtomicOrdering FailureOrdering, InsertPosition Pos,
1329c029702fSvporpo                           Context &Ctx, SyncScope::ID SSID, const Twine &Name) {
1330c029702fSvporpo   auto &Builder = setInsertPos(Pos);
1331eba106d4Svporpo   auto *LLVMAtomicCmpXchg =
1332eba106d4Svporpo       Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
1333eba106d4Svporpo                                   SuccessOrdering, FailureOrdering, SSID);
1334eba106d4Svporpo   LLVMAtomicCmpXchg->setName(Name);
1335eba106d4Svporpo   return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
1336eba106d4Svporpo }
1337eba106d4Svporpo 
1338eba106d4Svporpo void AtomicCmpXchgInst::setAlignment(Align Align) {
1339eba106d4Svporpo   Ctx.getTracker()
1340eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
1341eba106d4Svporpo                                        &AtomicCmpXchgInst::setAlignment>>(this);
1342eba106d4Svporpo   cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
1343eba106d4Svporpo }
1344eba106d4Svporpo 
1345eba106d4Svporpo void AtomicCmpXchgInst::setVolatile(bool V) {
1346eba106d4Svporpo   Ctx.getTracker()
1347eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
1348eba106d4Svporpo                                        &AtomicCmpXchgInst::setVolatile>>(this);
1349eba106d4Svporpo   cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
1350eba106d4Svporpo }
1351eba106d4Svporpo 
1352eba106d4Svporpo void AtomicCmpXchgInst::setWeak(bool IsWeak) {
1353eba106d4Svporpo   Ctx.getTracker()
1354eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
1355eba106d4Svporpo                                        &AtomicCmpXchgInst::setWeak>>(this);
1356eba106d4Svporpo   cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
1357eba106d4Svporpo }
1358eba106d4Svporpo 
1359eba106d4Svporpo void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering) {
1360eba106d4Svporpo   Ctx.getTracker()
1361eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
1362eba106d4Svporpo                                        &AtomicCmpXchgInst::setSuccessOrdering>>(
1363eba106d4Svporpo           this);
1364eba106d4Svporpo   cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
1365eba106d4Svporpo }
1366eba106d4Svporpo 
1367eba106d4Svporpo void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering) {
1368eba106d4Svporpo   Ctx.getTracker()
1369eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering,
1370eba106d4Svporpo                                        &AtomicCmpXchgInst::setFailureOrdering>>(
1371eba106d4Svporpo           this);
1372eba106d4Svporpo   cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
1373eba106d4Svporpo }
1374eba106d4Svporpo 
1375c029702fSvporpo AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,
1376c029702fSvporpo                                Context &Ctx, Value *ArraySize,
1377c029702fSvporpo                                const Twine &Name) {
1378c029702fSvporpo   auto &Builder = setInsertPos(Pos);
1379eba106d4Svporpo   auto *NewAlloca =
1380eba106d4Svporpo       Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name);
1381eba106d4Svporpo   return Ctx.createAllocaInst(NewAlloca);
1382eba106d4Svporpo }
1383eba106d4Svporpo 
1384eba106d4Svporpo Type *AllocaInst::getAllocatedType() const {
1385eba106d4Svporpo   return Ctx.getType(cast<llvm::AllocaInst>(Val)->getAllocatedType());
1386eba106d4Svporpo }
1387eba106d4Svporpo 
1388eba106d4Svporpo void AllocaInst::setAllocatedType(Type *Ty) {
1389eba106d4Svporpo   Ctx.getTracker()
1390eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType,
1391eba106d4Svporpo                                        &AllocaInst::setAllocatedType>>(this);
1392eba106d4Svporpo   cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy);
1393eba106d4Svporpo }
1394eba106d4Svporpo 
1395eba106d4Svporpo void AllocaInst::setAlignment(Align Align) {
1396eba106d4Svporpo   Ctx.getTracker()
1397eba106d4Svporpo       .emplaceIfTracking<
1398eba106d4Svporpo           GenericSetter<&AllocaInst::getAlign, &AllocaInst::setAlignment>>(
1399eba106d4Svporpo           this);
1400eba106d4Svporpo   cast<llvm::AllocaInst>(Val)->setAlignment(Align);
1401eba106d4Svporpo }
1402eba106d4Svporpo 
1403eba106d4Svporpo void AllocaInst::setUsedWithInAlloca(bool V) {
1404eba106d4Svporpo   Ctx.getTracker()
1405eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&AllocaInst::isUsedWithInAlloca,
1406eba106d4Svporpo                                        &AllocaInst::setUsedWithInAlloca>>(this);
1407eba106d4Svporpo   cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
1408eba106d4Svporpo }
1409eba106d4Svporpo 
1410eba106d4Svporpo Value *AllocaInst::getArraySize() {
1411eba106d4Svporpo   return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
1412eba106d4Svporpo }
1413eba106d4Svporpo 
1414eba106d4Svporpo PointerType *AllocaInst::getType() const {
1415eba106d4Svporpo   return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType()));
1416eba106d4Svporpo }
1417eba106d4Svporpo 
1418eba106d4Svporpo Value *CastInst::create(Type *DestTy, Opcode Op, Value *Operand,
1419c029702fSvporpo                         InsertPosition Pos, Context &Ctx, const Twine &Name) {
1420eba106d4Svporpo   assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
1421c029702fSvporpo   auto &Builder = setInsertPos(Pos);
1422eba106d4Svporpo   auto *NewV =
1423eba106d4Svporpo       Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name);
1424eba106d4Svporpo   if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
1425eba106d4Svporpo     return Ctx.createCastInst(NewCI);
1426eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1427eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1428eba106d4Svporpo }
1429eba106d4Svporpo 
1430eba106d4Svporpo bool CastInst::classof(const Value *From) {
1431eba106d4Svporpo   return From->getSubclassID() == ClassID::Cast;
1432eba106d4Svporpo }
1433eba106d4Svporpo 
1434eba106d4Svporpo Type *CastInst::getSrcTy() const {
1435eba106d4Svporpo   return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy());
1436eba106d4Svporpo }
1437eba106d4Svporpo 
1438eba106d4Svporpo Type *CastInst::getDestTy() const {
1439eba106d4Svporpo   return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy());
1440eba106d4Svporpo }
1441eba106d4Svporpo 
1442eba106d4Svporpo void PossiblyNonNegInst::setNonNeg(bool B) {
1443eba106d4Svporpo   Ctx.getTracker()
1444eba106d4Svporpo       .emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,
1445eba106d4Svporpo                                        &PossiblyNonNegInst::setNonNeg>>(this);
1446eba106d4Svporpo   cast<llvm::PossiblyNonNegInst>(Val)->setNonNeg(B);
1447eba106d4Svporpo }
1448eba106d4Svporpo 
1449eba106d4Svporpo Value *InsertElementInst::create(Value *Vec, Value *NewElt, Value *Idx,
1450635db5eeSvporpo                                  InsertPosition Pos, Context &Ctx,
1451eba106d4Svporpo                                  const Twine &Name) {
1452635db5eeSvporpo   auto &Builder = Instruction::setInsertPos(Pos);
1453eba106d4Svporpo   llvm::Value *NewV =
1454eba106d4Svporpo       Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
1455eba106d4Svporpo   if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
1456eba106d4Svporpo     return Ctx.createInsertElementInst(NewInsert);
1457eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1458eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1459eba106d4Svporpo }
1460eba106d4Svporpo 
1461e1434a87Svporpo Value *ExtractElementInst::create(Value *Vec, Value *Idx, InsertPosition Pos,
1462e1434a87Svporpo                                   Context &Ctx, const Twine &Name) {
1463e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
1464eba106d4Svporpo   llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
1465eba106d4Svporpo   if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
1466eba106d4Svporpo     return Ctx.createExtractElementInst(NewExtract);
1467eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1468eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1469eba106d4Svporpo }
1470eba106d4Svporpo 
1471eba106d4Svporpo Value *ShuffleVectorInst::create(Value *V1, Value *V2, Value *Mask,
1472e1434a87Svporpo                                  InsertPosition Pos, Context &Ctx,
1473eba106d4Svporpo                                  const Twine &Name) {
1474e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
1475eba106d4Svporpo   llvm::Value *NewV =
1476eba106d4Svporpo       Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, Name);
1477eba106d4Svporpo   if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1478eba106d4Svporpo     return Ctx.createShuffleVectorInst(NewShuffle);
1479eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1480eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1481eba106d4Svporpo }
1482eba106d4Svporpo 
1483eba106d4Svporpo Value *ShuffleVectorInst::create(Value *V1, Value *V2, ArrayRef<int> Mask,
1484e1434a87Svporpo                                  InsertPosition Pos, Context &Ctx,
1485eba106d4Svporpo                                  const Twine &Name) {
1486e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
1487eba106d4Svporpo   llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name);
1488eba106d4Svporpo   if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
1489eba106d4Svporpo     return Ctx.createShuffleVectorInst(NewShuffle);
1490eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1491eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1492eba106d4Svporpo }
1493eba106d4Svporpo 
1494eba106d4Svporpo void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {
1495eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1496eba106d4Svporpo   cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask);
1497eba106d4Svporpo }
1498eba106d4Svporpo 
1499eba106d4Svporpo VectorType *ShuffleVectorInst::getType() const {
1500eba106d4Svporpo   return cast<VectorType>(
1501eba106d4Svporpo       Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType()));
1502eba106d4Svporpo }
1503eba106d4Svporpo 
1504eba106d4Svporpo void ShuffleVectorInst::commute() {
1505eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
1506eba106d4Svporpo   Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0),
1507eba106d4Svporpo                                               getOperandUse(1));
1508eba106d4Svporpo   cast<llvm::ShuffleVectorInst>(Val)->commute();
1509eba106d4Svporpo }
1510eba106d4Svporpo 
1511eba106d4Svporpo Constant *ShuffleVectorInst::getShuffleMaskForBitcode() const {
1512eba106d4Svporpo   return Ctx.getOrCreateConstant(
1513eba106d4Svporpo       cast<llvm::ShuffleVectorInst>(Val)->getShuffleMaskForBitcode());
1514eba106d4Svporpo }
1515eba106d4Svporpo 
1516eba106d4Svporpo Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask,
1517eba106d4Svporpo                                                           Type *ResultTy) {
1518eba106d4Svporpo   return ResultTy->getContext().getOrCreateConstant(
1519eba106d4Svporpo       llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask,
1520eba106d4Svporpo                                                             ResultTy->LLVMTy));
1521eba106d4Svporpo }
1522eba106d4Svporpo 
1523eba106d4Svporpo VectorType *ExtractElementInst::getVectorOperandType() const {
1524eba106d4Svporpo   return cast<VectorType>(Ctx.getType(getVectorOperand()->getType()->LLVMTy));
1525eba106d4Svporpo }
1526eba106d4Svporpo 
1527eba106d4Svporpo Value *ExtractValueInst::create(Value *Agg, ArrayRef<unsigned> Idxs,
1528e1434a87Svporpo                                 InsertPosition Pos, Context &Ctx,
1529e1434a87Svporpo                                 const Twine &Name) {
1530e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
1531eba106d4Svporpo   llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);
1532eba106d4Svporpo   if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
1533eba106d4Svporpo     return Ctx.createExtractValueInst(NewExtractValueInst);
1534eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1535eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1536eba106d4Svporpo }
1537eba106d4Svporpo 
1538eba106d4Svporpo Type *ExtractValueInst::getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) {
1539eba106d4Svporpo   auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs);
1540eba106d4Svporpo   return Agg->getContext().getType(LLVMTy);
1541eba106d4Svporpo }
1542eba106d4Svporpo 
1543eba106d4Svporpo Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
1544e1434a87Svporpo                                InsertPosition Pos, Context &Ctx,
1545e1434a87Svporpo                                const Twine &Name) {
1546e1434a87Svporpo   auto &Builder = setInsertPos(Pos);
1547eba106d4Svporpo   llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
1548eba106d4Svporpo   if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
1549eba106d4Svporpo     return Ctx.createInsertValueInst(NewInsertValueInst);
1550eba106d4Svporpo   assert(isa<llvm::Constant>(NewV) && "Expected constant");
1551eba106d4Svporpo   return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
1552eba106d4Svporpo }
1553eba106d4Svporpo 
1554eba106d4Svporpo ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
1555eba106d4Svporpo   auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
1556eba106d4Svporpo   return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
1557eba106d4Svporpo }
1558eba106d4Svporpo 
1559eba106d4Svporpo } // namespace llvm::sandboxir
1560