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