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