1 //===- Instruction.cpp - The Instructions of Sandbox IR -------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/SandboxIR/Instruction.h"
10 #include "llvm/SandboxIR/Function.h"
12 namespace llvm::sandboxir
{
14 const char *Instruction::getOpcodeName(Opcode Opc
) {
19 #define OPCODES(...) __VA_ARGS__
20 #define DEF_INSTR(ID, OPC, CLASS) OPC
21 #include "llvm/SandboxIR/Values.def"
23 llvm_unreachable("Unknown Opcode");
26 llvm::Instruction
*Instruction::getTopmostLLVMInstruction() const {
27 Instruction
*Prev
= getPrevNode();
28 if (Prev
== nullptr) {
29 // If at top of the BB, return the first BB instruction.
30 return &*cast
<llvm::BasicBlock
>(getParent()->Val
)->begin();
32 // Else get the Previous sandbox IR instruction's bottom IR instruction and
33 // return its successor.
34 llvm::Instruction
*PrevBotI
= cast
<llvm::Instruction
>(Prev
->Val
);
35 return PrevBotI
->getNextNode();
38 BBIterator
Instruction::getIterator() const {
39 auto *I
= cast
<llvm::Instruction
>(Val
);
40 return BasicBlock::iterator(I
->getParent(), I
->getIterator(), &Ctx
);
43 Instruction
*Instruction::getNextNode() const {
44 assert(getParent() != nullptr && "Detached!");
45 assert(getIterator() != getParent()->end() && "Already at end!");
46 // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
47 // and get the corresponding sandboxir Instruction that maps to it. This works
48 // even for SandboxIR Instructions that map to more than one LLVM Instruction.
49 auto *LLVMI
= cast
<llvm::Instruction
>(Val
);
50 assert(LLVMI
->getParent() != nullptr && "LLVM IR instr is detached!");
51 auto *NextLLVMI
= LLVMI
->getNextNode();
52 auto *NextI
= cast_or_null
<Instruction
>(Ctx
.getValue(NextLLVMI
));
58 Instruction
*Instruction::getPrevNode() const {
59 assert(getParent() != nullptr && "Detached!");
60 auto It
= getIterator();
61 if (It
!= getParent()->begin())
62 return std::prev(getIterator()).get();
66 void Instruction::removeFromParent() {
67 Ctx
.getTracker().emplaceIfTracking
<RemoveFromParent
>(this);
69 // Detach all the LLVM IR instructions from their parent BB.
70 for (llvm::Instruction
*I
: getLLVMInstrs())
71 I
->removeFromParent();
74 void Instruction::eraseFromParent() {
75 assert(users().empty() && "Still connected to users, can't erase!");
77 Ctx
.runEraseInstrCallbacks(this);
78 std::unique_ptr
<Value
> Detached
= Ctx
.detach(this);
79 auto LLVMInstrs
= getLLVMInstrs();
81 auto &Tracker
= Ctx
.getTracker();
82 if (Tracker
.isTracking()) {
83 Tracker
.track(std::make_unique
<EraseFromParent
>(std::move(Detached
)));
84 // We don't actually delete the IR instruction, because then it would be
85 // impossible to bring it back from the dead at the same memory location.
86 // Instead we remove it from its BB and track its current location.
87 for (llvm::Instruction
*I
: LLVMInstrs
)
88 I
->removeFromParent();
89 // TODO: Multi-instructions need special treatment because some of the
90 // references are internal to the instruction.
91 for (llvm::Instruction
*I
: LLVMInstrs
)
92 I
->dropAllReferences();
94 // Erase in reverse to avoid erasing nstructions with attached uses.
95 for (llvm::Instruction
*I
: reverse(LLVMInstrs
))
100 void Instruction::moveBefore(BasicBlock
&BB
, const BBIterator
&WhereIt
) {
101 if (std::next(getIterator()) == WhereIt
)
102 // Destination is same as origin, nothing to do.
105 Ctx
.runMoveInstrCallbacks(this, WhereIt
);
106 Ctx
.getTracker().emplaceIfTracking
<MoveInstr
>(this);
108 auto *LLVMBB
= cast
<llvm::BasicBlock
>(BB
.Val
);
109 llvm::BasicBlock::iterator It
;
110 if (WhereIt
== BB
.end()) {
113 Instruction
*WhereI
= &*WhereIt
;
114 It
= WhereI
->getTopmostLLVMInstruction()->getIterator();
116 // TODO: Move this to the verifier of sandboxir::Instruction.
117 assert(is_sorted(getLLVMInstrs(),
118 [](auto *I1
, auto *I2
) { return I1
->comesBefore(I2
); }) &&
119 "Expected program order!");
120 // Do the actual move in LLVM IR.
121 for (auto *I
: getLLVMInstrs())
122 I
->moveBefore(*LLVMBB
, It
);
125 void Instruction::insertBefore(Instruction
*BeforeI
) {
126 llvm::Instruction
*BeforeTopI
= BeforeI
->getTopmostLLVMInstruction();
128 Ctx
.getTracker().emplaceIfTracking
<InsertIntoBB
>(this);
130 // Insert the LLVM IR Instructions in program order.
131 for (llvm::Instruction
*I
: getLLVMInstrs())
132 I
->insertBefore(BeforeTopI
);
135 void Instruction::insertAfter(Instruction
*AfterI
) {
136 insertInto(AfterI
->getParent(), std::next(AfterI
->getIterator()));
139 void Instruction::insertInto(BasicBlock
*BB
, const BBIterator
&WhereIt
) {
140 llvm::BasicBlock
*LLVMBB
= cast
<llvm::BasicBlock
>(BB
->Val
);
141 llvm::Instruction
*LLVMBeforeI
;
142 llvm::BasicBlock::iterator LLVMBeforeIt
;
143 Instruction
*BeforeI
;
144 if (WhereIt
!= BB
->end()) {
146 LLVMBeforeI
= BeforeI
->getTopmostLLVMInstruction();
147 LLVMBeforeIt
= LLVMBeforeI
->getIterator();
150 LLVMBeforeI
= nullptr;
151 LLVMBeforeIt
= LLVMBB
->end();
154 Ctx
.getTracker().emplaceIfTracking
<InsertIntoBB
>(this);
156 // Insert the LLVM IR Instructions in program order.
157 for (llvm::Instruction
*I
: getLLVMInstrs())
158 I
->insertInto(LLVMBB
, LLVMBeforeIt
);
161 BasicBlock
*Instruction::getParent() const {
162 // Get the LLVM IR Instruction that this maps to, get its parent, and get the
163 // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
164 auto *BB
= cast
<llvm::Instruction
>(Val
)->getParent();
167 return cast
<BasicBlock
>(Ctx
.getValue(BB
));
170 bool Instruction::classof(const sandboxir::Value
*From
) {
171 switch (From
->getSubclassID()) {
172 #define DEF_INSTR(ID, OPC, CLASS) \
175 #include "llvm/SandboxIR/Values.def"
181 void Instruction::setHasNoUnsignedWrap(bool B
) {
183 .emplaceIfTracking
<GenericSetter
<&Instruction::hasNoUnsignedWrap
,
184 &Instruction::setHasNoUnsignedWrap
>>(
186 cast
<llvm::Instruction
>(Val
)->setHasNoUnsignedWrap(B
);
189 void Instruction::setHasNoSignedWrap(bool B
) {
191 .emplaceIfTracking
<GenericSetter
<&Instruction::hasNoSignedWrap
,
192 &Instruction::setHasNoSignedWrap
>>(this);
193 cast
<llvm::Instruction
>(Val
)->setHasNoSignedWrap(B
);
196 void Instruction::setFast(bool B
) {
199 GenericSetter
<&Instruction::isFast
, &Instruction::setFast
>>(this);
200 cast
<llvm::Instruction
>(Val
)->setFast(B
);
203 void Instruction::setIsExact(bool B
) {
206 GenericSetter
<&Instruction::isExact
, &Instruction::setIsExact
>>(this);
207 cast
<llvm::Instruction
>(Val
)->setIsExact(B
);
210 void Instruction::setHasAllowReassoc(bool B
) {
212 .emplaceIfTracking
<GenericSetter
<&Instruction::hasAllowReassoc
,
213 &Instruction::setHasAllowReassoc
>>(this);
214 cast
<llvm::Instruction
>(Val
)->setHasAllowReassoc(B
);
217 void Instruction::setHasNoNaNs(bool B
) {
220 GenericSetter
<&Instruction::hasNoNaNs
, &Instruction::setHasNoNaNs
>>(
222 cast
<llvm::Instruction
>(Val
)->setHasNoNaNs(B
);
225 void Instruction::setHasNoInfs(bool B
) {
228 GenericSetter
<&Instruction::hasNoInfs
, &Instruction::setHasNoInfs
>>(
230 cast
<llvm::Instruction
>(Val
)->setHasNoInfs(B
);
233 void Instruction::setHasNoSignedZeros(bool B
) {
235 .emplaceIfTracking
<GenericSetter
<&Instruction::hasNoSignedZeros
,
236 &Instruction::setHasNoSignedZeros
>>(
238 cast
<llvm::Instruction
>(Val
)->setHasNoSignedZeros(B
);
241 void Instruction::setHasAllowReciprocal(bool B
) {
243 .emplaceIfTracking
<GenericSetter
<&Instruction::hasAllowReciprocal
,
244 &Instruction::setHasAllowReciprocal
>>(
246 cast
<llvm::Instruction
>(Val
)->setHasAllowReciprocal(B
);
249 void Instruction::setHasAllowContract(bool B
) {
251 .emplaceIfTracking
<GenericSetter
<&Instruction::hasAllowContract
,
252 &Instruction::setHasAllowContract
>>(
254 cast
<llvm::Instruction
>(Val
)->setHasAllowContract(B
);
257 void Instruction::setFastMathFlags(FastMathFlags FMF
) {
259 .emplaceIfTracking
<GenericSetter
<&Instruction::getFastMathFlags
,
260 &Instruction::copyFastMathFlags
>>(this);
261 cast
<llvm::Instruction
>(Val
)->setFastMathFlags(FMF
);
264 void Instruction::copyFastMathFlags(FastMathFlags FMF
) {
266 .emplaceIfTracking
<GenericSetter
<&Instruction::getFastMathFlags
,
267 &Instruction::copyFastMathFlags
>>(this);
268 cast
<llvm::Instruction
>(Val
)->copyFastMathFlags(FMF
);
271 Type
*Instruction::getAccessType() const {
272 return Ctx
.getType(cast
<llvm::Instruction
>(Val
)->getAccessType());
275 void Instruction::setHasApproxFunc(bool B
) {
277 .emplaceIfTracking
<GenericSetter
<&Instruction::hasApproxFunc
,
278 &Instruction::setHasApproxFunc
>>(this);
279 cast
<llvm::Instruction
>(Val
)->setHasApproxFunc(B
);
283 void Instruction::dumpOS(raw_ostream
&OS
) const {
284 OS
<< "Unimplemented! Please override dump().";
288 VAArgInst
*VAArgInst::create(Value
*List
, Type
*Ty
, InsertPosition Pos
,
289 Context
&Ctx
, const Twine
&Name
) {
290 auto &Builder
= setInsertPos(Pos
);
292 cast
<llvm::VAArgInst
>(Builder
.CreateVAArg(List
->Val
, Ty
->LLVMTy
, Name
));
293 return Ctx
.createVAArgInst(LLVMI
);
296 Value
*VAArgInst::getPointerOperand() {
297 return Ctx
.getValue(cast
<llvm::VAArgInst
>(Val
)->getPointerOperand());
300 FreezeInst
*FreezeInst::create(Value
*V
, InsertPosition Pos
, Context
&Ctx
,
302 auto &Builder
= setInsertPos(Pos
);
303 auto *LLVMI
= cast
<llvm::FreezeInst
>(Builder
.CreateFreeze(V
->Val
, Name
));
304 return Ctx
.createFreezeInst(LLVMI
);
307 FenceInst
*FenceInst::create(AtomicOrdering Ordering
, InsertPosition Pos
,
308 Context
&Ctx
, SyncScope::ID SSID
) {
309 auto &Builder
= Instruction::setInsertPos(Pos
);
310 llvm::FenceInst
*LLVMI
= Builder
.CreateFence(Ordering
, SSID
);
311 return Ctx
.createFenceInst(LLVMI
);
314 void FenceInst::setOrdering(AtomicOrdering Ordering
) {
317 GenericSetter
<&FenceInst::getOrdering
, &FenceInst::setOrdering
>>(
319 cast
<llvm::FenceInst
>(Val
)->setOrdering(Ordering
);
322 void FenceInst::setSyncScopeID(SyncScope::ID SSID
) {
324 .emplaceIfTracking
<GenericSetter
<&FenceInst::getSyncScopeID
,
325 &FenceInst::setSyncScopeID
>>(this);
326 cast
<llvm::FenceInst
>(Val
)->setSyncScopeID(SSID
);
329 Value
*SelectInst::create(Value
*Cond
, Value
*True
, Value
*False
,
330 InsertPosition Pos
, Context
&Ctx
, const Twine
&Name
) {
331 auto &Builder
= Instruction::setInsertPos(Pos
);
333 Builder
.CreateSelect(Cond
->Val
, True
->Val
, False
->Val
, Name
);
334 if (auto *NewSI
= dyn_cast
<llvm::SelectInst
>(NewV
))
335 return Ctx
.createSelectInst(NewSI
);
336 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
337 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
340 void SelectInst::swapValues() {
341 Ctx
.getTracker().emplaceIfTracking
<UseSwap
>(getOperandUse(1),
343 cast
<llvm::SelectInst
>(Val
)->swapValues();
346 bool SelectInst::classof(const Value
*From
) {
347 return From
->getSubclassID() == ClassID::Select
;
350 BranchInst
*BranchInst::create(BasicBlock
*IfTrue
, InsertPosition Pos
,
352 auto &Builder
= setInsertPos(Pos
);
353 llvm::BranchInst
*NewBr
=
354 Builder
.CreateBr(cast
<llvm::BasicBlock
>(IfTrue
->Val
));
355 return Ctx
.createBranchInst(NewBr
);
358 BranchInst
*BranchInst::create(BasicBlock
*IfTrue
, BasicBlock
*IfFalse
,
359 Value
*Cond
, InsertPosition Pos
, Context
&Ctx
) {
360 auto &Builder
= setInsertPos(Pos
);
361 llvm::BranchInst
*NewBr
=
362 Builder
.CreateCondBr(Cond
->Val
, cast
<llvm::BasicBlock
>(IfTrue
->Val
),
363 cast
<llvm::BasicBlock
>(IfFalse
->Val
));
364 return Ctx
.createBranchInst(NewBr
);
367 bool BranchInst::classof(const Value
*From
) {
368 return From
->getSubclassID() == ClassID::Br
;
371 Value
*BranchInst::getCondition() const {
372 assert(isConditional() && "Cannot get condition of an uncond branch!");
373 return Ctx
.getValue(cast
<llvm::BranchInst
>(Val
)->getCondition());
376 BasicBlock
*BranchInst::getSuccessor(unsigned SuccIdx
) const {
377 assert(SuccIdx
< getNumSuccessors() &&
378 "Successor # out of range for Branch!");
379 return cast_or_null
<BasicBlock
>(
380 Ctx
.getValue(cast
<llvm::BranchInst
>(Val
)->getSuccessor(SuccIdx
)));
383 void BranchInst::setSuccessor(unsigned Idx
, BasicBlock
*NewSucc
) {
384 assert((Idx
== 0 || Idx
== 1) && "Out of bounds!");
385 setOperand(2u - Idx
, NewSucc
);
388 BasicBlock
*BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock
*BB
) const {
389 return cast
<BasicBlock
>(Ctx
.getValue(BB
));
392 BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock
*BB
) const {
393 return cast
<BasicBlock
>(Ctx
.getValue(BB
));
396 void LoadInst::setVolatile(bool V
) {
399 GenericSetter
<&LoadInst::isVolatile
, &LoadInst::setVolatile
>>(this);
400 cast
<llvm::LoadInst
>(Val
)->setVolatile(V
);
403 LoadInst
*LoadInst::create(Type
*Ty
, Value
*Ptr
, MaybeAlign Align
,
404 InsertPosition Pos
, bool IsVolatile
, Context
&Ctx
,
406 auto &Builder
= setInsertPos(Pos
);
408 Builder
.CreateAlignedLoad(Ty
->LLVMTy
, Ptr
->Val
, Align
, IsVolatile
, Name
);
409 auto *NewSBI
= Ctx
.createLoadInst(NewLI
);
413 bool LoadInst::classof(const Value
*From
) {
414 return From
->getSubclassID() == ClassID::Load
;
417 Value
*LoadInst::getPointerOperand() const {
418 return Ctx
.getValue(cast
<llvm::LoadInst
>(Val
)->getPointerOperand());
421 void StoreInst::setVolatile(bool V
) {
424 GenericSetter
<&StoreInst::isVolatile
, &StoreInst::setVolatile
>>(this);
425 cast
<llvm::StoreInst
>(Val
)->setVolatile(V
);
428 StoreInst
*StoreInst::create(Value
*V
, Value
*Ptr
, MaybeAlign Align
,
429 InsertPosition Pos
, bool IsVolatile
,
431 auto &Builder
= setInsertPos(Pos
);
432 auto *NewSI
= Builder
.CreateAlignedStore(V
->Val
, Ptr
->Val
, Align
, IsVolatile
);
433 auto *NewSBI
= Ctx
.createStoreInst(NewSI
);
437 bool StoreInst::classof(const Value
*From
) {
438 return From
->getSubclassID() == ClassID::Store
;
441 Value
*StoreInst::getValueOperand() const {
442 return Ctx
.getValue(cast
<llvm::StoreInst
>(Val
)->getValueOperand());
445 Value
*StoreInst::getPointerOperand() const {
446 return Ctx
.getValue(cast
<llvm::StoreInst
>(Val
)->getPointerOperand());
449 UnreachableInst
*UnreachableInst::create(InsertPosition Pos
, Context
&Ctx
) {
450 auto &Builder
= setInsertPos(Pos
);
451 llvm::UnreachableInst
*NewUI
= Builder
.CreateUnreachable();
452 return Ctx
.createUnreachableInst(NewUI
);
455 bool UnreachableInst::classof(const Value
*From
) {
456 return From
->getSubclassID() == ClassID::Unreachable
;
459 ReturnInst
*ReturnInst::createCommon(Value
*RetVal
, IRBuilder
<> &Builder
,
461 llvm::ReturnInst
*NewRI
;
462 if (RetVal
!= nullptr)
463 NewRI
= Builder
.CreateRet(RetVal
->Val
);
465 NewRI
= Builder
.CreateRetVoid();
466 return Ctx
.createReturnInst(NewRI
);
469 ReturnInst
*ReturnInst::create(Value
*RetVal
, InsertPosition Pos
,
471 auto &Builder
= setInsertPos(Pos
);
472 return createCommon(RetVal
, Builder
, Ctx
);
475 Value
*ReturnInst::getReturnValue() const {
476 auto *LLVMRetVal
= cast
<llvm::ReturnInst
>(Val
)->getReturnValue();
477 return LLVMRetVal
!= nullptr ? Ctx
.getValue(LLVMRetVal
) : nullptr;
480 FunctionType
*CallBase::getFunctionType() const {
481 return cast
<FunctionType
>(
482 Ctx
.getType(cast
<llvm::CallBase
>(Val
)->getFunctionType()));
485 Value
*CallBase::getCalledOperand() const {
486 return Ctx
.getValue(cast
<llvm::CallBase
>(Val
)->getCalledOperand());
489 Use
CallBase::getCalledOperandUse() const {
490 llvm::Use
*LLVMUse
= &cast
<llvm::CallBase
>(Val
)->getCalledOperandUse();
491 return Use(LLVMUse
, cast
<User
>(Ctx
.getValue(LLVMUse
->getUser())), Ctx
);
494 Function
*CallBase::getCalledFunction() const {
495 return cast_or_null
<Function
>(
496 Ctx
.getValue(cast
<llvm::CallBase
>(Val
)->getCalledFunction()));
498 Function
*CallBase::getCaller() {
499 return cast
<Function
>(Ctx
.getValue(cast
<llvm::CallBase
>(Val
)->getCaller()));
502 void CallBase::setCalledFunction(Function
*F
) {
503 // F's function type is private, so we rely on `setCalledFunction()` to update
504 // it. But even though we are calling `setCalledFunction()` we also need to
505 // track this change at the SandboxIR level, which is why we call
506 // `setCalledOperand()` here.
507 // Note: This may break if `setCalledFunction()` early returns if `F`
508 // is already set, but we do have a unit test for it.
510 cast
<llvm::CallBase
>(Val
)->setCalledFunction(
511 cast
<llvm::FunctionType
>(F
->getFunctionType()->LLVMTy
),
512 cast
<llvm::Function
>(F
->Val
));
515 CallInst
*CallInst::create(FunctionType
*FTy
, Value
*Func
,
516 ArrayRef
<Value
*> Args
, InsertPosition Pos
,
517 Context
&Ctx
, const Twine
&NameStr
) {
518 auto &Builder
= setInsertPos(Pos
);
519 SmallVector
<llvm::Value
*> LLVMArgs
;
520 LLVMArgs
.reserve(Args
.size());
521 for (Value
*Arg
: Args
)
522 LLVMArgs
.push_back(Arg
->Val
);
523 llvm::CallInst
*NewCI
= Builder
.CreateCall(
524 cast
<llvm::FunctionType
>(FTy
->LLVMTy
), Func
->Val
, LLVMArgs
, NameStr
);
525 return Ctx
.createCallInst(NewCI
);
528 InvokeInst
*InvokeInst::create(FunctionType
*FTy
, Value
*Func
,
529 BasicBlock
*IfNormal
, BasicBlock
*IfException
,
530 ArrayRef
<Value
*> Args
, InsertPosition Pos
,
531 Context
&Ctx
, const Twine
&NameStr
) {
532 auto &Builder
= setInsertPos(Pos
);
533 SmallVector
<llvm::Value
*> LLVMArgs
;
534 LLVMArgs
.reserve(Args
.size());
535 for (Value
*Arg
: Args
)
536 LLVMArgs
.push_back(Arg
->Val
);
537 llvm::InvokeInst
*Invoke
= Builder
.CreateInvoke(
538 cast
<llvm::FunctionType
>(FTy
->LLVMTy
), Func
->Val
,
539 cast
<llvm::BasicBlock
>(IfNormal
->Val
),
540 cast
<llvm::BasicBlock
>(IfException
->Val
), LLVMArgs
, NameStr
);
541 return Ctx
.createInvokeInst(Invoke
);
544 BasicBlock
*InvokeInst::getNormalDest() const {
545 return cast
<BasicBlock
>(
546 Ctx
.getValue(cast
<llvm::InvokeInst
>(Val
)->getNormalDest()));
548 BasicBlock
*InvokeInst::getUnwindDest() const {
549 return cast
<BasicBlock
>(
550 Ctx
.getValue(cast
<llvm::InvokeInst
>(Val
)->getUnwindDest()));
552 void InvokeInst::setNormalDest(BasicBlock
*BB
) {
554 assert(getNormalDest() == BB
&& "LLVM IR uses a different operan index!");
556 void InvokeInst::setUnwindDest(BasicBlock
*BB
) {
558 assert(getUnwindDest() == BB
&& "LLVM IR uses a different operan index!");
560 LandingPadInst
*InvokeInst::getLandingPadInst() const {
561 return cast
<LandingPadInst
>(
562 Ctx
.getValue(cast
<llvm::InvokeInst
>(Val
)->getLandingPadInst()));
565 BasicBlock
*InvokeInst::getSuccessor(unsigned SuccIdx
) const {
566 return cast
<BasicBlock
>(
567 Ctx
.getValue(cast
<llvm::InvokeInst
>(Val
)->getSuccessor(SuccIdx
)));
570 CallBrInst
*CallBrInst::create(FunctionType
*FTy
, Value
*Func
,
571 BasicBlock
*DefaultDest
,
572 ArrayRef
<BasicBlock
*> IndirectDests
,
573 ArrayRef
<Value
*> Args
, InsertPosition Pos
,
574 Context
&Ctx
, const Twine
&NameStr
) {
575 auto &Builder
= setInsertPos(Pos
);
576 SmallVector
<llvm::BasicBlock
*> LLVMIndirectDests
;
577 LLVMIndirectDests
.reserve(IndirectDests
.size());
578 for (BasicBlock
*IndDest
: IndirectDests
)
579 LLVMIndirectDests
.push_back(cast
<llvm::BasicBlock
>(IndDest
->Val
));
581 SmallVector
<llvm::Value
*> LLVMArgs
;
582 LLVMArgs
.reserve(Args
.size());
583 for (Value
*Arg
: Args
)
584 LLVMArgs
.push_back(Arg
->Val
);
586 llvm::CallBrInst
*CallBr
=
587 Builder
.CreateCallBr(cast
<llvm::FunctionType
>(FTy
->LLVMTy
), Func
->Val
,
588 cast
<llvm::BasicBlock
>(DefaultDest
->Val
),
589 LLVMIndirectDests
, LLVMArgs
, NameStr
);
590 return Ctx
.createCallBrInst(CallBr
);
593 Value
*CallBrInst::getIndirectDestLabel(unsigned Idx
) const {
594 return Ctx
.getValue(cast
<llvm::CallBrInst
>(Val
)->getIndirectDestLabel(Idx
));
596 Value
*CallBrInst::getIndirectDestLabelUse(unsigned Idx
) const {
598 cast
<llvm::CallBrInst
>(Val
)->getIndirectDestLabelUse(Idx
));
600 BasicBlock
*CallBrInst::getDefaultDest() const {
601 return cast
<BasicBlock
>(
602 Ctx
.getValue(cast
<llvm::CallBrInst
>(Val
)->getDefaultDest()));
604 BasicBlock
*CallBrInst::getIndirectDest(unsigned Idx
) const {
605 return cast
<BasicBlock
>(
606 Ctx
.getValue(cast
<llvm::CallBrInst
>(Val
)->getIndirectDest(Idx
)));
608 llvm::SmallVector
<BasicBlock
*, 16> CallBrInst::getIndirectDests() const {
609 SmallVector
<BasicBlock
*, 16> BBs
;
610 for (llvm::BasicBlock
*LLVMBB
:
611 cast
<llvm::CallBrInst
>(Val
)->getIndirectDests())
612 BBs
.push_back(cast
<BasicBlock
>(Ctx
.getValue(LLVMBB
)));
615 void CallBrInst::setDefaultDest(BasicBlock
*BB
) {
617 .emplaceIfTracking
<GenericSetter
<&CallBrInst::getDefaultDest
,
618 &CallBrInst::setDefaultDest
>>(this);
619 cast
<llvm::CallBrInst
>(Val
)->setDefaultDest(cast
<llvm::BasicBlock
>(BB
->Val
));
621 void CallBrInst::setIndirectDest(unsigned Idx
, BasicBlock
*BB
) {
623 .emplaceIfTracking
<GenericSetterWithIdx
<&CallBrInst::getIndirectDest
,
624 &CallBrInst::setIndirectDest
>>(
626 cast
<llvm::CallBrInst
>(Val
)->setIndirectDest(Idx
,
627 cast
<llvm::BasicBlock
>(BB
->Val
));
629 BasicBlock
*CallBrInst::getSuccessor(unsigned Idx
) const {
630 return cast
<BasicBlock
>(
631 Ctx
.getValue(cast
<llvm::CallBrInst
>(Val
)->getSuccessor(Idx
)));
634 LandingPadInst
*LandingPadInst::create(Type
*RetTy
, unsigned NumReservedClauses
,
635 InsertPosition Pos
, Context
&Ctx
,
637 auto &Builder
= setInsertPos(Pos
);
638 llvm::LandingPadInst
*LLVMI
=
639 Builder
.CreateLandingPad(RetTy
->LLVMTy
, NumReservedClauses
, Name
);
640 return Ctx
.createLandingPadInst(LLVMI
);
643 void LandingPadInst::setCleanup(bool V
) {
645 .emplaceIfTracking
<GenericSetter
<&LandingPadInst::isCleanup
,
646 &LandingPadInst::setCleanup
>>(this);
647 cast
<llvm::LandingPadInst
>(Val
)->setCleanup(V
);
650 Constant
*LandingPadInst::getClause(unsigned Idx
) const {
651 return cast
<Constant
>(
652 Ctx
.getValue(cast
<llvm::LandingPadInst
>(Val
)->getClause(Idx
)));
655 Value
*FuncletPadInst::getParentPad() const {
656 return Ctx
.getValue(cast
<llvm::FuncletPadInst
>(Val
)->getParentPad());
659 void FuncletPadInst::setParentPad(Value
*ParentPad
) {
661 .emplaceIfTracking
<GenericSetter
<&FuncletPadInst::getParentPad
,
662 &FuncletPadInst::setParentPad
>>(this);
663 cast
<llvm::FuncletPadInst
>(Val
)->setParentPad(ParentPad
->Val
);
666 Value
*FuncletPadInst::getArgOperand(unsigned Idx
) const {
667 return Ctx
.getValue(cast
<llvm::FuncletPadInst
>(Val
)->getArgOperand(Idx
));
670 void FuncletPadInst::setArgOperand(unsigned Idx
, Value
*V
) {
672 .emplaceIfTracking
<GenericSetterWithIdx
<&FuncletPadInst::getArgOperand
,
673 &FuncletPadInst::setArgOperand
>>(
675 cast
<llvm::FuncletPadInst
>(Val
)->setArgOperand(Idx
, V
->Val
);
678 CatchSwitchInst
*CatchPadInst::getCatchSwitch() const {
679 return cast
<CatchSwitchInst
>(
680 Ctx
.getValue(cast
<llvm::CatchPadInst
>(Val
)->getCatchSwitch()));
683 CatchPadInst
*CatchPadInst::create(Value
*ParentPad
, ArrayRef
<Value
*> Args
,
684 InsertPosition Pos
, Context
&Ctx
,
686 auto &Builder
= setInsertPos(Pos
);
687 SmallVector
<llvm::Value
*> LLVMArgs
;
688 LLVMArgs
.reserve(Args
.size());
689 for (auto *Arg
: Args
)
690 LLVMArgs
.push_back(Arg
->Val
);
691 llvm::CatchPadInst
*LLVMI
=
692 Builder
.CreateCatchPad(ParentPad
->Val
, LLVMArgs
, Name
);
693 return Ctx
.createCatchPadInst(LLVMI
);
696 CleanupPadInst
*CleanupPadInst::create(Value
*ParentPad
, ArrayRef
<Value
*> Args
,
697 InsertPosition Pos
, Context
&Ctx
,
699 auto &Builder
= setInsertPos(Pos
);
700 SmallVector
<llvm::Value
*> LLVMArgs
;
701 LLVMArgs
.reserve(Args
.size());
702 for (auto *Arg
: Args
)
703 LLVMArgs
.push_back(Arg
->Val
);
704 llvm::CleanupPadInst
*LLVMI
=
705 Builder
.CreateCleanupPad(ParentPad
->Val
, LLVMArgs
, Name
);
706 return Ctx
.createCleanupPadInst(LLVMI
);
709 CatchReturnInst
*CatchReturnInst::create(CatchPadInst
*CatchPad
, BasicBlock
*BB
,
710 InsertPosition Pos
, Context
&Ctx
) {
711 auto &Builder
= setInsertPos(Pos
);
712 llvm::CatchReturnInst
*LLVMI
= Builder
.CreateCatchRet(
713 cast
<llvm::CatchPadInst
>(CatchPad
->Val
), cast
<llvm::BasicBlock
>(BB
->Val
));
714 return Ctx
.createCatchReturnInst(LLVMI
);
717 CatchPadInst
*CatchReturnInst::getCatchPad() const {
718 return cast
<CatchPadInst
>(
719 Ctx
.getValue(cast
<llvm::CatchReturnInst
>(Val
)->getCatchPad()));
722 void CatchReturnInst::setCatchPad(CatchPadInst
*CatchPad
) {
724 .emplaceIfTracking
<GenericSetter
<&CatchReturnInst::getCatchPad
,
725 &CatchReturnInst::setCatchPad
>>(this);
726 cast
<llvm::CatchReturnInst
>(Val
)->setCatchPad(
727 cast
<llvm::CatchPadInst
>(CatchPad
->Val
));
730 BasicBlock
*CatchReturnInst::getSuccessor() const {
731 return cast
<BasicBlock
>(
732 Ctx
.getValue(cast
<llvm::CatchReturnInst
>(Val
)->getSuccessor()));
735 void CatchReturnInst::setSuccessor(BasicBlock
*NewSucc
) {
737 .emplaceIfTracking
<GenericSetter
<&CatchReturnInst::getSuccessor
,
738 &CatchReturnInst::setSuccessor
>>(this);
739 cast
<llvm::CatchReturnInst
>(Val
)->setSuccessor(
740 cast
<llvm::BasicBlock
>(NewSucc
->Val
));
743 Value
*CatchReturnInst::getCatchSwitchParentPad() const {
745 cast
<llvm::CatchReturnInst
>(Val
)->getCatchSwitchParentPad());
748 CleanupReturnInst
*CleanupReturnInst::create(CleanupPadInst
*CleanupPad
,
749 BasicBlock
*UnwindBB
,
750 InsertPosition Pos
, Context
&Ctx
) {
751 auto &Builder
= setInsertPos(Pos
);
753 UnwindBB
!= nullptr ? cast
<llvm::BasicBlock
>(UnwindBB
->Val
) : nullptr;
754 llvm::CleanupReturnInst
*LLVMI
= Builder
.CreateCleanupRet(
755 cast
<llvm::CleanupPadInst
>(CleanupPad
->Val
), LLVMUnwindBB
);
756 return Ctx
.createCleanupReturnInst(LLVMI
);
759 CleanupPadInst
*CleanupReturnInst::getCleanupPad() const {
760 return cast
<CleanupPadInst
>(
761 Ctx
.getValue(cast
<llvm::CleanupReturnInst
>(Val
)->getCleanupPad()));
764 void CleanupReturnInst::setCleanupPad(CleanupPadInst
*CleanupPad
) {
766 .emplaceIfTracking
<GenericSetter
<&CleanupReturnInst::getCleanupPad
,
767 &CleanupReturnInst::setCleanupPad
>>(
769 cast
<llvm::CleanupReturnInst
>(Val
)->setCleanupPad(
770 cast
<llvm::CleanupPadInst
>(CleanupPad
->Val
));
773 BasicBlock
*CleanupReturnInst::getUnwindDest() const {
774 return cast_or_null
<BasicBlock
>(
775 Ctx
.getValue(cast
<llvm::CleanupReturnInst
>(Val
)->getUnwindDest()));
778 void CleanupReturnInst::setUnwindDest(BasicBlock
*NewDest
) {
780 .emplaceIfTracking
<GenericSetter
<&CleanupReturnInst::getUnwindDest
,
781 &CleanupReturnInst::setUnwindDest
>>(
783 cast
<llvm::CleanupReturnInst
>(Val
)->setUnwindDest(
784 cast
<llvm::BasicBlock
>(NewDest
->Val
));
787 Value
*GetElementPtrInst::create(Type
*Ty
, Value
*Ptr
,
788 ArrayRef
<Value
*> IdxList
, InsertPosition Pos
,
789 Context
&Ctx
, const Twine
&NameStr
) {
790 auto &Builder
= setInsertPos(Pos
);
791 SmallVector
<llvm::Value
*> LLVMIdxList
;
792 LLVMIdxList
.reserve(IdxList
.size());
793 for (Value
*Idx
: IdxList
)
794 LLVMIdxList
.push_back(Idx
->Val
);
796 Builder
.CreateGEP(Ty
->LLVMTy
, Ptr
->Val
, LLVMIdxList
, NameStr
);
797 if (auto *NewGEP
= dyn_cast
<llvm::GetElementPtrInst
>(NewV
))
798 return Ctx
.createGetElementPtrInst(NewGEP
);
799 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
800 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
803 Type
*GetElementPtrInst::getSourceElementType() const {
805 cast
<llvm::GetElementPtrInst
>(Val
)->getSourceElementType());
808 Type
*GetElementPtrInst::getResultElementType() const {
810 cast
<llvm::GetElementPtrInst
>(Val
)->getResultElementType());
813 Value
*GetElementPtrInst::getPointerOperand() const {
814 return Ctx
.getValue(cast
<llvm::GetElementPtrInst
>(Val
)->getPointerOperand());
817 Type
*GetElementPtrInst::getPointerOperandType() const {
819 cast
<llvm::GetElementPtrInst
>(Val
)->getPointerOperandType());
822 BasicBlock
*PHINode::LLVMBBToBB::operator()(llvm::BasicBlock
*LLVMBB
) const {
823 return cast
<BasicBlock
>(Ctx
.getValue(LLVMBB
));
826 PHINode
*PHINode::create(Type
*Ty
, unsigned NumReservedValues
,
827 InsertPosition Pos
, Context
&Ctx
, const Twine
&Name
) {
828 auto &Builder
= setInsertPos(Pos
);
829 llvm::PHINode
*NewPHI
=
830 Builder
.CreatePHI(Ty
->LLVMTy
, NumReservedValues
, Name
);
831 return Ctx
.createPHINode(NewPHI
);
834 bool PHINode::classof(const Value
*From
) {
835 return From
->getSubclassID() == ClassID::PHI
;
838 Value
*PHINode::getIncomingValue(unsigned Idx
) const {
839 return Ctx
.getValue(cast
<llvm::PHINode
>(Val
)->getIncomingValue(Idx
));
841 void PHINode::setIncomingValue(unsigned Idx
, Value
*V
) {
843 .emplaceIfTracking
<GenericSetterWithIdx
<&PHINode::getIncomingValue
,
844 &PHINode::setIncomingValue
>>(this,
846 cast
<llvm::PHINode
>(Val
)->setIncomingValue(Idx
, V
->Val
);
848 BasicBlock
*PHINode::getIncomingBlock(unsigned Idx
) const {
849 return cast
<BasicBlock
>(
850 Ctx
.getValue(cast
<llvm::PHINode
>(Val
)->getIncomingBlock(Idx
)));
852 BasicBlock
*PHINode::getIncomingBlock(const Use
&U
) const {
853 llvm::Use
*LLVMUse
= U
.LLVMUse
;
854 llvm::BasicBlock
*BB
= cast
<llvm::PHINode
>(Val
)->getIncomingBlock(*LLVMUse
);
855 return cast
<BasicBlock
>(Ctx
.getValue(BB
));
857 void PHINode::setIncomingBlock(unsigned Idx
, BasicBlock
*BB
) {
858 // Helper to disambiguate PHINode::getIncomingBlock(unsigned).
859 constexpr BasicBlock
*(PHINode::*GetIncomingBlockFn
)(unsigned) const =
860 &PHINode::getIncomingBlock
;
863 GenericSetterWithIdx
<GetIncomingBlockFn
, &PHINode::setIncomingBlock
>>(
865 cast
<llvm::PHINode
>(Val
)->setIncomingBlock(Idx
,
866 cast
<llvm::BasicBlock
>(BB
->Val
));
868 void PHINode::addIncoming(Value
*V
, BasicBlock
*BB
) {
869 auto &Tracker
= Ctx
.getTracker();
870 Tracker
.emplaceIfTracking
<PHIAddIncoming
>(this);
872 cast
<llvm::PHINode
>(Val
)->addIncoming(V
->Val
,
873 cast
<llvm::BasicBlock
>(BB
->Val
));
875 Value
*PHINode::removeIncomingValue(unsigned Idx
) {
876 auto &Tracker
= Ctx
.getTracker();
877 Tracker
.emplaceIfTracking
<PHIRemoveIncoming
>(this, Idx
);
879 cast
<llvm::PHINode
>(Val
)->removeIncomingValue(Idx
,
880 /*DeletePHIIfEmpty=*/false);
881 return Ctx
.getValue(LLVMV
);
883 Value
*PHINode::removeIncomingValue(BasicBlock
*BB
) {
884 auto &Tracker
= Ctx
.getTracker();
885 Tracker
.emplaceIfTracking
<PHIRemoveIncoming
>(this, getBasicBlockIndex(BB
));
887 auto *LLVMBB
= cast
<llvm::BasicBlock
>(BB
->Val
);
889 cast
<llvm::PHINode
>(Val
)->removeIncomingValue(LLVMBB
,
890 /*DeletePHIIfEmpty=*/false);
891 return Ctx
.getValue(LLVMV
);
893 int PHINode::getBasicBlockIndex(const BasicBlock
*BB
) const {
894 auto *LLVMBB
= cast
<llvm::BasicBlock
>(BB
->Val
);
895 return cast
<llvm::PHINode
>(Val
)->getBasicBlockIndex(LLVMBB
);
897 Value
*PHINode::getIncomingValueForBlock(const BasicBlock
*BB
) const {
898 auto *LLVMBB
= cast
<llvm::BasicBlock
>(BB
->Val
);
900 cast
<llvm::PHINode
>(Val
)->getIncomingValueForBlock(LLVMBB
);
901 return Ctx
.getValue(LLVMV
);
903 Value
*PHINode::hasConstantValue() const {
904 llvm::Value
*LLVMV
= cast
<llvm::PHINode
>(Val
)->hasConstantValue();
905 return LLVMV
!= nullptr ? Ctx
.getValue(LLVMV
) : nullptr;
907 void PHINode::replaceIncomingBlockWith(const BasicBlock
*Old
, BasicBlock
*New
) {
908 assert(New
&& Old
&& "Sandbox IR PHI node got a null basic block!");
909 for (unsigned Idx
= 0, NumOps
= cast
<llvm::PHINode
>(Val
)->getNumOperands();
910 Idx
!= NumOps
; ++Idx
)
911 if (getIncomingBlock(Idx
) == Old
)
912 setIncomingBlock(Idx
, New
);
914 void PHINode::removeIncomingValueIf(function_ref
<bool(unsigned)> Predicate
) {
915 // Avoid duplicate tracking by going through this->removeIncomingValue here at
916 // the expense of some performance. Copy PHI::removeIncomingValueIf more
917 // directly if performance becomes an issue.
919 // Removing the element at index X, moves the element previously at X + 1
920 // to X. Working from the end avoids complications from that.
921 unsigned Idx
= getNumIncomingValues();
923 if (Predicate(Idx
- 1))
924 removeIncomingValue(Idx
- 1);
929 Value
*CmpInst::create(Predicate P
, Value
*S1
, Value
*S2
, InsertPosition Pos
,
930 Context
&Ctx
, const Twine
&Name
) {
931 auto &Builder
= setInsertPos(Pos
);
932 auto *LLVMV
= Builder
.CreateCmp(P
, S1
->Val
, S2
->Val
, Name
);
933 // It may have been folded into a constant.
934 if (auto *LLVMC
= dyn_cast
<llvm::Constant
>(LLVMV
))
935 return Ctx
.getOrCreateConstant(LLVMC
);
936 if (isa
<llvm::ICmpInst
>(LLVMV
))
937 return Ctx
.createICmpInst(cast
<llvm::ICmpInst
>(LLVMV
));
938 return Ctx
.createFCmpInst(cast
<llvm::FCmpInst
>(LLVMV
));
941 Value
*CmpInst::createWithCopiedFlags(Predicate P
, Value
*S1
, Value
*S2
,
942 const Instruction
*F
, InsertPosition Pos
,
943 Context
&Ctx
, const Twine
&Name
) {
944 Value
*V
= create(P
, S1
, S2
, Pos
, Ctx
, Name
);
945 if (auto *C
= dyn_cast
<Constant
>(V
))
947 cast
<llvm::CmpInst
>(V
->Val
)->copyIRFlags(F
->Val
);
951 Type
*CmpInst::makeCmpResultType(Type
*OpndType
) {
952 if (auto *VT
= dyn_cast
<VectorType
>(OpndType
)) {
953 // TODO: Cleanup when we have more complete support for
954 // sandboxir::VectorType
955 return OpndType
->getContext().getType(llvm::VectorType::get(
956 llvm::Type::getInt1Ty(OpndType
->getContext().LLVMCtx
),
957 cast
<llvm::VectorType
>(VT
->LLVMTy
)->getElementCount()));
959 return Type::getInt1Ty(OpndType
->getContext());
962 void CmpInst::setPredicate(Predicate P
) {
965 GenericSetter
<&CmpInst::getPredicate
, &CmpInst::setPredicate
>>(this);
966 cast
<llvm::CmpInst
>(Val
)->setPredicate(P
);
969 void CmpInst::swapOperands() {
970 if (ICmpInst
*IC
= dyn_cast
<ICmpInst
>(this))
973 cast
<FCmpInst
>(this)->swapOperands();
976 void ICmpInst::swapOperands() {
977 Ctx
.getTracker().emplaceIfTracking
<CmpSwapOperands
>(this);
978 cast
<llvm::ICmpInst
>(Val
)->swapOperands();
981 void FCmpInst::swapOperands() {
982 Ctx
.getTracker().emplaceIfTracking
<CmpSwapOperands
>(this);
983 cast
<llvm::FCmpInst
>(Val
)->swapOperands();
987 void CmpInst::dumpOS(raw_ostream
&OS
) const {
988 dumpCommonPrefix(OS
);
989 dumpCommonSuffix(OS
);
992 void CmpInst::dump() const {
998 static llvm::Instruction::CastOps
getLLVMCastOp(Instruction::Opcode Opc
) {
1000 case Instruction::Opcode::ZExt
:
1001 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::ZExt
);
1002 case Instruction::Opcode::SExt
:
1003 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::SExt
);
1004 case Instruction::Opcode::FPToUI
:
1005 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::FPToUI
);
1006 case Instruction::Opcode::FPToSI
:
1007 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::FPToSI
);
1008 case Instruction::Opcode::FPExt
:
1009 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::FPExt
);
1010 case Instruction::Opcode::PtrToInt
:
1011 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::PtrToInt
);
1012 case Instruction::Opcode::IntToPtr
:
1013 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::IntToPtr
);
1014 case Instruction::Opcode::SIToFP
:
1015 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::SIToFP
);
1016 case Instruction::Opcode::UIToFP
:
1017 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::UIToFP
);
1018 case Instruction::Opcode::Trunc
:
1019 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::Trunc
);
1020 case Instruction::Opcode::FPTrunc
:
1021 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::FPTrunc
);
1022 case Instruction::Opcode::BitCast
:
1023 return static_cast<llvm::Instruction::CastOps
>(llvm::Instruction::BitCast
);
1024 case Instruction::Opcode::AddrSpaceCast
:
1025 return static_cast<llvm::Instruction::CastOps
>(
1026 llvm::Instruction::AddrSpaceCast
);
1028 llvm_unreachable("Opcode not suitable for CastInst!");
1032 /// \Returns the LLVM opcode that corresponds to \p Opc.
1033 static llvm::Instruction::UnaryOps
getLLVMUnaryOp(Instruction::Opcode Opc
) {
1035 case Instruction::Opcode::FNeg
:
1036 return static_cast<llvm::Instruction::UnaryOps
>(llvm::Instruction::FNeg
);
1038 llvm_unreachable("Not a unary op!");
1042 CatchSwitchInst
*CatchSwitchInst::create(Value
*ParentPad
, BasicBlock
*UnwindBB
,
1043 unsigned NumHandlers
,
1044 InsertPosition Pos
, Context
&Ctx
,
1045 const Twine
&Name
) {
1046 auto &Builder
= setInsertPos(Pos
);
1047 llvm::CatchSwitchInst
*LLVMCSI
= Builder
.CreateCatchSwitch(
1048 ParentPad
->Val
, cast
<llvm::BasicBlock
>(UnwindBB
->Val
), NumHandlers
, Name
);
1049 return Ctx
.createCatchSwitchInst(LLVMCSI
);
1052 Value
*CatchSwitchInst::getParentPad() const {
1053 return Ctx
.getValue(cast
<llvm::CatchSwitchInst
>(Val
)->getParentPad());
1056 void CatchSwitchInst::setParentPad(Value
*ParentPad
) {
1058 .emplaceIfTracking
<GenericSetter
<&CatchSwitchInst::getParentPad
,
1059 &CatchSwitchInst::setParentPad
>>(this);
1060 cast
<llvm::CatchSwitchInst
>(Val
)->setParentPad(ParentPad
->Val
);
1063 BasicBlock
*CatchSwitchInst::getUnwindDest() const {
1064 return cast_or_null
<BasicBlock
>(
1065 Ctx
.getValue(cast
<llvm::CatchSwitchInst
>(Val
)->getUnwindDest()));
1068 void CatchSwitchInst::setUnwindDest(BasicBlock
*UnwindDest
) {
1070 .emplaceIfTracking
<GenericSetter
<&CatchSwitchInst::getUnwindDest
,
1071 &CatchSwitchInst::setUnwindDest
>>(this);
1072 cast
<llvm::CatchSwitchInst
>(Val
)->setUnwindDest(
1073 cast
<llvm::BasicBlock
>(UnwindDest
->Val
));
1076 void CatchSwitchInst::addHandler(BasicBlock
*Dest
) {
1077 Ctx
.getTracker().emplaceIfTracking
<CatchSwitchAddHandler
>(this);
1078 cast
<llvm::CatchSwitchInst
>(Val
)->addHandler(
1079 cast
<llvm::BasicBlock
>(Dest
->Val
));
1082 ResumeInst
*ResumeInst::create(Value
*Exn
, InsertPosition Pos
, Context
&Ctx
) {
1083 auto &Builder
= setInsertPos(Pos
);
1084 auto *LLVMI
= cast
<llvm::ResumeInst
>(Builder
.CreateResume(Exn
->Val
));
1085 return Ctx
.createResumeInst(LLVMI
);
1088 Value
*ResumeInst::getValue() const {
1089 return Ctx
.getValue(cast
<llvm::ResumeInst
>(Val
)->getValue());
1092 SwitchInst
*SwitchInst::create(Value
*V
, BasicBlock
*Dest
, unsigned NumCases
,
1093 InsertPosition Pos
, Context
&Ctx
,
1094 const Twine
&Name
) {
1095 auto &Builder
= setInsertPos(Pos
);
1096 llvm::SwitchInst
*LLVMSwitch
=
1097 Builder
.CreateSwitch(V
->Val
, cast
<llvm::BasicBlock
>(Dest
->Val
), NumCases
);
1098 return Ctx
.createSwitchInst(LLVMSwitch
);
1101 Value
*SwitchInst::getCondition() const {
1102 return Ctx
.getValue(cast
<llvm::SwitchInst
>(Val
)->getCondition());
1105 void SwitchInst::setCondition(Value
*V
) {
1108 GenericSetter
<&SwitchInst::getCondition
, &SwitchInst::setCondition
>>(
1110 cast
<llvm::SwitchInst
>(Val
)->setCondition(V
->Val
);
1113 BasicBlock
*SwitchInst::getDefaultDest() const {
1114 return cast
<BasicBlock
>(
1115 Ctx
.getValue(cast
<llvm::SwitchInst
>(Val
)->getDefaultDest()));
1118 void SwitchInst::setDefaultDest(BasicBlock
*DefaultCase
) {
1120 .emplaceIfTracking
<GenericSetter
<&SwitchInst::getDefaultDest
,
1121 &SwitchInst::setDefaultDest
>>(this);
1122 cast
<llvm::SwitchInst
>(Val
)->setDefaultDest(
1123 cast
<llvm::BasicBlock
>(DefaultCase
->Val
));
1125 ConstantInt
*SwitchInst::findCaseDest(BasicBlock
*BB
) {
1126 auto *LLVMC
= cast
<llvm::SwitchInst
>(Val
)->findCaseDest(
1127 cast
<llvm::BasicBlock
>(BB
->Val
));
1128 return LLVMC
!= nullptr ? cast
<ConstantInt
>(Ctx
.getValue(LLVMC
)) : nullptr;
1131 void SwitchInst::addCase(ConstantInt
*OnVal
, BasicBlock
*Dest
) {
1132 Ctx
.getTracker().emplaceIfTracking
<SwitchAddCase
>(this, OnVal
);
1133 // TODO: Track this!
1134 cast
<llvm::SwitchInst
>(Val
)->addCase(cast
<llvm::ConstantInt
>(OnVal
->Val
),
1135 cast
<llvm::BasicBlock
>(Dest
->Val
));
1138 SwitchInst::CaseIt
SwitchInst::removeCase(CaseIt It
) {
1139 Ctx
.getTracker().emplaceIfTracking
<SwitchRemoveCase
>(this);
1141 auto *LLVMSwitch
= cast
<llvm::SwitchInst
>(Val
);
1142 unsigned CaseNum
= It
- case_begin();
1143 llvm::SwitchInst::CaseIt
LLVMIt(LLVMSwitch
, CaseNum
);
1144 auto LLVMCaseIt
= LLVMSwitch
->removeCase(LLVMIt
);
1145 unsigned Num
= LLVMCaseIt
- LLVMSwitch
->case_begin();
1146 return CaseIt(this, Num
);
1149 BasicBlock
*SwitchInst::getSuccessor(unsigned Idx
) const {
1150 return cast
<BasicBlock
>(
1151 Ctx
.getValue(cast
<llvm::SwitchInst
>(Val
)->getSuccessor(Idx
)));
1154 void SwitchInst::setSuccessor(unsigned Idx
, BasicBlock
*NewSucc
) {
1156 .emplaceIfTracking
<GenericSetterWithIdx
<&SwitchInst::getSuccessor
,
1157 &SwitchInst::setSuccessor
>>(this,
1159 cast
<llvm::SwitchInst
>(Val
)->setSuccessor(
1160 Idx
, cast
<llvm::BasicBlock
>(NewSucc
->Val
));
1163 Value
*UnaryOperator::create(Instruction::Opcode Op
, Value
*OpV
,
1164 InsertPosition Pos
, Context
&Ctx
,
1165 const Twine
&Name
) {
1166 auto &Builder
= setInsertPos(Pos
);
1167 auto *NewLLVMV
= Builder
.CreateUnOp(getLLVMUnaryOp(Op
), OpV
->Val
, Name
);
1168 if (auto *NewUnOpV
= dyn_cast
<llvm::UnaryOperator
>(NewLLVMV
)) {
1169 return Ctx
.createUnaryOperator(NewUnOpV
);
1171 assert(isa
<llvm::Constant
>(NewLLVMV
) && "Expected constant");
1172 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewLLVMV
));
1175 Value
*UnaryOperator::createWithCopiedFlags(Instruction::Opcode Op
, Value
*OpV
,
1176 Value
*CopyFrom
, InsertPosition Pos
,
1177 Context
&Ctx
, const Twine
&Name
) {
1178 auto *NewV
= create(Op
, OpV
, Pos
, Ctx
, Name
);
1179 if (auto *UnI
= dyn_cast
<llvm::UnaryOperator
>(NewV
->Val
))
1180 UnI
->copyIRFlags(CopyFrom
->Val
);
1184 /// \Returns the LLVM opcode that corresponds to \p Opc.
1185 static llvm::Instruction::BinaryOps
getLLVMBinaryOp(Instruction::Opcode Opc
) {
1187 case Instruction::Opcode::Add
:
1188 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::Add
);
1189 case Instruction::Opcode::FAdd
:
1190 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::FAdd
);
1191 case Instruction::Opcode::Sub
:
1192 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::Sub
);
1193 case Instruction::Opcode::FSub
:
1194 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::FSub
);
1195 case Instruction::Opcode::Mul
:
1196 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::Mul
);
1197 case Instruction::Opcode::FMul
:
1198 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::FMul
);
1199 case Instruction::Opcode::UDiv
:
1200 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::UDiv
);
1201 case Instruction::Opcode::SDiv
:
1202 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::SDiv
);
1203 case Instruction::Opcode::FDiv
:
1204 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::FDiv
);
1205 case Instruction::Opcode::URem
:
1206 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::URem
);
1207 case Instruction::Opcode::SRem
:
1208 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::SRem
);
1209 case Instruction::Opcode::FRem
:
1210 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::FRem
);
1211 case Instruction::Opcode::Shl
:
1212 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::Shl
);
1213 case Instruction::Opcode::LShr
:
1214 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::LShr
);
1215 case Instruction::Opcode::AShr
:
1216 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::AShr
);
1217 case Instruction::Opcode::And
:
1218 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::And
);
1219 case Instruction::Opcode::Or
:
1220 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::Or
);
1221 case Instruction::Opcode::Xor
:
1222 return static_cast<llvm::Instruction::BinaryOps
>(llvm::Instruction::Xor
);
1224 llvm_unreachable("Not a binary op!");
1227 Value
*BinaryOperator::create(Instruction::Opcode Op
, Value
*LHS
, Value
*RHS
,
1228 InsertPosition Pos
, Context
&Ctx
,
1229 const Twine
&Name
) {
1230 auto &Builder
= setInsertPos(Pos
);
1232 Builder
.CreateBinOp(getLLVMBinaryOp(Op
), LHS
->Val
, RHS
->Val
, Name
);
1233 if (auto *NewBinOp
= dyn_cast
<llvm::BinaryOperator
>(NewV
))
1234 return Ctx
.createBinaryOperator(NewBinOp
);
1235 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1236 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1239 Value
*BinaryOperator::createWithCopiedFlags(Instruction::Opcode Op
, Value
*LHS
,
1240 Value
*RHS
, Value
*CopyFrom
,
1241 InsertPosition Pos
, Context
&Ctx
,
1242 const Twine
&Name
) {
1244 Value
*NewV
= create(Op
, LHS
, RHS
, Pos
, Ctx
, Name
);
1245 if (auto *NewBO
= dyn_cast
<BinaryOperator
>(NewV
))
1246 cast
<llvm::BinaryOperator
>(NewBO
->Val
)->copyIRFlags(CopyFrom
->Val
);
1250 void PossiblyDisjointInst::setIsDisjoint(bool B
) {
1252 .emplaceIfTracking
<GenericSetter
<&PossiblyDisjointInst::isDisjoint
,
1253 &PossiblyDisjointInst::setIsDisjoint
>>(
1255 cast
<llvm::PossiblyDisjointInst
>(Val
)->setIsDisjoint(B
);
1258 void AtomicRMWInst::setAlignment(Align Align
) {
1260 .emplaceIfTracking
<GenericSetter
<&AtomicRMWInst::getAlign
,
1261 &AtomicRMWInst::setAlignment
>>(this);
1262 cast
<llvm::AtomicRMWInst
>(Val
)->setAlignment(Align
);
1265 void AtomicRMWInst::setVolatile(bool V
) {
1267 .emplaceIfTracking
<GenericSetter
<&AtomicRMWInst::isVolatile
,
1268 &AtomicRMWInst::setVolatile
>>(this);
1269 cast
<llvm::AtomicRMWInst
>(Val
)->setVolatile(V
);
1272 void AtomicRMWInst::setOrdering(AtomicOrdering Ordering
) {
1274 .emplaceIfTracking
<GenericSetter
<&AtomicRMWInst::getOrdering
,
1275 &AtomicRMWInst::setOrdering
>>(this);
1276 cast
<llvm::AtomicRMWInst
>(Val
)->setOrdering(Ordering
);
1279 void AtomicRMWInst::setSyncScopeID(SyncScope::ID SSID
) {
1281 .emplaceIfTracking
<GenericSetter
<&AtomicRMWInst::getSyncScopeID
,
1282 &AtomicRMWInst::setSyncScopeID
>>(this);
1283 cast
<llvm::AtomicRMWInst
>(Val
)->setSyncScopeID(SSID
);
1286 Value
*AtomicRMWInst::getPointerOperand() {
1287 return Ctx
.getValue(cast
<llvm::AtomicRMWInst
>(Val
)->getPointerOperand());
1290 Value
*AtomicRMWInst::getValOperand() {
1291 return Ctx
.getValue(cast
<llvm::AtomicRMWInst
>(Val
)->getValOperand());
1294 AtomicRMWInst
*AtomicRMWInst::create(BinOp Op
, Value
*Ptr
, Value
*Val
,
1295 MaybeAlign Align
, AtomicOrdering Ordering
,
1296 InsertPosition Pos
, Context
&Ctx
,
1297 SyncScope::ID SSID
, const Twine
&Name
) {
1298 auto &Builder
= setInsertPos(Pos
);
1299 auto *LLVMAtomicRMW
=
1300 Builder
.CreateAtomicRMW(Op
, Ptr
->Val
, Val
->Val
, Align
, Ordering
, SSID
);
1301 LLVMAtomicRMW
->setName(Name
);
1302 return Ctx
.createAtomicRMWInst(LLVMAtomicRMW
);
1305 void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID
) {
1307 .emplaceIfTracking
<GenericSetter
<&AtomicCmpXchgInst::getSyncScopeID
,
1308 &AtomicCmpXchgInst::setSyncScopeID
>>(
1310 cast
<llvm::AtomicCmpXchgInst
>(Val
)->setSyncScopeID(SSID
);
1313 Value
*AtomicCmpXchgInst::getPointerOperand() {
1314 return Ctx
.getValue(cast
<llvm::AtomicCmpXchgInst
>(Val
)->getPointerOperand());
1317 Value
*AtomicCmpXchgInst::getCompareOperand() {
1318 return Ctx
.getValue(cast
<llvm::AtomicCmpXchgInst
>(Val
)->getCompareOperand());
1321 Value
*AtomicCmpXchgInst::getNewValOperand() {
1322 return Ctx
.getValue(cast
<llvm::AtomicCmpXchgInst
>(Val
)->getNewValOperand());
1326 AtomicCmpXchgInst::create(Value
*Ptr
, Value
*Cmp
, Value
*New
, MaybeAlign Align
,
1327 AtomicOrdering SuccessOrdering
,
1328 AtomicOrdering FailureOrdering
, InsertPosition Pos
,
1329 Context
&Ctx
, SyncScope::ID SSID
, const Twine
&Name
) {
1330 auto &Builder
= setInsertPos(Pos
);
1331 auto *LLVMAtomicCmpXchg
=
1332 Builder
.CreateAtomicCmpXchg(Ptr
->Val
, Cmp
->Val
, New
->Val
, Align
,
1333 SuccessOrdering
, FailureOrdering
, SSID
);
1334 LLVMAtomicCmpXchg
->setName(Name
);
1335 return Ctx
.createAtomicCmpXchgInst(LLVMAtomicCmpXchg
);
1338 void AtomicCmpXchgInst::setAlignment(Align Align
) {
1340 .emplaceIfTracking
<GenericSetter
<&AtomicCmpXchgInst::getAlign
,
1341 &AtomicCmpXchgInst::setAlignment
>>(this);
1342 cast
<llvm::AtomicCmpXchgInst
>(Val
)->setAlignment(Align
);
1345 void AtomicCmpXchgInst::setVolatile(bool V
) {
1347 .emplaceIfTracking
<GenericSetter
<&AtomicCmpXchgInst::isVolatile
,
1348 &AtomicCmpXchgInst::setVolatile
>>(this);
1349 cast
<llvm::AtomicCmpXchgInst
>(Val
)->setVolatile(V
);
1352 void AtomicCmpXchgInst::setWeak(bool IsWeak
) {
1354 .emplaceIfTracking
<GenericSetter
<&AtomicCmpXchgInst::isWeak
,
1355 &AtomicCmpXchgInst::setWeak
>>(this);
1356 cast
<llvm::AtomicCmpXchgInst
>(Val
)->setWeak(IsWeak
);
1359 void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering
) {
1361 .emplaceIfTracking
<GenericSetter
<&AtomicCmpXchgInst::getSuccessOrdering
,
1362 &AtomicCmpXchgInst::setSuccessOrdering
>>(
1364 cast
<llvm::AtomicCmpXchgInst
>(Val
)->setSuccessOrdering(Ordering
);
1367 void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering
) {
1369 .emplaceIfTracking
<GenericSetter
<&AtomicCmpXchgInst::getFailureOrdering
,
1370 &AtomicCmpXchgInst::setFailureOrdering
>>(
1372 cast
<llvm::AtomicCmpXchgInst
>(Val
)->setFailureOrdering(Ordering
);
1375 AllocaInst
*AllocaInst::create(Type
*Ty
, unsigned AddrSpace
, InsertPosition Pos
,
1376 Context
&Ctx
, Value
*ArraySize
,
1377 const Twine
&Name
) {
1378 auto &Builder
= setInsertPos(Pos
);
1380 Builder
.CreateAlloca(Ty
->LLVMTy
, AddrSpace
, ArraySize
->Val
, Name
);
1381 return Ctx
.createAllocaInst(NewAlloca
);
1384 Type
*AllocaInst::getAllocatedType() const {
1385 return Ctx
.getType(cast
<llvm::AllocaInst
>(Val
)->getAllocatedType());
1388 void AllocaInst::setAllocatedType(Type
*Ty
) {
1390 .emplaceIfTracking
<GenericSetter
<&AllocaInst::getAllocatedType
,
1391 &AllocaInst::setAllocatedType
>>(this);
1392 cast
<llvm::AllocaInst
>(Val
)->setAllocatedType(Ty
->LLVMTy
);
1395 void AllocaInst::setAlignment(Align Align
) {
1398 GenericSetter
<&AllocaInst::getAlign
, &AllocaInst::setAlignment
>>(
1400 cast
<llvm::AllocaInst
>(Val
)->setAlignment(Align
);
1403 void AllocaInst::setUsedWithInAlloca(bool V
) {
1405 .emplaceIfTracking
<GenericSetter
<&AllocaInst::isUsedWithInAlloca
,
1406 &AllocaInst::setUsedWithInAlloca
>>(this);
1407 cast
<llvm::AllocaInst
>(Val
)->setUsedWithInAlloca(V
);
1410 Value
*AllocaInst::getArraySize() {
1411 return Ctx
.getValue(cast
<llvm::AllocaInst
>(Val
)->getArraySize());
1414 PointerType
*AllocaInst::getType() const {
1415 return cast
<PointerType
>(Ctx
.getType(cast
<llvm::AllocaInst
>(Val
)->getType()));
1418 Value
*CastInst::create(Type
*DestTy
, Opcode Op
, Value
*Operand
,
1419 InsertPosition Pos
, Context
&Ctx
, const Twine
&Name
) {
1420 assert(getLLVMCastOp(Op
) && "Opcode not suitable for CastInst!");
1421 auto &Builder
= setInsertPos(Pos
);
1423 Builder
.CreateCast(getLLVMCastOp(Op
), Operand
->Val
, DestTy
->LLVMTy
, Name
);
1424 if (auto *NewCI
= dyn_cast
<llvm::CastInst
>(NewV
))
1425 return Ctx
.createCastInst(NewCI
);
1426 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1427 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1430 bool CastInst::classof(const Value
*From
) {
1431 return From
->getSubclassID() == ClassID::Cast
;
1434 Type
*CastInst::getSrcTy() const {
1435 return Ctx
.getType(cast
<llvm::CastInst
>(Val
)->getSrcTy());
1438 Type
*CastInst::getDestTy() const {
1439 return Ctx
.getType(cast
<llvm::CastInst
>(Val
)->getDestTy());
1442 void PossiblyNonNegInst::setNonNeg(bool B
) {
1444 .emplaceIfTracking
<GenericSetter
<&PossiblyNonNegInst::hasNonNeg
,
1445 &PossiblyNonNegInst::setNonNeg
>>(this);
1446 cast
<llvm::PossiblyNonNegInst
>(Val
)->setNonNeg(B
);
1449 Value
*InsertElementInst::create(Value
*Vec
, Value
*NewElt
, Value
*Idx
,
1450 InsertPosition Pos
, Context
&Ctx
,
1451 const Twine
&Name
) {
1452 auto &Builder
= Instruction::setInsertPos(Pos
);
1454 Builder
.CreateInsertElement(Vec
->Val
, NewElt
->Val
, Idx
->Val
, Name
);
1455 if (auto *NewInsert
= dyn_cast
<llvm::InsertElementInst
>(NewV
))
1456 return Ctx
.createInsertElementInst(NewInsert
);
1457 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1458 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1461 Value
*ExtractElementInst::create(Value
*Vec
, Value
*Idx
, InsertPosition Pos
,
1462 Context
&Ctx
, const Twine
&Name
) {
1463 auto &Builder
= setInsertPos(Pos
);
1464 llvm::Value
*NewV
= Builder
.CreateExtractElement(Vec
->Val
, Idx
->Val
, Name
);
1465 if (auto *NewExtract
= dyn_cast
<llvm::ExtractElementInst
>(NewV
))
1466 return Ctx
.createExtractElementInst(NewExtract
);
1467 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1468 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1471 Value
*ShuffleVectorInst::create(Value
*V1
, Value
*V2
, Value
*Mask
,
1472 InsertPosition Pos
, Context
&Ctx
,
1473 const Twine
&Name
) {
1474 auto &Builder
= setInsertPos(Pos
);
1476 Builder
.CreateShuffleVector(V1
->Val
, V2
->Val
, Mask
->Val
, Name
);
1477 if (auto *NewShuffle
= dyn_cast
<llvm::ShuffleVectorInst
>(NewV
))
1478 return Ctx
.createShuffleVectorInst(NewShuffle
);
1479 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1480 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1483 Value
*ShuffleVectorInst::create(Value
*V1
, Value
*V2
, ArrayRef
<int> Mask
,
1484 InsertPosition Pos
, Context
&Ctx
,
1485 const Twine
&Name
) {
1486 auto &Builder
= setInsertPos(Pos
);
1487 llvm::Value
*NewV
= Builder
.CreateShuffleVector(V1
->Val
, V2
->Val
, Mask
, Name
);
1488 if (auto *NewShuffle
= dyn_cast
<llvm::ShuffleVectorInst
>(NewV
))
1489 return Ctx
.createShuffleVectorInst(NewShuffle
);
1490 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1491 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1494 void ShuffleVectorInst::setShuffleMask(ArrayRef
<int> Mask
) {
1495 Ctx
.getTracker().emplaceIfTracking
<ShuffleVectorSetMask
>(this);
1496 cast
<llvm::ShuffleVectorInst
>(Val
)->setShuffleMask(Mask
);
1499 VectorType
*ShuffleVectorInst::getType() const {
1500 return cast
<VectorType
>(
1501 Ctx
.getType(cast
<llvm::ShuffleVectorInst
>(Val
)->getType()));
1504 void ShuffleVectorInst::commute() {
1505 Ctx
.getTracker().emplaceIfTracking
<ShuffleVectorSetMask
>(this);
1506 Ctx
.getTracker().emplaceIfTracking
<UseSwap
>(getOperandUse(0),
1508 cast
<llvm::ShuffleVectorInst
>(Val
)->commute();
1511 Constant
*ShuffleVectorInst::getShuffleMaskForBitcode() const {
1512 return Ctx
.getOrCreateConstant(
1513 cast
<llvm::ShuffleVectorInst
>(Val
)->getShuffleMaskForBitcode());
1516 Constant
*ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef
<int> Mask
,
1518 return ResultTy
->getContext().getOrCreateConstant(
1519 llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask
,
1523 VectorType
*ExtractElementInst::getVectorOperandType() const {
1524 return cast
<VectorType
>(Ctx
.getType(getVectorOperand()->getType()->LLVMTy
));
1527 Value
*ExtractValueInst::create(Value
*Agg
, ArrayRef
<unsigned> Idxs
,
1528 InsertPosition Pos
, Context
&Ctx
,
1529 const Twine
&Name
) {
1530 auto &Builder
= setInsertPos(Pos
);
1531 llvm::Value
*NewV
= Builder
.CreateExtractValue(Agg
->Val
, Idxs
, Name
);
1532 if (auto *NewExtractValueInst
= dyn_cast
<llvm::ExtractValueInst
>(NewV
))
1533 return Ctx
.createExtractValueInst(NewExtractValueInst
);
1534 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1535 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1538 Type
*ExtractValueInst::getIndexedType(Type
*Agg
, ArrayRef
<unsigned> Idxs
) {
1539 auto *LLVMTy
= llvm::ExtractValueInst::getIndexedType(Agg
->LLVMTy
, Idxs
);
1540 return Agg
->getContext().getType(LLVMTy
);
1543 Value
*InsertValueInst::create(Value
*Agg
, Value
*Val
, ArrayRef
<unsigned> Idxs
,
1544 InsertPosition Pos
, Context
&Ctx
,
1545 const Twine
&Name
) {
1546 auto &Builder
= setInsertPos(Pos
);
1547 llvm::Value
*NewV
= Builder
.CreateInsertValue(Agg
->Val
, Val
->Val
, Idxs
, Name
);
1548 if (auto *NewInsertValueInst
= dyn_cast
<llvm::InsertValueInst
>(NewV
))
1549 return Ctx
.createInsertValueInst(NewInsertValueInst
);
1550 assert(isa
<llvm::Constant
>(NewV
) && "Expected constant");
1551 return Ctx
.getOrCreateConstant(cast
<llvm::Constant
>(NewV
));
1554 ConstantTokenNone
*ConstantTokenNone::get(Context
&Ctx
) {
1555 auto *LLVMC
= llvm::ConstantTokenNone::get(Ctx
.LLVMCtx
);
1556 return cast
<ConstantTokenNone
>(Ctx
.getOrCreateConstant(LLVMC
));
1559 } // namespace llvm::sandboxir