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