File indexing completed on 2026-05-10 08:44:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_IR_INSTRUCTIONS_H
0016 #define LLVM_IR_INSTRUCTIONS_H
0017
0018 #include "llvm/ADT/ArrayRef.h"
0019 #include "llvm/ADT/Bitfields.h"
0020 #include "llvm/ADT/MapVector.h"
0021 #include "llvm/ADT/STLExtras.h"
0022 #include "llvm/ADT/SmallVector.h"
0023 #include "llvm/ADT/Twine.h"
0024 #include "llvm/ADT/iterator.h"
0025 #include "llvm/ADT/iterator_range.h"
0026 #include "llvm/IR/CFG.h"
0027 #include "llvm/IR/CmpPredicate.h"
0028 #include "llvm/IR/Constant.h"
0029 #include "llvm/IR/DerivedTypes.h"
0030 #include "llvm/IR/GEPNoWrapFlags.h"
0031 #include "llvm/IR/InstrTypes.h"
0032 #include "llvm/IR/Instruction.h"
0033 #include "llvm/IR/Intrinsics.h"
0034 #include "llvm/IR/OperandTraits.h"
0035 #include "llvm/IR/Use.h"
0036 #include "llvm/IR/User.h"
0037 #include "llvm/Support/AtomicOrdering.h"
0038 #include "llvm/Support/ErrorHandling.h"
0039 #include <cassert>
0040 #include <cstddef>
0041 #include <cstdint>
0042 #include <iterator>
0043 #include <optional>
0044
0045 namespace llvm {
0046
0047 class APFloat;
0048 class APInt;
0049 class BasicBlock;
0050 class ConstantInt;
0051 class DataLayout;
0052 struct KnownBits;
0053 class StringRef;
0054 class Type;
0055 class Value;
0056 class UnreachableInst;
0057
0058
0059
0060
0061
0062
0063 class AllocaInst : public UnaryInstruction {
0064 Type *AllocatedType;
0065
0066 using AlignmentField = AlignmentBitfieldElementT<0>;
0067 using UsedWithInAllocaField = BoolBitfieldElementT<AlignmentField::NextBit>;
0068 using SwiftErrorField = BoolBitfieldElementT<UsedWithInAllocaField::NextBit>;
0069 static_assert(Bitfield::areContiguous<AlignmentField, UsedWithInAllocaField,
0070 SwiftErrorField>(),
0071 "Bitfields must be contiguous");
0072
0073 protected:
0074
0075 friend class Instruction;
0076
0077 AllocaInst *cloneImpl() const;
0078
0079 public:
0080 explicit AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize,
0081 const Twine &Name, InsertPosition InsertBefore);
0082
0083 AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name,
0084 InsertPosition InsertBefore);
0085
0086 AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, Align Align,
0087 const Twine &Name = "", InsertPosition InsertBefore = nullptr);
0088
0089
0090
0091 bool isArrayAllocation() const;
0092
0093
0094
0095 const Value *getArraySize() const { return getOperand(0); }
0096 Value *getArraySize() { return getOperand(0); }
0097
0098
0099 PointerType *getType() const {
0100 return cast<PointerType>(Instruction::getType());
0101 }
0102
0103
0104 unsigned getAddressSpace() const {
0105 return getType()->getAddressSpace();
0106 }
0107
0108
0109
0110 std::optional<TypeSize> getAllocationSize(const DataLayout &DL) const;
0111
0112
0113
0114 std::optional<TypeSize> getAllocationSizeInBits(const DataLayout &DL) const;
0115
0116
0117 Type *getAllocatedType() const { return AllocatedType; }
0118
0119
0120 void setAllocatedType(Type *Ty) { AllocatedType = Ty; }
0121
0122
0123
0124 Align getAlign() const {
0125 return Align(1ULL << getSubclassData<AlignmentField>());
0126 }
0127
0128 void setAlignment(Align Align) {
0129 setSubclassData<AlignmentField>(Log2(Align));
0130 }
0131
0132
0133
0134
0135 bool isStaticAlloca() const;
0136
0137
0138
0139 bool isUsedWithInAlloca() const {
0140 return getSubclassData<UsedWithInAllocaField>();
0141 }
0142
0143
0144 void setUsedWithInAlloca(bool V) {
0145 setSubclassData<UsedWithInAllocaField>(V);
0146 }
0147
0148
0149 bool isSwiftError() const { return getSubclassData<SwiftErrorField>(); }
0150
0151 void setSwiftError(bool V) { setSubclassData<SwiftErrorField>(V); }
0152
0153
0154 static bool classof(const Instruction *I) {
0155 return (I->getOpcode() == Instruction::Alloca);
0156 }
0157 static bool classof(const Value *V) {
0158 return isa<Instruction>(V) && classof(cast<Instruction>(V));
0159 }
0160
0161 private:
0162
0163
0164 template <typename Bitfield>
0165 void setSubclassData(typename Bitfield::Type Value) {
0166 Instruction::setSubclassData<Bitfield>(Value);
0167 }
0168 };
0169
0170
0171
0172
0173
0174
0175
0176 class LoadInst : public UnaryInstruction {
0177 using VolatileField = BoolBitfieldElementT<0>;
0178 using AlignmentField = AlignmentBitfieldElementT<VolatileField::NextBit>;
0179 using OrderingField = AtomicOrderingBitfieldElementT<AlignmentField::NextBit>;
0180 static_assert(
0181 Bitfield::areContiguous<VolatileField, AlignmentField, OrderingField>(),
0182 "Bitfields must be contiguous");
0183
0184 void AssertOK();
0185
0186 protected:
0187
0188 friend class Instruction;
0189
0190 LoadInst *cloneImpl() const;
0191
0192 public:
0193 LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr,
0194 InsertPosition InsertBefore);
0195 LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
0196 InsertPosition InsertBefore);
0197 LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
0198 Align Align, InsertPosition InsertBefore = nullptr);
0199 LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
0200 Align Align, AtomicOrdering Order,
0201 SyncScope::ID SSID = SyncScope::System,
0202 InsertPosition InsertBefore = nullptr);
0203
0204
0205 bool isVolatile() const { return getSubclassData<VolatileField>(); }
0206
0207
0208 void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
0209
0210
0211 Align getAlign() const {
0212 return Align(1ULL << (getSubclassData<AlignmentField>()));
0213 }
0214
0215 void setAlignment(Align Align) {
0216 setSubclassData<AlignmentField>(Log2(Align));
0217 }
0218
0219
0220 AtomicOrdering getOrdering() const {
0221 return getSubclassData<OrderingField>();
0222 }
0223
0224
0225 void setOrdering(AtomicOrdering Ordering) {
0226 setSubclassData<OrderingField>(Ordering);
0227 }
0228
0229
0230 SyncScope::ID getSyncScopeID() const {
0231 return SSID;
0232 }
0233
0234
0235 void setSyncScopeID(SyncScope::ID SSID) {
0236 this->SSID = SSID;
0237 }
0238
0239
0240
0241 void setAtomic(AtomicOrdering Ordering,
0242 SyncScope::ID SSID = SyncScope::System) {
0243 setOrdering(Ordering);
0244 setSyncScopeID(SSID);
0245 }
0246
0247 bool isSimple() const { return !isAtomic() && !isVolatile(); }
0248
0249 bool isUnordered() const {
0250 return (getOrdering() == AtomicOrdering::NotAtomic ||
0251 getOrdering() == AtomicOrdering::Unordered) &&
0252 !isVolatile();
0253 }
0254
0255 Value *getPointerOperand() { return getOperand(0); }
0256 const Value *getPointerOperand() const { return getOperand(0); }
0257 static unsigned getPointerOperandIndex() { return 0U; }
0258 Type *getPointerOperandType() const { return getPointerOperand()->getType(); }
0259
0260
0261 unsigned getPointerAddressSpace() const {
0262 return getPointerOperandType()->getPointerAddressSpace();
0263 }
0264
0265
0266 static bool classof(const Instruction *I) {
0267 return I->getOpcode() == Instruction::Load;
0268 }
0269 static bool classof(const Value *V) {
0270 return isa<Instruction>(V) && classof(cast<Instruction>(V));
0271 }
0272
0273 private:
0274
0275
0276 template <typename Bitfield>
0277 void setSubclassData(typename Bitfield::Type Value) {
0278 Instruction::setSubclassData<Bitfield>(Value);
0279 }
0280
0281
0282
0283
0284 SyncScope::ID SSID;
0285 };
0286
0287
0288
0289
0290
0291
0292 class StoreInst : public Instruction {
0293 using VolatileField = BoolBitfieldElementT<0>;
0294 using AlignmentField = AlignmentBitfieldElementT<VolatileField::NextBit>;
0295 using OrderingField = AtomicOrderingBitfieldElementT<AlignmentField::NextBit>;
0296 static_assert(
0297 Bitfield::areContiguous<VolatileField, AlignmentField, OrderingField>(),
0298 "Bitfields must be contiguous");
0299
0300 void AssertOK();
0301
0302 constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
0303
0304 protected:
0305
0306 friend class Instruction;
0307
0308 StoreInst *cloneImpl() const;
0309
0310 public:
0311 StoreInst(Value *Val, Value *Ptr, InsertPosition InsertBefore);
0312 StoreInst(Value *Val, Value *Ptr, bool isVolatile,
0313 InsertPosition InsertBefore);
0314 StoreInst(Value *Val, Value *Ptr, bool isVolatile, Align Align,
0315 InsertPosition InsertBefore = nullptr);
0316 StoreInst(Value *Val, Value *Ptr, bool isVolatile, Align Align,
0317 AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System,
0318 InsertPosition InsertBefore = nullptr);
0319
0320
0321 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
0322 void operator delete(void *Ptr) { User::operator delete(Ptr); }
0323
0324
0325 bool isVolatile() const { return getSubclassData<VolatileField>(); }
0326
0327
0328 void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
0329
0330
0331 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0332
0333 Align getAlign() const {
0334 return Align(1ULL << (getSubclassData<AlignmentField>()));
0335 }
0336
0337 void setAlignment(Align Align) {
0338 setSubclassData<AlignmentField>(Log2(Align));
0339 }
0340
0341
0342 AtomicOrdering getOrdering() const {
0343 return getSubclassData<OrderingField>();
0344 }
0345
0346
0347
0348 void setOrdering(AtomicOrdering Ordering) {
0349 setSubclassData<OrderingField>(Ordering);
0350 }
0351
0352
0353 SyncScope::ID getSyncScopeID() const {
0354 return SSID;
0355 }
0356
0357
0358 void setSyncScopeID(SyncScope::ID SSID) {
0359 this->SSID = SSID;
0360 }
0361
0362
0363
0364 void setAtomic(AtomicOrdering Ordering,
0365 SyncScope::ID SSID = SyncScope::System) {
0366 setOrdering(Ordering);
0367 setSyncScopeID(SSID);
0368 }
0369
0370 bool isSimple() const { return !isAtomic() && !isVolatile(); }
0371
0372 bool isUnordered() const {
0373 return (getOrdering() == AtomicOrdering::NotAtomic ||
0374 getOrdering() == AtomicOrdering::Unordered) &&
0375 !isVolatile();
0376 }
0377
0378 Value *getValueOperand() { return getOperand(0); }
0379 const Value *getValueOperand() const { return getOperand(0); }
0380
0381 Value *getPointerOperand() { return getOperand(1); }
0382 const Value *getPointerOperand() const { return getOperand(1); }
0383 static unsigned getPointerOperandIndex() { return 1U; }
0384 Type *getPointerOperandType() const { return getPointerOperand()->getType(); }
0385
0386
0387 unsigned getPointerAddressSpace() const {
0388 return getPointerOperandType()->getPointerAddressSpace();
0389 }
0390
0391
0392 static bool classof(const Instruction *I) {
0393 return I->getOpcode() == Instruction::Store;
0394 }
0395 static bool classof(const Value *V) {
0396 return isa<Instruction>(V) && classof(cast<Instruction>(V));
0397 }
0398
0399 private:
0400
0401
0402 template <typename Bitfield>
0403 void setSubclassData(typename Bitfield::Type Value) {
0404 Instruction::setSubclassData<Bitfield>(Value);
0405 }
0406
0407
0408
0409
0410 SyncScope::ID SSID;
0411 };
0412
0413 template <>
0414 struct OperandTraits<StoreInst> : public FixedNumOperandTraits<StoreInst, 2> {
0415 };
0416
0417 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
0418
0419
0420
0421
0422
0423
0424 class FenceInst : public Instruction {
0425 using OrderingField = AtomicOrderingBitfieldElementT<0>;
0426
0427 constexpr static IntrusiveOperandsAllocMarker AllocMarker{0};
0428
0429 void Init(AtomicOrdering Ordering, SyncScope::ID SSID);
0430
0431 protected:
0432
0433 friend class Instruction;
0434
0435 FenceInst *cloneImpl() const;
0436
0437 public:
0438
0439
0440 FenceInst(LLVMContext &C, AtomicOrdering Ordering,
0441 SyncScope::ID SSID = SyncScope::System,
0442 InsertPosition InsertBefore = nullptr);
0443
0444
0445 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
0446 void operator delete(void *Ptr) { User::operator delete(Ptr); }
0447
0448
0449 AtomicOrdering getOrdering() const {
0450 return getSubclassData<OrderingField>();
0451 }
0452
0453
0454
0455 void setOrdering(AtomicOrdering Ordering) {
0456 setSubclassData<OrderingField>(Ordering);
0457 }
0458
0459
0460 SyncScope::ID getSyncScopeID() const {
0461 return SSID;
0462 }
0463
0464
0465 void setSyncScopeID(SyncScope::ID SSID) {
0466 this->SSID = SSID;
0467 }
0468
0469
0470 static bool classof(const Instruction *I) {
0471 return I->getOpcode() == Instruction::Fence;
0472 }
0473 static bool classof(const Value *V) {
0474 return isa<Instruction>(V) && classof(cast<Instruction>(V));
0475 }
0476
0477 private:
0478
0479
0480 template <typename Bitfield>
0481 void setSubclassData(typename Bitfield::Type Value) {
0482 Instruction::setSubclassData<Bitfield>(Value);
0483 }
0484
0485
0486
0487
0488 SyncScope::ID SSID;
0489 };
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501 class AtomicCmpXchgInst : public Instruction {
0502 void Init(Value *Ptr, Value *Cmp, Value *NewVal, Align Align,
0503 AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
0504 SyncScope::ID SSID);
0505
0506 template <unsigned Offset>
0507 using AtomicOrderingBitfieldElement =
0508 typename Bitfield::Element<AtomicOrdering, Offset, 3,
0509 AtomicOrdering::LAST>;
0510
0511 constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
0512
0513 protected:
0514
0515 friend class Instruction;
0516
0517 AtomicCmpXchgInst *cloneImpl() const;
0518
0519 public:
0520 AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, Align Alignment,
0521 AtomicOrdering SuccessOrdering,
0522 AtomicOrdering FailureOrdering, SyncScope::ID SSID,
0523 InsertPosition InsertBefore = nullptr);
0524
0525
0526 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
0527 void operator delete(void *Ptr) { User::operator delete(Ptr); }
0528
0529 using VolatileField = BoolBitfieldElementT<0>;
0530 using WeakField = BoolBitfieldElementT<VolatileField::NextBit>;
0531 using SuccessOrderingField =
0532 AtomicOrderingBitfieldElementT<WeakField::NextBit>;
0533 using FailureOrderingField =
0534 AtomicOrderingBitfieldElementT<SuccessOrderingField::NextBit>;
0535 using AlignmentField =
0536 AlignmentBitfieldElementT<FailureOrderingField::NextBit>;
0537 static_assert(
0538 Bitfield::areContiguous<VolatileField, WeakField, SuccessOrderingField,
0539 FailureOrderingField, AlignmentField>(),
0540 "Bitfields must be contiguous");
0541
0542
0543
0544 Align getAlign() const {
0545 return Align(1ULL << getSubclassData<AlignmentField>());
0546 }
0547
0548 void setAlignment(Align Align) {
0549 setSubclassData<AlignmentField>(Log2(Align));
0550 }
0551
0552
0553
0554
0555 bool isVolatile() const { return getSubclassData<VolatileField>(); }
0556
0557
0558
0559 void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
0560
0561
0562 bool isWeak() const { return getSubclassData<WeakField>(); }
0563
0564 void setWeak(bool IsWeak) { setSubclassData<WeakField>(IsWeak); }
0565
0566
0567 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0568
0569 static bool isValidSuccessOrdering(AtomicOrdering Ordering) {
0570 return Ordering != AtomicOrdering::NotAtomic &&
0571 Ordering != AtomicOrdering::Unordered;
0572 }
0573
0574 static bool isValidFailureOrdering(AtomicOrdering Ordering) {
0575 return Ordering != AtomicOrdering::NotAtomic &&
0576 Ordering != AtomicOrdering::Unordered &&
0577 Ordering != AtomicOrdering::AcquireRelease &&
0578 Ordering != AtomicOrdering::Release;
0579 }
0580
0581
0582 AtomicOrdering getSuccessOrdering() const {
0583 return getSubclassData<SuccessOrderingField>();
0584 }
0585
0586
0587 void setSuccessOrdering(AtomicOrdering Ordering) {
0588 assert(isValidSuccessOrdering(Ordering) &&
0589 "invalid CmpXchg success ordering");
0590 setSubclassData<SuccessOrderingField>(Ordering);
0591 }
0592
0593
0594 AtomicOrdering getFailureOrdering() const {
0595 return getSubclassData<FailureOrderingField>();
0596 }
0597
0598
0599 void setFailureOrdering(AtomicOrdering Ordering) {
0600 assert(isValidFailureOrdering(Ordering) &&
0601 "invalid CmpXchg failure ordering");
0602 setSubclassData<FailureOrderingField>(Ordering);
0603 }
0604
0605
0606
0607 AtomicOrdering getMergedOrdering() const {
0608 if (getFailureOrdering() == AtomicOrdering::SequentiallyConsistent)
0609 return AtomicOrdering::SequentiallyConsistent;
0610 if (getFailureOrdering() == AtomicOrdering::Acquire) {
0611 if (getSuccessOrdering() == AtomicOrdering::Monotonic)
0612 return AtomicOrdering::Acquire;
0613 if (getSuccessOrdering() == AtomicOrdering::Release)
0614 return AtomicOrdering::AcquireRelease;
0615 }
0616 return getSuccessOrdering();
0617 }
0618
0619
0620 SyncScope::ID getSyncScopeID() const {
0621 return SSID;
0622 }
0623
0624
0625 void setSyncScopeID(SyncScope::ID SSID) {
0626 this->SSID = SSID;
0627 }
0628
0629 Value *getPointerOperand() { return getOperand(0); }
0630 const Value *getPointerOperand() const { return getOperand(0); }
0631 static unsigned getPointerOperandIndex() { return 0U; }
0632
0633 Value *getCompareOperand() { return getOperand(1); }
0634 const Value *getCompareOperand() const { return getOperand(1); }
0635
0636 Value *getNewValOperand() { return getOperand(2); }
0637 const Value *getNewValOperand() const { return getOperand(2); }
0638
0639
0640 unsigned getPointerAddressSpace() const {
0641 return getPointerOperand()->getType()->getPointerAddressSpace();
0642 }
0643
0644
0645
0646
0647
0648
0649
0650
0651 static AtomicOrdering
0652 getStrongestFailureOrdering(AtomicOrdering SuccessOrdering) {
0653 switch (SuccessOrdering) {
0654 default:
0655 llvm_unreachable("invalid cmpxchg success ordering");
0656 case AtomicOrdering::Release:
0657 case AtomicOrdering::Monotonic:
0658 return AtomicOrdering::Monotonic;
0659 case AtomicOrdering::AcquireRelease:
0660 case AtomicOrdering::Acquire:
0661 return AtomicOrdering::Acquire;
0662 case AtomicOrdering::SequentiallyConsistent:
0663 return AtomicOrdering::SequentiallyConsistent;
0664 }
0665 }
0666
0667
0668 static bool classof(const Instruction *I) {
0669 return I->getOpcode() == Instruction::AtomicCmpXchg;
0670 }
0671 static bool classof(const Value *V) {
0672 return isa<Instruction>(V) && classof(cast<Instruction>(V));
0673 }
0674
0675 private:
0676
0677
0678 template <typename Bitfield>
0679 void setSubclassData(typename Bitfield::Type Value) {
0680 Instruction::setSubclassData<Bitfield>(Value);
0681 }
0682
0683
0684
0685
0686 SyncScope::ID SSID;
0687 };
0688
0689 template <>
0690 struct OperandTraits<AtomicCmpXchgInst> :
0691 public FixedNumOperandTraits<AtomicCmpXchgInst, 3> {
0692 };
0693
0694 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicCmpXchgInst, Value)
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704 class AtomicRMWInst : public Instruction {
0705 protected:
0706
0707 friend class Instruction;
0708
0709 AtomicRMWInst *cloneImpl() const;
0710
0711 public:
0712
0713
0714
0715
0716 enum BinOp : unsigned {
0717
0718 Xchg,
0719
0720 Add,
0721
0722 Sub,
0723
0724 And,
0725
0726 Nand,
0727
0728 Or,
0729
0730 Xor,
0731
0732 Max,
0733
0734 Min,
0735
0736 UMax,
0737
0738 UMin,
0739
0740
0741 FAdd,
0742
0743
0744 FSub,
0745
0746
0747
0748 FMax,
0749
0750
0751
0752 FMin,
0753
0754
0755
0756 UIncWrap,
0757
0758
0759
0760 UDecWrap,
0761
0762
0763
0764 USubCond,
0765
0766
0767
0768 USubSat,
0769
0770 FIRST_BINOP = Xchg,
0771 LAST_BINOP = USubSat,
0772 BAD_BINOP
0773 };
0774
0775 private:
0776 template <unsigned Offset>
0777 using AtomicOrderingBitfieldElement =
0778 typename Bitfield::Element<AtomicOrdering, Offset, 3,
0779 AtomicOrdering::LAST>;
0780
0781 template <unsigned Offset>
0782 using BinOpBitfieldElement =
0783 typename Bitfield::Element<BinOp, Offset, 5, BinOp::LAST_BINOP>;
0784
0785 constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
0786
0787 public:
0788 AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, Align Alignment,
0789 AtomicOrdering Ordering, SyncScope::ID SSID,
0790 InsertPosition InsertBefore = nullptr);
0791
0792
0793 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
0794 void operator delete(void *Ptr) { User::operator delete(Ptr); }
0795
0796 using VolatileField = BoolBitfieldElementT<0>;
0797 using AtomicOrderingField =
0798 AtomicOrderingBitfieldElementT<VolatileField::NextBit>;
0799 using OperationField = BinOpBitfieldElement<AtomicOrderingField::NextBit>;
0800 using AlignmentField = AlignmentBitfieldElementT<OperationField::NextBit>;
0801 static_assert(Bitfield::areContiguous<VolatileField, AtomicOrderingField,
0802 OperationField, AlignmentField>(),
0803 "Bitfields must be contiguous");
0804
0805 BinOp getOperation() const { return getSubclassData<OperationField>(); }
0806
0807 static StringRef getOperationName(BinOp Op);
0808
0809 static bool isFPOperation(BinOp Op) {
0810 switch (Op) {
0811 case AtomicRMWInst::FAdd:
0812 case AtomicRMWInst::FSub:
0813 case AtomicRMWInst::FMax:
0814 case AtomicRMWInst::FMin:
0815 return true;
0816 default:
0817 return false;
0818 }
0819 }
0820
0821 void setOperation(BinOp Operation) {
0822 setSubclassData<OperationField>(Operation);
0823 }
0824
0825
0826
0827 Align getAlign() const {
0828 return Align(1ULL << getSubclassData<AlignmentField>());
0829 }
0830
0831 void setAlignment(Align Align) {
0832 setSubclassData<AlignmentField>(Log2(Align));
0833 }
0834
0835
0836
0837 bool isVolatile() const { return getSubclassData<VolatileField>(); }
0838
0839
0840
0841 void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
0842
0843
0844 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0845
0846
0847 AtomicOrdering getOrdering() const {
0848 return getSubclassData<AtomicOrderingField>();
0849 }
0850
0851
0852 void setOrdering(AtomicOrdering Ordering) {
0853 assert(Ordering != AtomicOrdering::NotAtomic &&
0854 "atomicrmw instructions can only be atomic.");
0855 assert(Ordering != AtomicOrdering::Unordered &&
0856 "atomicrmw instructions cannot be unordered.");
0857 setSubclassData<AtomicOrderingField>(Ordering);
0858 }
0859
0860
0861 SyncScope::ID getSyncScopeID() const {
0862 return SSID;
0863 }
0864
0865
0866 void setSyncScopeID(SyncScope::ID SSID) {
0867 this->SSID = SSID;
0868 }
0869
0870 Value *getPointerOperand() { return getOperand(0); }
0871 const Value *getPointerOperand() const { return getOperand(0); }
0872 static unsigned getPointerOperandIndex() { return 0U; }
0873
0874 Value *getValOperand() { return getOperand(1); }
0875 const Value *getValOperand() const { return getOperand(1); }
0876
0877
0878 unsigned getPointerAddressSpace() const {
0879 return getPointerOperand()->getType()->getPointerAddressSpace();
0880 }
0881
0882 bool isFloatingPointOperation() const {
0883 return isFPOperation(getOperation());
0884 }
0885
0886
0887 static bool classof(const Instruction *I) {
0888 return I->getOpcode() == Instruction::AtomicRMW;
0889 }
0890 static bool classof(const Value *V) {
0891 return isa<Instruction>(V) && classof(cast<Instruction>(V));
0892 }
0893
0894 private:
0895 void Init(BinOp Operation, Value *Ptr, Value *Val, Align Align,
0896 AtomicOrdering Ordering, SyncScope::ID SSID);
0897
0898
0899
0900 template <typename Bitfield>
0901 void setSubclassData(typename Bitfield::Type Value) {
0902 Instruction::setSubclassData<Bitfield>(Value);
0903 }
0904
0905
0906
0907
0908 SyncScope::ID SSID;
0909 };
0910
0911 template <>
0912 struct OperandTraits<AtomicRMWInst>
0913 : public FixedNumOperandTraits<AtomicRMWInst,2> {
0914 };
0915
0916 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AtomicRMWInst, Value)
0917
0918
0919
0920
0921
0922
0923
0924
0925 inline Type *checkGEPType(Type *Ty) {
0926 assert(Ty && "Invalid GetElementPtrInst indices for type!");
0927 return Ty;
0928 }
0929
0930
0931
0932
0933 class GetElementPtrInst : public Instruction {
0934 Type *SourceElementType;
0935 Type *ResultElementType;
0936
0937 GetElementPtrInst(const GetElementPtrInst &GEPI, AllocInfo AllocInfo);
0938
0939
0940
0941
0942
0943 inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
0944 ArrayRef<Value *> IdxList, AllocInfo AllocInfo,
0945 const Twine &NameStr, InsertPosition InsertBefore);
0946
0947 void init(Value *Ptr, ArrayRef<Value *> IdxList, const Twine &NameStr);
0948
0949 protected:
0950
0951 friend class Instruction;
0952
0953 GetElementPtrInst *cloneImpl() const;
0954
0955 public:
0956 static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
0957 ArrayRef<Value *> IdxList,
0958 const Twine &NameStr = "",
0959 InsertPosition InsertBefore = nullptr) {
0960 unsigned Values = 1 + unsigned(IdxList.size());
0961 assert(PointeeType && "Must specify element type");
0962 IntrusiveOperandsAllocMarker AllocMarker{Values};
0963 return new (AllocMarker) GetElementPtrInst(
0964 PointeeType, Ptr, IdxList, AllocMarker, NameStr, InsertBefore);
0965 }
0966
0967 static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
0968 ArrayRef<Value *> IdxList, GEPNoWrapFlags NW,
0969 const Twine &NameStr = "",
0970 InsertPosition InsertBefore = nullptr) {
0971 GetElementPtrInst *GEP =
0972 Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
0973 GEP->setNoWrapFlags(NW);
0974 return GEP;
0975 }
0976
0977
0978
0979 static GetElementPtrInst *
0980 CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList,
0981 const Twine &NameStr = "",
0982 InsertPosition InsertBefore = nullptr) {
0983 return Create(PointeeType, Ptr, IdxList, GEPNoWrapFlags::inBounds(),
0984 NameStr, InsertBefore);
0985 }
0986
0987
0988 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0989
0990 Type *getSourceElementType() const { return SourceElementType; }
0991
0992 void setSourceElementType(Type *Ty) { SourceElementType = Ty; }
0993 void setResultElementType(Type *Ty) { ResultElementType = Ty; }
0994
0995 Type *getResultElementType() const {
0996 return ResultElementType;
0997 }
0998
0999
1000 unsigned getAddressSpace() const {
1001
1002
1003 return getPointerAddressSpace();
1004 }
1005
1006
1007
1008
1009
1010
1011 static Type *getIndexedType(Type *Ty, ArrayRef<Value *> IdxList);
1012 static Type *getIndexedType(Type *Ty, ArrayRef<Constant *> IdxList);
1013 static Type *getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList);
1014
1015
1016
1017
1018
1019
1020 static Type *getTypeAtIndex(Type *Ty, Value *Idx);
1021 static Type *getTypeAtIndex(Type *Ty, uint64_t Idx);
1022
1023 inline op_iterator idx_begin() { return op_begin()+1; }
1024 inline const_op_iterator idx_begin() const { return op_begin()+1; }
1025 inline op_iterator idx_end() { return op_end(); }
1026 inline const_op_iterator idx_end() const { return op_end(); }
1027
1028 inline iterator_range<op_iterator> indices() {
1029 return make_range(idx_begin(), idx_end());
1030 }
1031
1032 inline iterator_range<const_op_iterator> indices() const {
1033 return make_range(idx_begin(), idx_end());
1034 }
1035
1036 Value *getPointerOperand() {
1037 return getOperand(0);
1038 }
1039 const Value *getPointerOperand() const {
1040 return getOperand(0);
1041 }
1042 static unsigned getPointerOperandIndex() {
1043 return 0U;
1044 }
1045
1046
1047
1048 Type *getPointerOperandType() const {
1049 return getPointerOperand()->getType();
1050 }
1051
1052
1053 unsigned getPointerAddressSpace() const {
1054 return getPointerOperandType()->getPointerAddressSpace();
1055 }
1056
1057
1058
1059 static Type *getGEPReturnType(Value *Ptr, ArrayRef<Value *> IdxList) {
1060
1061 Type *Ty = Ptr->getType();
1062 if (Ty->isVectorTy())
1063 return Ty;
1064
1065 for (Value *Index : IdxList)
1066 if (auto *IndexVTy = dyn_cast<VectorType>(Index->getType())) {
1067 ElementCount EltCount = IndexVTy->getElementCount();
1068 return VectorType::get(Ty, EltCount);
1069 }
1070
1071 return Ty;
1072 }
1073
1074 unsigned getNumIndices() const {
1075 return getNumOperands() - 1;
1076 }
1077
1078 bool hasIndices() const {
1079 return getNumOperands() > 1;
1080 }
1081
1082
1083
1084
1085 bool hasAllZeroIndices() const;
1086
1087
1088
1089
1090 bool hasAllConstantIndices() const;
1091
1092
1093 void setNoWrapFlags(GEPNoWrapFlags NW);
1094
1095
1096
1097
1098 void setIsInBounds(bool b = true);
1099
1100
1101 GEPNoWrapFlags getNoWrapFlags() const;
1102
1103
1104 bool isInBounds() const;
1105
1106
1107 bool hasNoUnsignedSignedWrap() const;
1108
1109
1110 bool hasNoUnsignedWrap() const;
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120 bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
1121 bool collectOffset(const DataLayout &DL, unsigned BitWidth,
1122 SmallMapVector<Value *, APInt, 4> &VariableOffsets,
1123 APInt &ConstantOffset) const;
1124
1125 static bool classof(const Instruction *I) {
1126 return (I->getOpcode() == Instruction::GetElementPtr);
1127 }
1128 static bool classof(const Value *V) {
1129 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1130 }
1131 };
1132
1133 template <>
1134 struct OperandTraits<GetElementPtrInst>
1135 : public VariadicOperandTraits<GetElementPtrInst> {};
1136
1137 GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
1138 ArrayRef<Value *> IdxList,
1139 AllocInfo AllocInfo, const Twine &NameStr,
1140 InsertPosition InsertBefore)
1141 : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr, AllocInfo,
1142 InsertBefore),
1143 SourceElementType(PointeeType),
1144 ResultElementType(getIndexedType(PointeeType, IdxList)) {
1145 init(Ptr, IdxList, NameStr);
1146 }
1147
1148 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158 class ICmpInst: public CmpInst {
1159 void AssertOK() {
1160 assert(isIntPredicate() &&
1161 "Invalid ICmp predicate value");
1162 assert(getOperand(0)->getType() == getOperand(1)->getType() &&
1163 "Both operands to ICmp instruction are not of the same type!");
1164
1165 assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
1166 getOperand(0)->getType()->isPtrOrPtrVectorTy()) &&
1167 "Invalid operand types for ICmp instruction");
1168 }
1169
1170 enum { SameSign = (1 << 0) };
1171
1172 protected:
1173
1174 friend class Instruction;
1175
1176
1177 ICmpInst *cloneImpl() const;
1178
1179 public:
1180
1181 ICmpInst(InsertPosition InsertBefore,
1182 Predicate pred,
1183 Value *LHS,
1184 Value *RHS,
1185 const Twine &NameStr = ""
1186 )
1187 : CmpInst(makeCmpResultType(LHS->getType()), Instruction::ICmp, pred, LHS,
1188 RHS, NameStr, InsertBefore) {
1189 #ifndef NDEBUG
1190 AssertOK();
1191 #endif
1192 }
1193
1194
1195 ICmpInst(
1196 Predicate pred,
1197 Value *LHS,
1198 Value *RHS,
1199 const Twine &NameStr = ""
1200 ) : CmpInst(makeCmpResultType(LHS->getType()),
1201 Instruction::ICmp, pred, LHS, RHS, NameStr) {
1202 #ifndef NDEBUG
1203 AssertOK();
1204 #endif
1205 }
1206
1207
1208 CmpPredicate getCmpPredicate() const {
1209 return {getPredicate(), hasSameSign()};
1210 }
1211
1212
1213
1214 static CmpPredicate getInverseCmpPredicate(CmpPredicate Pred) {
1215 return {getInversePredicate(Pred), Pred.hasSameSign()};
1216 }
1217
1218
1219 CmpPredicate getInverseCmpPredicate() const {
1220 return getInverseCmpPredicate(getCmpPredicate());
1221 }
1222
1223
1224
1225 static CmpPredicate getSwappedCmpPredicate(CmpPredicate Pred) {
1226 return {getSwappedPredicate(Pred), Pred.hasSameSign()};
1227 }
1228
1229
1230 CmpPredicate getSwappedCmpPredicate() const {
1231 return getSwappedCmpPredicate(getCmpPredicate());
1232 }
1233
1234
1235
1236
1237
1238 Predicate getSignedPredicate() const {
1239 return getSignedPredicate(getPredicate());
1240 }
1241
1242
1243 static Predicate getSignedPredicate(Predicate Pred);
1244
1245
1246
1247
1248
1249 Predicate getUnsignedPredicate() const {
1250 return getUnsignedPredicate(getPredicate());
1251 }
1252
1253
1254 static Predicate getUnsignedPredicate(Predicate Pred);
1255
1256
1257
1258
1259
1260 static Predicate getFlippedSignednessPredicate(Predicate Pred);
1261
1262
1263
1264
1265 Predicate getFlippedSignednessPredicate() const {
1266 return getFlippedSignednessPredicate(getPredicate());
1267 }
1268
1269
1270
1271 static std::optional<bool> isImpliedByMatchingCmp(CmpPredicate Pred1,
1272 CmpPredicate Pred2);
1273
1274 void setSameSign(bool B = true) {
1275 SubclassOptionalData = (SubclassOptionalData & ~SameSign) | (B * SameSign);
1276 }
1277
1278
1279
1280
1281 bool hasSameSign() const { return SubclassOptionalData & SameSign; }
1282
1283
1284
1285 static bool isEquality(Predicate P) {
1286 return P == ICMP_EQ || P == ICMP_NE;
1287 }
1288
1289
1290
1291 bool isEquality() const {
1292 return isEquality(getPredicate());
1293 }
1294
1295
1296
1297 static bool isCommutative(Predicate P) { return isEquality(P); }
1298
1299
1300
1301 bool isCommutative() const { return isCommutative(getPredicate()); }
1302
1303
1304
1305 bool isRelational() const {
1306 return !isEquality();
1307 }
1308
1309
1310
1311 static bool isRelational(Predicate P) {
1312 return !isEquality(P);
1313 }
1314
1315
1316
1317 static bool isGT(Predicate P) {
1318 return P == ICMP_SGT || P == ICMP_UGT;
1319 }
1320
1321
1322
1323 static bool isLT(Predicate P) {
1324 return P == ICMP_SLT || P == ICMP_ULT;
1325 }
1326
1327
1328
1329 static bool isGE(Predicate P) {
1330 return P == ICMP_SGE || P == ICMP_UGE;
1331 }
1332
1333
1334
1335 static bool isLE(Predicate P) {
1336 return P == ICMP_SLE || P == ICMP_ULE;
1337 }
1338
1339
1340
1341 static auto predicates() { return ICmpPredicates(); }
1342
1343
1344
1345
1346
1347
1348 void swapOperands() {
1349 setPredicate(getSwappedPredicate());
1350 Op<0>().swap(Op<1>());
1351 }
1352
1353
1354 static bool compare(const APInt &LHS, const APInt &RHS,
1355 ICmpInst::Predicate Pred);
1356
1357
1358
1359 static std::optional<bool> compare(const KnownBits &LHS, const KnownBits &RHS,
1360 ICmpInst::Predicate Pred);
1361
1362
1363 static bool classof(const Instruction *I) {
1364 return I->getOpcode() == Instruction::ICmp;
1365 }
1366 static bool classof(const Value *V) {
1367 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1368 }
1369 };
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379 class FCmpInst: public CmpInst {
1380 void AssertOK() {
1381 assert(isFPPredicate() && "Invalid FCmp predicate value");
1382 assert(getOperand(0)->getType() == getOperand(1)->getType() &&
1383 "Both operands to FCmp instruction are not of the same type!");
1384
1385 assert(getOperand(0)->getType()->isFPOrFPVectorTy() &&
1386 "Invalid operand types for FCmp instruction");
1387 }
1388
1389 protected:
1390
1391 friend class Instruction;
1392
1393
1394 FCmpInst *cloneImpl() const;
1395
1396 public:
1397
1398 FCmpInst(InsertPosition InsertBefore,
1399 Predicate pred,
1400 Value *LHS,
1401 Value *RHS,
1402 const Twine &NameStr = ""
1403 )
1404 : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, pred, LHS,
1405 RHS, NameStr, InsertBefore) {
1406 AssertOK();
1407 }
1408
1409
1410 FCmpInst(Predicate Pred,
1411 Value *LHS,
1412 Value *RHS,
1413 const Twine &NameStr = "",
1414 Instruction *FlagsSource = nullptr)
1415 : CmpInst(makeCmpResultType(LHS->getType()), Instruction::FCmp, Pred, LHS,
1416 RHS, NameStr, nullptr, FlagsSource) {
1417 AssertOK();
1418 }
1419
1420
1421
1422 static bool isEquality(Predicate Pred) {
1423 return Pred == FCMP_OEQ || Pred == FCMP_ONE || Pred == FCMP_UEQ ||
1424 Pred == FCMP_UNE;
1425 }
1426
1427
1428
1429 bool isEquality() const { return isEquality(getPredicate()); }
1430
1431
1432
1433 static bool isCommutative(Predicate Pred) {
1434 return isEquality(Pred) || Pred == FCMP_FALSE || Pred == FCMP_TRUE ||
1435 Pred == FCMP_ORD || Pred == FCMP_UNO;
1436 }
1437
1438
1439
1440 bool isCommutative() const { return isCommutative(getPredicate()); }
1441
1442
1443
1444 bool isRelational() const { return !isEquality(); }
1445
1446
1447
1448
1449
1450
1451 void swapOperands() {
1452 setPredicate(getSwappedPredicate());
1453 Op<0>().swap(Op<1>());
1454 }
1455
1456
1457
1458 static auto predicates() { return FCmpPredicates(); }
1459
1460
1461 static bool compare(const APFloat &LHS, const APFloat &RHS,
1462 FCmpInst::Predicate Pred);
1463
1464
1465 static bool classof(const Instruction *I) {
1466 return I->getOpcode() == Instruction::FCmp;
1467 }
1468 static bool classof(const Value *V) {
1469 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1470 }
1471 };
1472
1473
1474
1475
1476
1477
1478
1479 class CallInst : public CallBase {
1480 CallInst(const CallInst &CI, AllocInfo AllocInfo);
1481
1482
1483 inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
1484 ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
1485 AllocInfo AllocInfo, InsertPosition InsertBefore);
1486
1487 inline CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
1488 const Twine &NameStr, AllocInfo AllocInfo,
1489 InsertPosition InsertBefore)
1490 : CallInst(Ty, Func, Args, {}, NameStr, AllocInfo, InsertBefore) {}
1491
1492 explicit CallInst(FunctionType *Ty, Value *F, const Twine &NameStr,
1493 AllocInfo AllocInfo, InsertPosition InsertBefore);
1494
1495 void init(FunctionType *FTy, Value *Func, ArrayRef<Value *> Args,
1496 ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
1497 void init(FunctionType *FTy, Value *Func, const Twine &NameStr);
1498
1499
1500 static unsigned ComputeNumOperands(unsigned NumArgs,
1501 unsigned NumBundleInputs = 0) {
1502
1503
1504 return 1 + NumArgs + NumBundleInputs;
1505 }
1506
1507 protected:
1508
1509 friend class Instruction;
1510
1511 CallInst *cloneImpl() const;
1512
1513 public:
1514 static CallInst *Create(FunctionType *Ty, Value *F, const Twine &NameStr = "",
1515 InsertPosition InsertBefore = nullptr) {
1516 IntrusiveOperandsAllocMarker AllocMarker{ComputeNumOperands(0)};
1517 return new (AllocMarker)
1518 CallInst(Ty, F, NameStr, AllocMarker, InsertBefore);
1519 }
1520
1521 static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
1522 const Twine &NameStr,
1523 InsertPosition InsertBefore = nullptr) {
1524 IntrusiveOperandsAllocMarker AllocMarker{ComputeNumOperands(Args.size())};
1525 return new (AllocMarker)
1526 CallInst(Ty, Func, Args, {}, NameStr, AllocMarker, InsertBefore);
1527 }
1528
1529 static CallInst *Create(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
1530 ArrayRef<OperandBundleDef> Bundles = {},
1531 const Twine &NameStr = "",
1532 InsertPosition InsertBefore = nullptr) {
1533 IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
1534 ComputeNumOperands(unsigned(Args.size()), CountBundleInputs(Bundles)),
1535 unsigned(Bundles.size() * sizeof(BundleOpInfo))};
1536
1537 return new (AllocMarker)
1538 CallInst(Ty, Func, Args, Bundles, NameStr, AllocMarker, InsertBefore);
1539 }
1540
1541 static CallInst *Create(FunctionCallee Func, const Twine &NameStr = "",
1542 InsertPosition InsertBefore = nullptr) {
1543 return Create(Func.getFunctionType(), Func.getCallee(), NameStr,
1544 InsertBefore);
1545 }
1546
1547 static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
1548 ArrayRef<OperandBundleDef> Bundles = {},
1549 const Twine &NameStr = "",
1550 InsertPosition InsertBefore = nullptr) {
1551 return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles,
1552 NameStr, InsertBefore);
1553 }
1554
1555 static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args,
1556 const Twine &NameStr,
1557 InsertPosition InsertBefore = nullptr) {
1558 return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr,
1559 InsertBefore);
1560 }
1561
1562
1563
1564
1565
1566
1567
1568 static CallInst *Create(CallInst *CI, ArrayRef<OperandBundleDef> Bundles,
1569 InsertPosition InsertPt = nullptr);
1570
1571
1572 enum TailCallKind : unsigned {
1573 TCK_None = 0,
1574 TCK_Tail = 1,
1575 TCK_MustTail = 2,
1576 TCK_NoTail = 3,
1577 TCK_LAST = TCK_NoTail
1578 };
1579
1580 using TailCallKindField = Bitfield::Element<TailCallKind, 0, 2, TCK_LAST>;
1581 static_assert(
1582 Bitfield::areContiguous<TailCallKindField, CallBase::CallingConvField>(),
1583 "Bitfields must be contiguous");
1584
1585 TailCallKind getTailCallKind() const {
1586 return getSubclassData<TailCallKindField>();
1587 }
1588
1589 bool isTailCall() const {
1590 TailCallKind Kind = getTailCallKind();
1591 return Kind == TCK_Tail || Kind == TCK_MustTail;
1592 }
1593
1594 bool isMustTailCall() const { return getTailCallKind() == TCK_MustTail; }
1595
1596 bool isNoTailCall() const { return getTailCallKind() == TCK_NoTail; }
1597
1598 void setTailCallKind(TailCallKind TCK) {
1599 setSubclassData<TailCallKindField>(TCK);
1600 }
1601
1602 void setTailCall(bool IsTc = true) {
1603 setTailCallKind(IsTc ? TCK_Tail : TCK_None);
1604 }
1605
1606
1607 bool canReturnTwice() const { return hasFnAttr(Attribute::ReturnsTwice); }
1608 void setCanReturnTwice() { addFnAttr(Attribute::ReturnsTwice); }
1609
1610
1611 bool isNonContinuableTrap() const {
1612 switch (getIntrinsicID()) {
1613 case Intrinsic::trap:
1614 case Intrinsic::ubsantrap:
1615 return !hasFnAttr("trap-func-name");
1616 default:
1617 return false;
1618 }
1619 }
1620
1621
1622 static bool classof(const Instruction *I) {
1623 return I->getOpcode() == Instruction::Call;
1624 }
1625 static bool classof(const Value *V) {
1626 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1627 }
1628
1629
1630 void updateProfWeight(uint64_t S, uint64_t T);
1631
1632 private:
1633
1634
1635 template <typename Bitfield>
1636 void setSubclassData(typename Bitfield::Type Value) {
1637 Instruction::setSubclassData<Bitfield>(Value);
1638 }
1639 };
1640
1641 CallInst::CallInst(FunctionType *Ty, Value *Func, ArrayRef<Value *> Args,
1642 ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr,
1643 AllocInfo AllocInfo, InsertPosition InsertBefore)
1644 : CallBase(Ty->getReturnType(), Instruction::Call, AllocInfo,
1645 InsertBefore) {
1646 assert(AllocInfo.NumOps ==
1647 unsigned(Args.size() + CountBundleInputs(Bundles) + 1));
1648 init(Ty, Func, Args, Bundles, NameStr);
1649 }
1650
1651
1652
1653
1654
1655
1656
1657 class SelectInst : public Instruction {
1658 constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
1659
1660 SelectInst(Value *C, Value *S1, Value *S2, const Twine &NameStr,
1661 InsertPosition InsertBefore)
1662 : Instruction(S1->getType(), Instruction::Select, AllocMarker,
1663 InsertBefore) {
1664 init(C, S1, S2);
1665 setName(NameStr);
1666 }
1667
1668 void init(Value *C, Value *S1, Value *S2) {
1669 assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select");
1670 Op<0>() = C;
1671 Op<1>() = S1;
1672 Op<2>() = S2;
1673 }
1674
1675 protected:
1676
1677 friend class Instruction;
1678
1679 SelectInst *cloneImpl() const;
1680
1681 public:
1682 static SelectInst *Create(Value *C, Value *S1, Value *S2,
1683 const Twine &NameStr = "",
1684 InsertPosition InsertBefore = nullptr,
1685 Instruction *MDFrom = nullptr) {
1686 SelectInst *Sel =
1687 new (AllocMarker) SelectInst(C, S1, S2, NameStr, InsertBefore);
1688 if (MDFrom)
1689 Sel->copyMetadata(*MDFrom);
1690 return Sel;
1691 }
1692
1693 const Value *getCondition() const { return Op<0>(); }
1694 const Value *getTrueValue() const { return Op<1>(); }
1695 const Value *getFalseValue() const { return Op<2>(); }
1696 Value *getCondition() { return Op<0>(); }
1697 Value *getTrueValue() { return Op<1>(); }
1698 Value *getFalseValue() { return Op<2>(); }
1699
1700 void setCondition(Value *V) { Op<0>() = V; }
1701 void setTrueValue(Value *V) { Op<1>() = V; }
1702 void setFalseValue(Value *V) { Op<2>() = V; }
1703
1704
1705
1706 void swapValues() { Op<1>().swap(Op<2>()); }
1707
1708
1709
1710 static const char *areInvalidOperands(Value *Cond, Value *True, Value *False);
1711
1712
1713 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
1714
1715 OtherOps getOpcode() const {
1716 return static_cast<OtherOps>(Instruction::getOpcode());
1717 }
1718
1719
1720 static bool classof(const Instruction *I) {
1721 return I->getOpcode() == Instruction::Select;
1722 }
1723 static bool classof(const Value *V) {
1724 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1725 }
1726 };
1727
1728 template <>
1729 struct OperandTraits<SelectInst> : public FixedNumOperandTraits<SelectInst, 3> {
1730 };
1731
1732 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SelectInst, Value)
1733
1734
1735
1736
1737
1738
1739
1740
1741 class VAArgInst : public UnaryInstruction {
1742 protected:
1743
1744 friend class Instruction;
1745
1746 VAArgInst *cloneImpl() const;
1747
1748 public:
1749 VAArgInst(Value *List, Type *Ty, const Twine &NameStr = "",
1750 InsertPosition InsertBefore = nullptr)
1751 : UnaryInstruction(Ty, VAArg, List, InsertBefore) {
1752 setName(NameStr);
1753 }
1754
1755 Value *getPointerOperand() { return getOperand(0); }
1756 const Value *getPointerOperand() const { return getOperand(0); }
1757 static unsigned getPointerOperandIndex() { return 0U; }
1758
1759
1760 static bool classof(const Instruction *I) {
1761 return I->getOpcode() == VAArg;
1762 }
1763 static bool classof(const Value *V) {
1764 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1765 }
1766 };
1767
1768
1769
1770
1771
1772
1773
1774
1775 class ExtractElementInst : public Instruction {
1776 constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
1777
1778 ExtractElementInst(Value *Vec, Value *Idx, const Twine &NameStr = "",
1779 InsertPosition InsertBefore = nullptr);
1780
1781 protected:
1782
1783 friend class Instruction;
1784
1785 ExtractElementInst *cloneImpl() const;
1786
1787 public:
1788 static ExtractElementInst *Create(Value *Vec, Value *Idx,
1789 const Twine &NameStr = "",
1790 InsertPosition InsertBefore = nullptr) {
1791 return new (AllocMarker)
1792 ExtractElementInst(Vec, Idx, NameStr, InsertBefore);
1793 }
1794
1795
1796
1797 static bool isValidOperands(const Value *Vec, const Value *Idx);
1798
1799 Value *getVectorOperand() { return Op<0>(); }
1800 Value *getIndexOperand() { return Op<1>(); }
1801 const Value *getVectorOperand() const { return Op<0>(); }
1802 const Value *getIndexOperand() const { return Op<1>(); }
1803
1804 VectorType *getVectorOperandType() const {
1805 return cast<VectorType>(getVectorOperand()->getType());
1806 }
1807
1808
1809 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
1810
1811
1812 static bool classof(const Instruction *I) {
1813 return I->getOpcode() == Instruction::ExtractElement;
1814 }
1815 static bool classof(const Value *V) {
1816 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1817 }
1818 };
1819
1820 template <>
1821 struct OperandTraits<ExtractElementInst> :
1822 public FixedNumOperandTraits<ExtractElementInst, 2> {
1823 };
1824
1825 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ExtractElementInst, Value)
1826
1827
1828
1829
1830
1831
1832
1833
1834 class InsertElementInst : public Instruction {
1835 constexpr static IntrusiveOperandsAllocMarker AllocMarker{3};
1836
1837 InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
1838 const Twine &NameStr = "",
1839 InsertPosition InsertBefore = nullptr);
1840
1841 protected:
1842
1843 friend class Instruction;
1844
1845 InsertElementInst *cloneImpl() const;
1846
1847 public:
1848 static InsertElementInst *Create(Value *Vec, Value *NewElt, Value *Idx,
1849 const Twine &NameStr = "",
1850 InsertPosition InsertBefore = nullptr) {
1851 return new (AllocMarker)
1852 InsertElementInst(Vec, NewElt, Idx, NameStr, InsertBefore);
1853 }
1854
1855
1856
1857 static bool isValidOperands(const Value *Vec, const Value *NewElt,
1858 const Value *Idx);
1859
1860
1861
1862 VectorType *getType() const {
1863 return cast<VectorType>(Instruction::getType());
1864 }
1865
1866
1867 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
1868
1869
1870 static bool classof(const Instruction *I) {
1871 return I->getOpcode() == Instruction::InsertElement;
1872 }
1873 static bool classof(const Value *V) {
1874 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1875 }
1876 };
1877
1878 template <>
1879 struct OperandTraits<InsertElementInst> :
1880 public FixedNumOperandTraits<InsertElementInst, 3> {
1881 };
1882
1883 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
1884
1885
1886
1887
1888
1889 constexpr int PoisonMaskElem = -1;
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901 class ShuffleVectorInst : public Instruction {
1902 constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
1903
1904 SmallVector<int, 4> ShuffleMask;
1905 Constant *ShuffleMaskForBitcode;
1906
1907 protected:
1908
1909 friend class Instruction;
1910
1911 ShuffleVectorInst *cloneImpl() const;
1912
1913 public:
1914 ShuffleVectorInst(Value *V1, Value *Mask, const Twine &NameStr = "",
1915 InsertPosition InsertBefore = nullptr);
1916 ShuffleVectorInst(Value *V1, ArrayRef<int> Mask, const Twine &NameStr = "",
1917 InsertPosition InsertBefore = nullptr);
1918 ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
1919 const Twine &NameStr = "",
1920 InsertPosition InsertBefore = nullptr);
1921 ShuffleVectorInst(Value *V1, Value *V2, ArrayRef<int> Mask,
1922 const Twine &NameStr = "",
1923 InsertPosition InsertBefore = nullptr);
1924
1925 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
1926 void operator delete(void *Ptr) { return User::operator delete(Ptr); }
1927
1928
1929
1930 void commute();
1931
1932
1933
1934 static bool isValidOperands(const Value *V1, const Value *V2,
1935 const Value *Mask);
1936 static bool isValidOperands(const Value *V1, const Value *V2,
1937 ArrayRef<int> Mask);
1938
1939
1940
1941 VectorType *getType() const {
1942 return cast<VectorType>(Instruction::getType());
1943 }
1944
1945
1946 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
1947
1948
1949
1950 int getMaskValue(unsigned Elt) const { return ShuffleMask[Elt]; }
1951
1952
1953
1954 static void getShuffleMask(const Constant *Mask,
1955 SmallVectorImpl<int> &Result);
1956
1957
1958
1959 void getShuffleMask(SmallVectorImpl<int> &Result) const {
1960 Result.assign(ShuffleMask.begin(), ShuffleMask.end());
1961 }
1962
1963
1964
1965
1966
1967 Constant *getShuffleMaskForBitcode() const { return ShuffleMaskForBitcode; }
1968
1969 static Constant *convertShuffleMaskForBitcode(ArrayRef<int> Mask,
1970 Type *ResultTy);
1971
1972 void setShuffleMask(ArrayRef<int> Mask);
1973
1974 ArrayRef<int> getShuffleMask() const { return ShuffleMask; }
1975
1976
1977
1978
1979
1980 bool changesLength() const {
1981 unsigned NumSourceElts = cast<VectorType>(Op<0>()->getType())
1982 ->getElementCount()
1983 .getKnownMinValue();
1984 unsigned NumMaskElts = ShuffleMask.size();
1985 return NumSourceElts != NumMaskElts;
1986 }
1987
1988
1989
1990
1991 bool increasesLength() const {
1992 unsigned NumSourceElts = cast<VectorType>(Op<0>()->getType())
1993 ->getElementCount()
1994 .getKnownMinValue();
1995 unsigned NumMaskElts = ShuffleMask.size();
1996 return NumSourceElts < NumMaskElts;
1997 }
1998
1999
2000
2001
2002
2003
2004 static bool isSingleSourceMask(ArrayRef<int> Mask, int NumSrcElts);
2005 static bool isSingleSourceMask(const Constant *Mask, int NumSrcElts) {
2006 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2007 SmallVector<int, 16> MaskAsInts;
2008 getShuffleMask(Mask, MaskAsInts);
2009 return isSingleSourceMask(MaskAsInts, NumSrcElts);
2010 }
2011
2012
2013
2014
2015
2016 bool isSingleSource() const {
2017 return !changesLength() &&
2018 isSingleSourceMask(ShuffleMask, ShuffleMask.size());
2019 }
2020
2021
2022
2023
2024
2025
2026 static bool isIdentityMask(ArrayRef<int> Mask, int NumSrcElts);
2027 static bool isIdentityMask(const Constant *Mask, int NumSrcElts) {
2028 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2029
2030
2031
2032 if (isa<ScalableVectorType>(Mask->getType()))
2033 return false;
2034
2035 SmallVector<int, 16> MaskAsInts;
2036 getShuffleMask(Mask, MaskAsInts);
2037 return isIdentityMask(MaskAsInts, NumSrcElts);
2038 }
2039
2040
2041
2042
2043
2044 bool isIdentity() const {
2045
2046
2047 if (isa<ScalableVectorType>(getType()))
2048 return false;
2049
2050 return !changesLength() && isIdentityMask(ShuffleMask, ShuffleMask.size());
2051 }
2052
2053
2054
2055 bool isIdentityWithPadding() const;
2056
2057
2058
2059 bool isIdentityWithExtract() const;
2060
2061
2062
2063
2064 bool isConcat() const;
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074 static bool isSelectMask(ArrayRef<int> Mask, int NumSrcElts);
2075 static bool isSelectMask(const Constant *Mask, int NumSrcElts) {
2076 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2077 SmallVector<int, 16> MaskAsInts;
2078 getShuffleMask(Mask, MaskAsInts);
2079 return isSelectMask(MaskAsInts, NumSrcElts);
2080 }
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090 bool isSelect() const {
2091 return !changesLength() && isSelectMask(ShuffleMask, ShuffleMask.size());
2092 }
2093
2094
2095
2096
2097
2098
2099 static bool isReverseMask(ArrayRef<int> Mask, int NumSrcElts);
2100 static bool isReverseMask(const Constant *Mask, int NumSrcElts) {
2101 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2102 SmallVector<int, 16> MaskAsInts;
2103 getShuffleMask(Mask, MaskAsInts);
2104 return isReverseMask(MaskAsInts, NumSrcElts);
2105 }
2106
2107
2108
2109
2110
2111 bool isReverse() const {
2112 return !changesLength() && isReverseMask(ShuffleMask, ShuffleMask.size());
2113 }
2114
2115
2116
2117
2118
2119
2120 static bool isZeroEltSplatMask(ArrayRef<int> Mask, int NumSrcElts);
2121 static bool isZeroEltSplatMask(const Constant *Mask, int NumSrcElts) {
2122 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2123 SmallVector<int, 16> MaskAsInts;
2124 getShuffleMask(Mask, MaskAsInts);
2125 return isZeroEltSplatMask(MaskAsInts, NumSrcElts);
2126 }
2127
2128
2129
2130
2131
2132
2133
2134 bool isZeroEltSplat() const {
2135 return !changesLength() &&
2136 isZeroEltSplatMask(ShuffleMask, ShuffleMask.size());
2137 }
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171 static bool isTransposeMask(ArrayRef<int> Mask, int NumSrcElts);
2172 static bool isTransposeMask(const Constant *Mask, int NumSrcElts) {
2173 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2174 SmallVector<int, 16> MaskAsInts;
2175 getShuffleMask(Mask, MaskAsInts);
2176 return isTransposeMask(MaskAsInts, NumSrcElts);
2177 }
2178
2179
2180
2181
2182
2183
2184 bool isTranspose() const {
2185 return !changesLength() && isTransposeMask(ShuffleMask, ShuffleMask.size());
2186 }
2187
2188
2189
2190
2191
2192
2193
2194 static bool isSpliceMask(ArrayRef<int> Mask, int NumSrcElts, int &Index);
2195 static bool isSpliceMask(const Constant *Mask, int NumSrcElts, int &Index) {
2196 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2197 SmallVector<int, 16> MaskAsInts;
2198 getShuffleMask(Mask, MaskAsInts);
2199 return isSpliceMask(MaskAsInts, NumSrcElts, Index);
2200 }
2201
2202
2203
2204
2205
2206 bool isSplice(int &Index) const {
2207 return !changesLength() &&
2208 isSpliceMask(ShuffleMask, ShuffleMask.size(), Index);
2209 }
2210
2211
2212
2213
2214 static bool isExtractSubvectorMask(ArrayRef<int> Mask, int NumSrcElts,
2215 int &Index);
2216 static bool isExtractSubvectorMask(const Constant *Mask, int NumSrcElts,
2217 int &Index) {
2218 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2219
2220
2221 if (isa<ScalableVectorType>(Mask->getType()))
2222 return false;
2223 SmallVector<int, 16> MaskAsInts;
2224 getShuffleMask(Mask, MaskAsInts);
2225 return isExtractSubvectorMask(MaskAsInts, NumSrcElts, Index);
2226 }
2227
2228
2229 bool isExtractSubvectorMask(int &Index) const {
2230
2231
2232 if (isa<ScalableVectorType>(getType()))
2233 return false;
2234
2235 int NumSrcElts =
2236 cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
2237 return isExtractSubvectorMask(ShuffleMask, NumSrcElts, Index);
2238 }
2239
2240
2241
2242
2243
2244 static bool isInsertSubvectorMask(ArrayRef<int> Mask, int NumSrcElts,
2245 int &NumSubElts, int &Index);
2246 static bool isInsertSubvectorMask(const Constant *Mask, int NumSrcElts,
2247 int &NumSubElts, int &Index) {
2248 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2249
2250
2251 if (isa<ScalableVectorType>(Mask->getType()))
2252 return false;
2253 SmallVector<int, 16> MaskAsInts;
2254 getShuffleMask(Mask, MaskAsInts);
2255 return isInsertSubvectorMask(MaskAsInts, NumSrcElts, NumSubElts, Index);
2256 }
2257
2258
2259 bool isInsertSubvectorMask(int &NumSubElts, int &Index) const {
2260
2261
2262 if (isa<ScalableVectorType>(getType()))
2263 return false;
2264
2265 int NumSrcElts =
2266 cast<FixedVectorType>(Op<0>()->getType())->getNumElements();
2267 return isInsertSubvectorMask(ShuffleMask, NumSrcElts, NumSubElts, Index);
2268 }
2269
2270
2271
2272
2273
2274 static bool isReplicationMask(ArrayRef<int> Mask, int &ReplicationFactor,
2275 int &VF);
2276 static bool isReplicationMask(const Constant *Mask, int &ReplicationFactor,
2277 int &VF) {
2278 assert(Mask->getType()->isVectorTy() && "Shuffle needs vector constant.");
2279
2280
2281 if (isa<ScalableVectorType>(Mask->getType()))
2282 return false;
2283 SmallVector<int, 16> MaskAsInts;
2284 getShuffleMask(Mask, MaskAsInts);
2285 return isReplicationMask(MaskAsInts, ReplicationFactor, VF);
2286 }
2287
2288
2289 bool isReplicationMask(int &ReplicationFactor, int &VF) const;
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300 static bool isOneUseSingleSourceMask(ArrayRef<int> Mask, int VF);
2301
2302
2303
2304 bool isOneUseSingleSourceMask(int VF) const;
2305
2306
2307
2308 static void commuteShuffleMask(MutableArrayRef<int> Mask,
2309 unsigned InVecNumElts) {
2310 for (int &Idx : Mask) {
2311 if (Idx == -1)
2312 continue;
2313 Idx = Idx < (int)InVecNumElts ? Idx + InVecNumElts : Idx - InVecNumElts;
2314 assert(Idx >= 0 && Idx < (int)InVecNumElts * 2 &&
2315 "shufflevector mask index out of range");
2316 }
2317 }
2318
2319
2320 bool isInterleave(unsigned Factor);
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341 static bool isInterleaveMask(ArrayRef<int> Mask, unsigned Factor,
2342 unsigned NumInputElts,
2343 SmallVectorImpl<unsigned> &StartIndexes);
2344 static bool isInterleaveMask(ArrayRef<int> Mask, unsigned Factor,
2345 unsigned NumInputElts) {
2346 SmallVector<unsigned, 8> StartIndexes;
2347 return isInterleaveMask(Mask, Factor, NumInputElts, StartIndexes);
2348 }
2349
2350
2351
2352
2353 static bool isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, unsigned Factor,
2354 unsigned &Index);
2355 static bool isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, unsigned Factor) {
2356 unsigned Unused;
2357 return isDeInterleaveMaskOfFactor(Mask, Factor, Unused);
2358 }
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371 static bool isBitRotateMask(ArrayRef<int> Mask, unsigned EltSizeInBits,
2372 unsigned MinSubElts, unsigned MaxSubElts,
2373 unsigned &NumSubElts, unsigned &RotateAmt);
2374
2375
2376 static bool classof(const Instruction *I) {
2377 return I->getOpcode() == Instruction::ShuffleVector;
2378 }
2379 static bool classof(const Value *V) {
2380 return isa<Instruction>(V) && classof(cast<Instruction>(V));
2381 }
2382 };
2383
2384 template <>
2385 struct OperandTraits<ShuffleVectorInst>
2386 : public FixedNumOperandTraits<ShuffleVectorInst, 2> {};
2387
2388 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value)
2389
2390
2391
2392
2393
2394
2395
2396
2397 class ExtractValueInst : public UnaryInstruction {
2398 SmallVector<unsigned, 4> Indices;
2399
2400 ExtractValueInst(const ExtractValueInst &EVI);
2401
2402
2403
2404
2405
2406 inline ExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
2407 const Twine &NameStr, InsertPosition InsertBefore);
2408
2409 void init(ArrayRef<unsigned> Idxs, const Twine &NameStr);
2410
2411 protected:
2412
2413 friend class Instruction;
2414
2415 ExtractValueInst *cloneImpl() const;
2416
2417 public:
2418 static ExtractValueInst *Create(Value *Agg, ArrayRef<unsigned> Idxs,
2419 const Twine &NameStr = "",
2420 InsertPosition InsertBefore = nullptr) {
2421 return new
2422 ExtractValueInst(Agg, Idxs, NameStr, InsertBefore);
2423 }
2424
2425
2426
2427
2428
2429 static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs);
2430
2431 using idx_iterator = const unsigned*;
2432
2433 inline idx_iterator idx_begin() const { return Indices.begin(); }
2434 inline idx_iterator idx_end() const { return Indices.end(); }
2435 inline iterator_range<idx_iterator> indices() const {
2436 return make_range(idx_begin(), idx_end());
2437 }
2438
2439 Value *getAggregateOperand() {
2440 return getOperand(0);
2441 }
2442 const Value *getAggregateOperand() const {
2443 return getOperand(0);
2444 }
2445 static unsigned getAggregateOperandIndex() {
2446 return 0U;
2447 }
2448
2449 ArrayRef<unsigned> getIndices() const {
2450 return Indices;
2451 }
2452
2453 unsigned getNumIndices() const {
2454 return (unsigned)Indices.size();
2455 }
2456
2457 bool hasIndices() const {
2458 return true;
2459 }
2460
2461
2462 static bool classof(const Instruction *I) {
2463 return I->getOpcode() == Instruction::ExtractValue;
2464 }
2465 static bool classof(const Value *V) {
2466 return isa<Instruction>(V) && classof(cast<Instruction>(V));
2467 }
2468 };
2469
2470 ExtractValueInst::ExtractValueInst(Value *Agg, ArrayRef<unsigned> Idxs,
2471 const Twine &NameStr,
2472 InsertPosition InsertBefore)
2473 : UnaryInstruction(checkGEPType(getIndexedType(Agg->getType(), Idxs)),
2474 ExtractValue, Agg, InsertBefore) {
2475 init(Idxs, NameStr);
2476 }
2477
2478
2479
2480
2481
2482
2483
2484
2485 class InsertValueInst : public Instruction {
2486 constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
2487
2488 SmallVector<unsigned, 4> Indices;
2489
2490 InsertValueInst(const InsertValueInst &IVI);
2491
2492
2493
2494
2495
2496 inline InsertValueInst(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
2497 const Twine &NameStr, InsertPosition InsertBefore);
2498
2499
2500
2501 InsertValueInst(Value *Agg, Value *Val, unsigned Idx,
2502 const Twine &NameStr = "",
2503 InsertPosition InsertBefore = nullptr);
2504
2505 void init(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
2506 const Twine &NameStr);
2507
2508 protected:
2509
2510 friend class Instruction;
2511
2512 InsertValueInst *cloneImpl() const;
2513
2514 public:
2515
2516 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
2517 void operator delete(void *Ptr) { User::operator delete(Ptr); }
2518
2519 static InsertValueInst *Create(Value *Agg, Value *Val,
2520 ArrayRef<unsigned> Idxs,
2521 const Twine &NameStr = "",
2522 InsertPosition InsertBefore = nullptr) {
2523 return new InsertValueInst(Agg, Val, Idxs, NameStr, InsertBefore);
2524 }
2525
2526
2527 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
2528
2529 using idx_iterator = const unsigned*;
2530
2531 inline idx_iterator idx_begin() const { return Indices.begin(); }
2532 inline idx_iterator idx_end() const { return Indices.end(); }
2533 inline iterator_range<idx_iterator> indices() const {
2534 return make_range(idx_begin(), idx_end());
2535 }
2536
2537 Value *getAggregateOperand() {
2538 return getOperand(0);
2539 }
2540 const Value *getAggregateOperand() const {
2541 return getOperand(0);
2542 }
2543 static unsigned getAggregateOperandIndex() {
2544 return 0U;
2545 }
2546
2547 Value *getInsertedValueOperand() {
2548 return getOperand(1);
2549 }
2550 const Value *getInsertedValueOperand() const {
2551 return getOperand(1);
2552 }
2553 static unsigned getInsertedValueOperandIndex() {
2554 return 1U;
2555 }
2556
2557 ArrayRef<unsigned> getIndices() const {
2558 return Indices;
2559 }
2560
2561 unsigned getNumIndices() const {
2562 return (unsigned)Indices.size();
2563 }
2564
2565 bool hasIndices() const {
2566 return true;
2567 }
2568
2569
2570 static bool classof(const Instruction *I) {
2571 return I->getOpcode() == Instruction::InsertValue;
2572 }
2573 static bool classof(const Value *V) {
2574 return isa<Instruction>(V) && classof(cast<Instruction>(V));
2575 }
2576 };
2577
2578 template <>
2579 struct OperandTraits<InsertValueInst> :
2580 public FixedNumOperandTraits<InsertValueInst, 2> {
2581 };
2582
2583 InsertValueInst::InsertValueInst(Value *Agg, Value *Val,
2584 ArrayRef<unsigned> Idxs, const Twine &NameStr,
2585 InsertPosition InsertBefore)
2586 : Instruction(Agg->getType(), InsertValue, AllocMarker, InsertBefore) {
2587 init(Agg, Val, Idxs, NameStr);
2588 }
2589
2590 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value)
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600 class PHINode : public Instruction {
2601 constexpr static HungOffOperandsAllocMarker AllocMarker{};
2602
2603
2604
2605 unsigned ReservedSpace;
2606
2607 PHINode(const PHINode &PN);
2608
2609 explicit PHINode(Type *Ty, unsigned NumReservedValues,
2610 const Twine &NameStr = "",
2611 InsertPosition InsertBefore = nullptr)
2612 : Instruction(Ty, Instruction::PHI, AllocMarker, InsertBefore),
2613 ReservedSpace(NumReservedValues) {
2614 assert(!Ty->isTokenTy() && "PHI nodes cannot have token type!");
2615 setName(NameStr);
2616 allocHungoffUses(ReservedSpace);
2617 }
2618
2619 protected:
2620
2621 friend class Instruction;
2622
2623 PHINode *cloneImpl() const;
2624
2625
2626
2627
2628 void allocHungoffUses(unsigned N) {
2629 User::allocHungoffUses(N, true);
2630 }
2631
2632 public:
2633
2634
2635 static PHINode *Create(Type *Ty, unsigned NumReservedValues,
2636 const Twine &NameStr = "",
2637 InsertPosition InsertBefore = nullptr) {
2638 return new (AllocMarker)
2639 PHINode(Ty, NumReservedValues, NameStr, InsertBefore);
2640 }
2641
2642
2643 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
2644
2645
2646
2647
2648
2649
2650 using block_iterator = BasicBlock **;
2651 using const_block_iterator = BasicBlock * const *;
2652
2653 const_block_iterator block_begin() const {
2654 return reinterpret_cast<const_block_iterator>(op_begin() + ReservedSpace);
2655 }
2656
2657 const_block_iterator block_end() const {
2658 return block_begin() + getNumOperands();
2659 }
2660
2661 iterator_range<const_block_iterator> blocks() const {
2662 return make_range(block_begin(), block_end());
2663 }
2664
2665 op_range incoming_values() { return operands(); }
2666
2667 const_op_range incoming_values() const { return operands(); }
2668
2669
2670
2671 unsigned getNumIncomingValues() const { return getNumOperands(); }
2672
2673
2674
2675 Value *getIncomingValue(unsigned i) const {
2676 return getOperand(i);
2677 }
2678 void setIncomingValue(unsigned i, Value *V) {
2679 assert(V && "PHI node got a null value!");
2680 assert(getType() == V->getType() &&
2681 "All operands to PHI node must be the same type as the PHI node!");
2682 setOperand(i, V);
2683 }
2684
2685 static unsigned getOperandNumForIncomingValue(unsigned i) {
2686 return i;
2687 }
2688
2689 static unsigned getIncomingValueNumForOperand(unsigned i) {
2690 return i;
2691 }
2692
2693
2694
2695 BasicBlock *getIncomingBlock(unsigned i) const {
2696 return block_begin()[i];
2697 }
2698
2699
2700
2701
2702 BasicBlock *getIncomingBlock(const Use &U) const {
2703 assert(this == U.getUser() && "Iterator doesn't point to PHI's Uses?");
2704 return getIncomingBlock(unsigned(&U - op_begin()));
2705 }
2706
2707
2708
2709
2710 BasicBlock *getIncomingBlock(Value::const_user_iterator I) const {
2711 return getIncomingBlock(I.getUse());
2712 }
2713
2714 void setIncomingBlock(unsigned i, BasicBlock *BB) {
2715 const_cast<block_iterator>(block_begin())[i] = BB;
2716 }
2717
2718
2719
2720 void copyIncomingBlocks(iterator_range<const_block_iterator> BBRange,
2721 uint32_t ToIdx = 0) {
2722 copy(BBRange, const_cast<block_iterator>(block_begin()) + ToIdx);
2723 }
2724
2725
2726 void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) {
2727 assert(New && Old && "PHI node got a null basic block!");
2728 for (unsigned Op = 0, NumOps = getNumOperands(); Op != NumOps; ++Op)
2729 if (getIncomingBlock(Op) == Old)
2730 setIncomingBlock(Op, New);
2731 }
2732
2733
2734
2735 void addIncoming(Value *V, BasicBlock *BB) {
2736 if (getNumOperands() == ReservedSpace)
2737 growOperands();
2738
2739 setNumHungOffUseOperands(getNumOperands() + 1);
2740 setIncomingValue(getNumOperands() - 1, V);
2741 setIncomingBlock(getNumOperands() - 1, BB);
2742 }
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752 Value *removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty = true);
2753
2754 Value *removeIncomingValue(const BasicBlock *BB, bool DeletePHIIfEmpty=true) {
2755 int Idx = getBasicBlockIndex(BB);
2756 assert(Idx >= 0 && "Invalid basic block argument to remove!");
2757 return removeIncomingValue(Idx, DeletePHIIfEmpty);
2758 }
2759
2760
2761
2762 void removeIncomingValueIf(function_ref<bool(unsigned)> Predicate,
2763 bool DeletePHIIfEmpty = true);
2764
2765
2766
2767
2768 int getBasicBlockIndex(const BasicBlock *BB) const {
2769 for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
2770 if (block_begin()[i] == BB)
2771 return i;
2772 return -1;
2773 }
2774
2775 Value *getIncomingValueForBlock(const BasicBlock *BB) const {
2776 int Idx = getBasicBlockIndex(BB);
2777 assert(Idx >= 0 && "Invalid basic block argument!");
2778 return getIncomingValue(Idx);
2779 }
2780
2781
2782 void setIncomingValueForBlock(const BasicBlock *BB, Value *V) {
2783 assert(BB && "PHI node got a null basic block!");
2784 bool Found = false;
2785 for (unsigned Op = 0, NumOps = getNumOperands(); Op != NumOps; ++Op)
2786 if (getIncomingBlock(Op) == BB) {
2787 Found = true;
2788 setIncomingValue(Op, V);
2789 }
2790 (void)Found;
2791 assert(Found && "Invalid basic block argument to set!");
2792 }
2793
2794
2795
2796 Value *hasConstantValue() const;
2797
2798
2799
2800
2801 bool hasConstantOrUndefValue() const;
2802
2803
2804
2805 bool isComplete() const {
2806 return llvm::all_of(predecessors(getParent()),
2807 [this](const BasicBlock *Pred) {
2808 return getBasicBlockIndex(Pred) >= 0;
2809 });
2810 }
2811
2812
2813 static bool classof(const Instruction *I) {
2814 return I->getOpcode() == Instruction::PHI;
2815 }
2816 static bool classof(const Value *V) {
2817 return isa<Instruction>(V) && classof(cast<Instruction>(V));
2818 }
2819
2820 private:
2821 void growOperands();
2822 };
2823
2824 template <> struct OperandTraits<PHINode> : public HungoffOperandTraits {};
2825
2826 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value)
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840 class LandingPadInst : public Instruction {
2841 using CleanupField = BoolBitfieldElementT<0>;
2842
2843 constexpr static HungOffOperandsAllocMarker AllocMarker{};
2844
2845
2846
2847 unsigned ReservedSpace;
2848
2849 LandingPadInst(const LandingPadInst &LP);
2850
2851 public:
2852 enum ClauseType { Catch, Filter };
2853
2854 private:
2855 explicit LandingPadInst(Type *RetTy, unsigned NumReservedValues,
2856 const Twine &NameStr, InsertPosition InsertBefore);
2857
2858
2859 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
2860
2861 void growOperands(unsigned Size);
2862 void init(unsigned NumReservedValues, const Twine &NameStr);
2863
2864 protected:
2865
2866 friend class Instruction;
2867
2868 LandingPadInst *cloneImpl() const;
2869
2870 public:
2871 void operator delete(void *Ptr) { User::operator delete(Ptr); }
2872
2873
2874
2875 static LandingPadInst *Create(Type *RetTy, unsigned NumReservedClauses,
2876 const Twine &NameStr = "",
2877 InsertPosition InsertBefore = nullptr);
2878
2879
2880 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
2881
2882
2883
2884
2885 bool isCleanup() const { return getSubclassData<CleanupField>(); }
2886
2887
2888 void setCleanup(bool V) { setSubclassData<CleanupField>(V); }
2889
2890
2891 void addClause(Constant *ClauseVal);
2892
2893
2894
2895 Constant *getClause(unsigned Idx) const {
2896 return cast<Constant>(getOperandList()[Idx]);
2897 }
2898
2899
2900 bool isCatch(unsigned Idx) const {
2901 return !isa<ArrayType>(getOperandList()[Idx]->getType());
2902 }
2903
2904
2905 bool isFilter(unsigned Idx) const {
2906 return isa<ArrayType>(getOperandList()[Idx]->getType());
2907 }
2908
2909
2910 unsigned getNumClauses() const { return getNumOperands(); }
2911
2912
2913
2914 void reserveClauses(unsigned Size) { growOperands(Size); }
2915
2916
2917 static bool classof(const Instruction *I) {
2918 return I->getOpcode() == Instruction::LandingPad;
2919 }
2920 static bool classof(const Value *V) {
2921 return isa<Instruction>(V) && classof(cast<Instruction>(V));
2922 }
2923 };
2924
2925 template <>
2926 struct OperandTraits<LandingPadInst> : public HungoffOperandTraits {};
2927
2928 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value)
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938 class ReturnInst : public Instruction {
2939 ReturnInst(const ReturnInst &RI, AllocInfo AllocInfo);
2940
2941 private:
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955 explicit ReturnInst(LLVMContext &C, Value *retVal, AllocInfo AllocInfo,
2956 InsertPosition InsertBefore);
2957
2958 protected:
2959
2960 friend class Instruction;
2961
2962 ReturnInst *cloneImpl() const;
2963
2964 public:
2965 static ReturnInst *Create(LLVMContext &C, Value *retVal = nullptr,
2966 InsertPosition InsertBefore = nullptr) {
2967 IntrusiveOperandsAllocMarker AllocMarker{retVal ? 1U : 0U};
2968 return new (AllocMarker) ReturnInst(C, retVal, AllocMarker, InsertBefore);
2969 }
2970
2971 static ReturnInst *Create(LLVMContext &C, BasicBlock *InsertAtEnd) {
2972 IntrusiveOperandsAllocMarker AllocMarker{0};
2973 return new (AllocMarker) ReturnInst(C, nullptr, AllocMarker, InsertAtEnd);
2974 }
2975
2976
2977 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
2978
2979
2980 Value *getReturnValue() const {
2981 return getNumOperands() != 0 ? getOperand(0) : nullptr;
2982 }
2983
2984 unsigned getNumSuccessors() const { return 0; }
2985
2986
2987 static bool classof(const Instruction *I) {
2988 return (I->getOpcode() == Instruction::Ret);
2989 }
2990 static bool classof(const Value *V) {
2991 return isa<Instruction>(V) && classof(cast<Instruction>(V));
2992 }
2993
2994 private:
2995 BasicBlock *getSuccessor(unsigned idx) const {
2996 llvm_unreachable("ReturnInst has no successors!");
2997 }
2998
2999 void setSuccessor(unsigned idx, BasicBlock *B) {
3000 llvm_unreachable("ReturnInst has no successors!");
3001 }
3002 };
3003
3004 template <>
3005 struct OperandTraits<ReturnInst> : public VariadicOperandTraits<ReturnInst> {};
3006
3007 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value)
3008
3009
3010
3011
3012
3013
3014
3015
3016 class BranchInst : public Instruction {
3017
3018
3019
3020
3021 BranchInst(const BranchInst &BI, AllocInfo AllocInfo);
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031 explicit BranchInst(BasicBlock *IfTrue, AllocInfo AllocInfo,
3032 InsertPosition InsertBefore);
3033 BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
3034 AllocInfo AllocInfo, InsertPosition InsertBefore);
3035
3036 void AssertOK();
3037
3038 protected:
3039
3040 friend class Instruction;
3041
3042 BranchInst *cloneImpl() const;
3043
3044 public:
3045
3046
3047
3048
3049 struct succ_op_iterator
3050 : iterator_adaptor_base<succ_op_iterator, value_op_iterator,
3051 std::random_access_iterator_tag, BasicBlock *,
3052 ptrdiff_t, BasicBlock *, BasicBlock *> {
3053 explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {}
3054
3055 BasicBlock *operator*() const { return cast<BasicBlock>(*I); }
3056 BasicBlock *operator->() const { return operator*(); }
3057 };
3058
3059
3060 struct const_succ_op_iterator
3061 : iterator_adaptor_base<const_succ_op_iterator, const_value_op_iterator,
3062 std::random_access_iterator_tag,
3063 const BasicBlock *, ptrdiff_t, const BasicBlock *,
3064 const BasicBlock *> {
3065 explicit const_succ_op_iterator(const_value_op_iterator I)
3066 : iterator_adaptor_base(I) {}
3067
3068 const BasicBlock *operator*() const { return cast<BasicBlock>(*I); }
3069 const BasicBlock *operator->() const { return operator*(); }
3070 };
3071
3072 static BranchInst *Create(BasicBlock *IfTrue,
3073 InsertPosition InsertBefore = nullptr) {
3074 IntrusiveOperandsAllocMarker AllocMarker{1};
3075 return new (AllocMarker) BranchInst(IfTrue, AllocMarker, InsertBefore);
3076 }
3077
3078 static BranchInst *Create(BasicBlock *IfTrue, BasicBlock *IfFalse,
3079 Value *Cond,
3080 InsertPosition InsertBefore = nullptr) {
3081 IntrusiveOperandsAllocMarker AllocMarker{3};
3082 return new (AllocMarker)
3083 BranchInst(IfTrue, IfFalse, Cond, AllocMarker, InsertBefore);
3084 }
3085
3086
3087 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
3088
3089 bool isUnconditional() const { return getNumOperands() == 1; }
3090 bool isConditional() const { return getNumOperands() == 3; }
3091
3092 Value *getCondition() const {
3093 assert(isConditional() && "Cannot get condition of an uncond branch!");
3094 return Op<-3>();
3095 }
3096
3097 void setCondition(Value *V) {
3098 assert(isConditional() && "Cannot set condition of unconditional branch!");
3099 Op<-3>() = V;
3100 }
3101
3102 unsigned getNumSuccessors() const { return 1+isConditional(); }
3103
3104 BasicBlock *getSuccessor(unsigned i) const {
3105 assert(i < getNumSuccessors() && "Successor # out of range for Branch!");
3106 return cast_or_null<BasicBlock>((&Op<-1>() - i)->get());
3107 }
3108
3109 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
3110 assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
3111 *(&Op<-1>() - idx) = NewSucc;
3112 }
3113
3114
3115
3116
3117
3118
3119 void swapSuccessors();
3120
3121 iterator_range<succ_op_iterator> successors() {
3122 return make_range(
3123 succ_op_iterator(std::next(value_op_begin(), isConditional() ? 1 : 0)),
3124 succ_op_iterator(value_op_end()));
3125 }
3126
3127 iterator_range<const_succ_op_iterator> successors() const {
3128 return make_range(const_succ_op_iterator(
3129 std::next(value_op_begin(), isConditional() ? 1 : 0)),
3130 const_succ_op_iterator(value_op_end()));
3131 }
3132
3133
3134 static bool classof(const Instruction *I) {
3135 return (I->getOpcode() == Instruction::Br);
3136 }
3137 static bool classof(const Value *V) {
3138 return isa<Instruction>(V) && classof(cast<Instruction>(V));
3139 }
3140 };
3141
3142 template <>
3143 struct OperandTraits<BranchInst> : public VariadicOperandTraits<BranchInst> {};
3144
3145 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BranchInst, Value)
3146
3147
3148
3149
3150
3151
3152
3153
3154 class SwitchInst : public Instruction {
3155 constexpr static HungOffOperandsAllocMarker AllocMarker{};
3156
3157 unsigned ReservedSpace;
3158
3159
3160
3161
3162
3163 SwitchInst(const SwitchInst &SI);
3164
3165
3166
3167
3168
3169 SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
3170 InsertPosition InsertBefore);
3171
3172
3173 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
3174
3175 void init(Value *Value, BasicBlock *Default, unsigned NumReserved);
3176 void growOperands();
3177
3178 protected:
3179
3180 friend class Instruction;
3181
3182 SwitchInst *cloneImpl() const;
3183
3184 public:
3185 void operator delete(void *Ptr) { User::operator delete(Ptr); }
3186
3187
3188 static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
3189
3190 template <typename CaseHandleT> class CaseIteratorImpl;
3191
3192
3193
3194
3195
3196
3197 template <typename SwitchInstT, typename ConstantIntT, typename BasicBlockT>
3198 class CaseHandleImpl {
3199
3200 friend class SwitchInst::CaseIteratorImpl<
3201 CaseHandleImpl<SwitchInstT, ConstantIntT, BasicBlockT>>;
3202
3203 protected:
3204
3205 using SwitchInstType = SwitchInstT;
3206
3207 SwitchInstT *SI;
3208 ptrdiff_t Index;
3209
3210 CaseHandleImpl() = default;
3211 CaseHandleImpl(SwitchInstT *SI, ptrdiff_t Index) : SI(SI), Index(Index) {}
3212
3213 public:
3214
3215 ConstantIntT *getCaseValue() const {
3216 assert((unsigned)Index < SI->getNumCases() &&
3217 "Index out the number of cases.");
3218 return reinterpret_cast<ConstantIntT *>(SI->getOperand(2 + Index * 2));
3219 }
3220
3221
3222 BasicBlockT *getCaseSuccessor() const {
3223 assert(((unsigned)Index < SI->getNumCases() ||
3224 (unsigned)Index == DefaultPseudoIndex) &&
3225 "Index out the number of cases.");
3226 return SI->getSuccessor(getSuccessorIndex());
3227 }
3228
3229
3230 unsigned getCaseIndex() const { return Index; }
3231
3232
3233 unsigned getSuccessorIndex() const {
3234 assert(((unsigned)Index == DefaultPseudoIndex ||
3235 (unsigned)Index < SI->getNumCases()) &&
3236 "Index out the number of cases.");
3237 return (unsigned)Index != DefaultPseudoIndex ? Index + 1 : 0;
3238 }
3239
3240 bool operator==(const CaseHandleImpl &RHS) const {
3241 assert(SI == RHS.SI && "Incompatible operators.");
3242 return Index == RHS.Index;
3243 }
3244 };
3245
3246 using ConstCaseHandle =
3247 CaseHandleImpl<const SwitchInst, const ConstantInt, const BasicBlock>;
3248
3249 class CaseHandle
3250 : public CaseHandleImpl<SwitchInst, ConstantInt, BasicBlock> {
3251 friend class SwitchInst::CaseIteratorImpl<CaseHandle>;
3252
3253 public:
3254 CaseHandle(SwitchInst *SI, ptrdiff_t Index) : CaseHandleImpl(SI, Index) {}
3255
3256
3257 void setValue(ConstantInt *V) const {
3258 assert((unsigned)Index < SI->getNumCases() &&
3259 "Index out the number of cases.");
3260 SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
3261 }
3262
3263
3264 void setSuccessor(BasicBlock *S) const {
3265 SI->setSuccessor(getSuccessorIndex(), S);
3266 }
3267 };
3268
3269 template <typename CaseHandleT>
3270 class CaseIteratorImpl
3271 : public iterator_facade_base<CaseIteratorImpl<CaseHandleT>,
3272 std::random_access_iterator_tag,
3273 const CaseHandleT> {
3274 using SwitchInstT = typename CaseHandleT::SwitchInstType;
3275
3276 CaseHandleT Case;
3277
3278 public:
3279
3280
3281 CaseIteratorImpl() = default;
3282
3283
3284
3285 CaseIteratorImpl(SwitchInstT *SI, unsigned CaseNum) : Case(SI, CaseNum) {}
3286
3287
3288
3289 static CaseIteratorImpl fromSuccessorIndex(SwitchInstT *SI,
3290 unsigned SuccessorIndex) {
3291 assert(SuccessorIndex < SI->getNumSuccessors() &&
3292 "Successor index # out of range!");
3293 return SuccessorIndex != 0 ? CaseIteratorImpl(SI, SuccessorIndex - 1)
3294 : CaseIteratorImpl(SI, DefaultPseudoIndex);
3295 }
3296
3297
3298
3299 operator CaseIteratorImpl<ConstCaseHandle>() const {
3300 return CaseIteratorImpl<ConstCaseHandle>(Case.SI, Case.Index);
3301 }
3302
3303 CaseIteratorImpl &operator+=(ptrdiff_t N) {
3304
3305
3306 assert(Case.Index + N >= 0 &&
3307 (unsigned)(Case.Index + N) <= Case.SI->getNumCases() &&
3308 "Case.Index out the number of cases.");
3309 Case.Index += N;
3310 return *this;
3311 }
3312 CaseIteratorImpl &operator-=(ptrdiff_t N) {
3313
3314
3315 assert(Case.Index - N >= 0 &&
3316 (unsigned)(Case.Index - N) <= Case.SI->getNumCases() &&
3317 "Case.Index out the number of cases.");
3318 Case.Index -= N;
3319 return *this;
3320 }
3321 ptrdiff_t operator-(const CaseIteratorImpl &RHS) const {
3322 assert(Case.SI == RHS.Case.SI && "Incompatible operators.");
3323 return Case.Index - RHS.Case.Index;
3324 }
3325 bool operator==(const CaseIteratorImpl &RHS) const {
3326 return Case == RHS.Case;
3327 }
3328 bool operator<(const CaseIteratorImpl &RHS) const {
3329 assert(Case.SI == RHS.Case.SI && "Incompatible operators.");
3330 return Case.Index < RHS.Case.Index;
3331 }
3332 const CaseHandleT &operator*() const { return Case; }
3333 };
3334
3335 using CaseIt = CaseIteratorImpl<CaseHandle>;
3336 using ConstCaseIt = CaseIteratorImpl<ConstCaseHandle>;
3337
3338 static SwitchInst *Create(Value *Value, BasicBlock *Default,
3339 unsigned NumCases,
3340 InsertPosition InsertBefore = nullptr) {
3341 return new SwitchInst(Value, Default, NumCases, InsertBefore);
3342 }
3343
3344
3345 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
3346
3347
3348 Value *getCondition() const { return getOperand(0); }
3349 void setCondition(Value *V) { setOperand(0, V); }
3350
3351 BasicBlock *getDefaultDest() const {
3352 return cast<BasicBlock>(getOperand(1));
3353 }
3354
3355
3356
3357 bool defaultDestUndefined() const {
3358 return isa<UnreachableInst>(getDefaultDest()->getFirstNonPHIOrDbg());
3359 }
3360
3361 void setDefaultDest(BasicBlock *DefaultCase) {
3362 setOperand(1, reinterpret_cast<Value*>(DefaultCase));
3363 }
3364
3365
3366
3367 unsigned getNumCases() const {
3368 return getNumOperands()/2 - 1;
3369 }
3370
3371
3372
3373 CaseIt case_begin() {
3374 return CaseIt(this, 0);
3375 }
3376
3377
3378
3379 ConstCaseIt case_begin() const {
3380 return ConstCaseIt(this, 0);
3381 }
3382
3383
3384
3385 CaseIt case_end() {
3386 return CaseIt(this, getNumCases());
3387 }
3388
3389
3390
3391 ConstCaseIt case_end() const {
3392 return ConstCaseIt(this, getNumCases());
3393 }
3394
3395
3396 iterator_range<CaseIt> cases() {
3397 return make_range(case_begin(), case_end());
3398 }
3399
3400
3401 iterator_range<ConstCaseIt> cases() const {
3402 return make_range(case_begin(), case_end());
3403 }
3404
3405
3406
3407
3408
3409
3410 CaseIt case_default() {
3411 return CaseIt(this, DefaultPseudoIndex);
3412 }
3413 ConstCaseIt case_default() const {
3414 return ConstCaseIt(this, DefaultPseudoIndex);
3415 }
3416
3417
3418
3419
3420
3421 CaseIt findCaseValue(const ConstantInt *C) {
3422 return CaseIt(
3423 this,
3424 const_cast<const SwitchInst *>(this)->findCaseValue(C)->getCaseIndex());
3425 }
3426 ConstCaseIt findCaseValue(const ConstantInt *C) const {
3427 ConstCaseIt I = llvm::find_if(cases(), [C](const ConstCaseHandle &Case) {
3428 return Case.getCaseValue() == C;
3429 });
3430 if (I != case_end())
3431 return I;
3432
3433 return case_default();
3434 }
3435
3436
3437
3438 ConstantInt *findCaseDest(BasicBlock *BB) {
3439 if (BB == getDefaultDest())
3440 return nullptr;
3441
3442 ConstantInt *CI = nullptr;
3443 for (auto Case : cases()) {
3444 if (Case.getCaseSuccessor() != BB)
3445 continue;
3446
3447 if (CI)
3448 return nullptr;
3449
3450 CI = Case.getCaseValue();
3451 }
3452
3453 return CI;
3454 }
3455
3456
3457
3458
3459
3460 void addCase(ConstantInt *OnVal, BasicBlock *Dest);
3461
3462
3463
3464
3465
3466
3467
3468
3469 CaseIt removeCase(CaseIt I);
3470
3471 unsigned getNumSuccessors() const { return getNumOperands()/2; }
3472 BasicBlock *getSuccessor(unsigned idx) const {
3473 assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
3474 return cast<BasicBlock>(getOperand(idx*2+1));
3475 }
3476 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
3477 assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
3478 setOperand(idx * 2 + 1, NewSucc);
3479 }
3480
3481
3482 static bool classof(const Instruction *I) {
3483 return I->getOpcode() == Instruction::Switch;
3484 }
3485 static bool classof(const Value *V) {
3486 return isa<Instruction>(V) && classof(cast<Instruction>(V));
3487 }
3488 };
3489
3490
3491
3492 class SwitchInstProfUpdateWrapper {
3493 SwitchInst &SI;
3494 std::optional<SmallVector<uint32_t, 8>> Weights;
3495 bool Changed = false;
3496
3497 protected:
3498 MDNode *buildProfBranchWeightsMD();
3499
3500 void init();
3501
3502 public:
3503 using CaseWeightOpt = std::optional<uint32_t>;
3504 SwitchInst *operator->() { return &SI; }
3505 SwitchInst &operator*() { return SI; }
3506 operator SwitchInst *() { return &SI; }
3507
3508 SwitchInstProfUpdateWrapper(SwitchInst &SI) : SI(SI) { init(); }
3509
3510 ~SwitchInstProfUpdateWrapper() {
3511 if (Changed)
3512 SI.setMetadata(LLVMContext::MD_prof, buildProfBranchWeightsMD());
3513 }
3514
3515
3516
3517 SwitchInst::CaseIt removeCase(SwitchInst::CaseIt I);
3518
3519
3520
3521 void addCase(ConstantInt *OnVal, BasicBlock *Dest, CaseWeightOpt W);
3522
3523
3524
3525 Instruction::InstListType::iterator eraseFromParent();
3526
3527 void setSuccessorWeight(unsigned idx, CaseWeightOpt W);
3528 CaseWeightOpt getSuccessorWeight(unsigned idx);
3529
3530 static CaseWeightOpt getSuccessorWeight(const SwitchInst &SI, unsigned idx);
3531 };
3532
3533 template <> struct OperandTraits<SwitchInst> : public HungoffOperandTraits {};
3534
3535 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
3536
3537
3538
3539
3540
3541
3542
3543
3544 class IndirectBrInst : public Instruction {
3545 constexpr static HungOffOperandsAllocMarker AllocMarker{};
3546
3547 unsigned ReservedSpace;
3548
3549
3550
3551 IndirectBrInst(const IndirectBrInst &IBI);
3552
3553
3554
3555
3556
3557 IndirectBrInst(Value *Address, unsigned NumDests,
3558 InsertPosition InsertBefore);
3559
3560
3561 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
3562
3563 void init(Value *Address, unsigned NumDests);
3564 void growOperands();
3565
3566 protected:
3567
3568 friend class Instruction;
3569
3570 IndirectBrInst *cloneImpl() const;
3571
3572 public:
3573 void operator delete(void *Ptr) { User::operator delete(Ptr); }
3574
3575
3576
3577
3578
3579 struct succ_op_iterator
3580 : iterator_adaptor_base<succ_op_iterator, value_op_iterator,
3581 std::random_access_iterator_tag, BasicBlock *,
3582 ptrdiff_t, BasicBlock *, BasicBlock *> {
3583 explicit succ_op_iterator(value_op_iterator I) : iterator_adaptor_base(I) {}
3584
3585 BasicBlock *operator*() const { return cast<BasicBlock>(*I); }
3586 BasicBlock *operator->() const { return operator*(); }
3587 };
3588
3589
3590 struct const_succ_op_iterator
3591 : iterator_adaptor_base<const_succ_op_iterator, const_value_op_iterator,
3592 std::random_access_iterator_tag,
3593 const BasicBlock *, ptrdiff_t, const BasicBlock *,
3594 const BasicBlock *> {
3595 explicit const_succ_op_iterator(const_value_op_iterator I)
3596 : iterator_adaptor_base(I) {}
3597
3598 const BasicBlock *operator*() const { return cast<BasicBlock>(*I); }
3599 const BasicBlock *operator->() const { return operator*(); }
3600 };
3601
3602 static IndirectBrInst *Create(Value *Address, unsigned NumDests,
3603 InsertPosition InsertBefore = nullptr) {
3604 return new IndirectBrInst(Address, NumDests, InsertBefore);
3605 }
3606
3607
3608 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
3609
3610
3611 Value *getAddress() { return getOperand(0); }
3612 const Value *getAddress() const { return getOperand(0); }
3613 void setAddress(Value *V) { setOperand(0, V); }
3614
3615
3616
3617 unsigned getNumDestinations() const { return getNumOperands()-1; }
3618
3619
3620 BasicBlock *getDestination(unsigned i) { return getSuccessor(i); }
3621 const BasicBlock *getDestination(unsigned i) const { return getSuccessor(i); }
3622
3623
3624
3625 void addDestination(BasicBlock *Dest);
3626
3627
3628
3629 void removeDestination(unsigned i);
3630
3631 unsigned getNumSuccessors() const { return getNumOperands()-1; }
3632 BasicBlock *getSuccessor(unsigned i) const {
3633 return cast<BasicBlock>(getOperand(i+1));
3634 }
3635 void setSuccessor(unsigned i, BasicBlock *NewSucc) {
3636 setOperand(i + 1, NewSucc);
3637 }
3638
3639 iterator_range<succ_op_iterator> successors() {
3640 return make_range(succ_op_iterator(std::next(value_op_begin())),
3641 succ_op_iterator(value_op_end()));
3642 }
3643
3644 iterator_range<const_succ_op_iterator> successors() const {
3645 return make_range(const_succ_op_iterator(std::next(value_op_begin())),
3646 const_succ_op_iterator(value_op_end()));
3647 }
3648
3649
3650 static bool classof(const Instruction *I) {
3651 return I->getOpcode() == Instruction::IndirectBr;
3652 }
3653 static bool classof(const Value *V) {
3654 return isa<Instruction>(V) && classof(cast<Instruction>(V));
3655 }
3656 };
3657
3658 template <>
3659 struct OperandTraits<IndirectBrInst> : public HungoffOperandTraits {};
3660
3661 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(IndirectBrInst, Value)
3662
3663
3664
3665
3666
3667
3668
3669
3670 class InvokeInst : public CallBase {
3671
3672
3673 static constexpr int NumExtraOperands = 2;
3674
3675
3676 static constexpr int NormalDestOpEndIdx = -3;
3677
3678
3679 static constexpr int UnwindDestOpEndIdx = -2;
3680
3681 InvokeInst(const InvokeInst &BI, AllocInfo AllocInfo);
3682
3683
3684
3685
3686 inline InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
3687 BasicBlock *IfException, ArrayRef<Value *> Args,
3688 ArrayRef<OperandBundleDef> Bundles, AllocInfo AllocInfo,
3689 const Twine &NameStr, InsertPosition InsertBefore);
3690
3691 void init(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
3692 BasicBlock *IfException, ArrayRef<Value *> Args,
3693 ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
3694
3695
3696 static unsigned ComputeNumOperands(unsigned NumArgs,
3697 size_t NumBundleInputs = 0) {
3698
3699
3700 return 1 + NumExtraOperands + NumArgs + unsigned(NumBundleInputs);
3701 }
3702
3703 protected:
3704
3705 friend class Instruction;
3706
3707 InvokeInst *cloneImpl() const;
3708
3709 public:
3710 static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
3711 BasicBlock *IfException, ArrayRef<Value *> Args,
3712 const Twine &NameStr,
3713 InsertPosition InsertBefore = nullptr) {
3714 IntrusiveOperandsAllocMarker AllocMarker{
3715 ComputeNumOperands(unsigned(Args.size()))};
3716 return new (AllocMarker) InvokeInst(Ty, Func, IfNormal, IfException, Args,
3717 {}, AllocMarker, NameStr, InsertBefore);
3718 }
3719
3720 static InvokeInst *Create(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
3721 BasicBlock *IfException, ArrayRef<Value *> Args,
3722 ArrayRef<OperandBundleDef> Bundles = {},
3723 const Twine &NameStr = "",
3724 InsertPosition InsertBefore = nullptr) {
3725 IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
3726 ComputeNumOperands(Args.size(), CountBundleInputs(Bundles)),
3727 unsigned(Bundles.size() * sizeof(BundleOpInfo))};
3728
3729 return new (AllocMarker)
3730 InvokeInst(Ty, Func, IfNormal, IfException, Args, Bundles, AllocMarker,
3731 NameStr, InsertBefore);
3732 }
3733
3734 static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
3735 BasicBlock *IfException, ArrayRef<Value *> Args,
3736 const Twine &NameStr,
3737 InsertPosition InsertBefore = nullptr) {
3738 return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
3739 IfException, Args, {}, NameStr, InsertBefore);
3740 }
3741
3742 static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal,
3743 BasicBlock *IfException, ArrayRef<Value *> Args,
3744 ArrayRef<OperandBundleDef> Bundles = {},
3745 const Twine &NameStr = "",
3746 InsertPosition InsertBefore = nullptr) {
3747 return Create(Func.getFunctionType(), Func.getCallee(), IfNormal,
3748 IfException, Args, Bundles, NameStr, InsertBefore);
3749 }
3750
3751
3752
3753
3754
3755
3756
3757 static InvokeInst *Create(InvokeInst *II, ArrayRef<OperandBundleDef> Bundles,
3758 InsertPosition InsertPt = nullptr);
3759
3760
3761 BasicBlock *getNormalDest() const {
3762 return cast<BasicBlock>(Op<NormalDestOpEndIdx>());
3763 }
3764 BasicBlock *getUnwindDest() const {
3765 return cast<BasicBlock>(Op<UnwindDestOpEndIdx>());
3766 }
3767 void setNormalDest(BasicBlock *B) {
3768 Op<NormalDestOpEndIdx>() = reinterpret_cast<Value *>(B);
3769 }
3770 void setUnwindDest(BasicBlock *B) {
3771 Op<UnwindDestOpEndIdx>() = reinterpret_cast<Value *>(B);
3772 }
3773
3774
3775
3776 LandingPadInst *getLandingPadInst() const;
3777
3778 BasicBlock *getSuccessor(unsigned i) const {
3779 assert(i < 2 && "Successor # out of range for invoke!");
3780 return i == 0 ? getNormalDest() : getUnwindDest();
3781 }
3782
3783 void setSuccessor(unsigned i, BasicBlock *NewSucc) {
3784 assert(i < 2 && "Successor # out of range for invoke!");
3785 if (i == 0)
3786 setNormalDest(NewSucc);
3787 else
3788 setUnwindDest(NewSucc);
3789 }
3790
3791 unsigned getNumSuccessors() const { return 2; }
3792
3793
3794 void updateProfWeight(uint64_t S, uint64_t T);
3795
3796
3797 static bool classof(const Instruction *I) {
3798 return (I->getOpcode() == Instruction::Invoke);
3799 }
3800 static bool classof(const Value *V) {
3801 return isa<Instruction>(V) && classof(cast<Instruction>(V));
3802 }
3803
3804 private:
3805
3806
3807 template <typename Bitfield>
3808 void setSubclassData(typename Bitfield::Type Value) {
3809 Instruction::setSubclassData<Bitfield>(Value);
3810 }
3811 };
3812
3813 InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal,
3814 BasicBlock *IfException, ArrayRef<Value *> Args,
3815 ArrayRef<OperandBundleDef> Bundles, AllocInfo AllocInfo,
3816 const Twine &NameStr, InsertPosition InsertBefore)
3817 : CallBase(Ty->getReturnType(), Instruction::Invoke, AllocInfo,
3818 InsertBefore) {
3819 init(Ty, Func, IfNormal, IfException, Args, Bundles, NameStr);
3820 }
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830 class CallBrInst : public CallBase {
3831
3832 unsigned NumIndirectDests;
3833
3834 CallBrInst(const CallBrInst &BI, AllocInfo AllocInfo);
3835
3836
3837
3838
3839 inline CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest,
3840 ArrayRef<BasicBlock *> IndirectDests,
3841 ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles,
3842 AllocInfo AllocInfo, const Twine &NameStr,
3843 InsertPosition InsertBefore);
3844
3845 void init(FunctionType *FTy, Value *Func, BasicBlock *DefaultDest,
3846 ArrayRef<BasicBlock *> IndirectDests, ArrayRef<Value *> Args,
3847 ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr);
3848
3849
3850 static unsigned ComputeNumOperands(int NumArgs, int NumIndirectDests,
3851 int NumBundleInputs = 0) {
3852
3853
3854 return unsigned(2 + NumIndirectDests + NumArgs + NumBundleInputs);
3855 }
3856
3857 protected:
3858
3859 friend class Instruction;
3860
3861 CallBrInst *cloneImpl() const;
3862
3863 public:
3864 static CallBrInst *Create(FunctionType *Ty, Value *Func,
3865 BasicBlock *DefaultDest,
3866 ArrayRef<BasicBlock *> IndirectDests,
3867 ArrayRef<Value *> Args, const Twine &NameStr,
3868 InsertPosition InsertBefore = nullptr) {
3869 IntrusiveOperandsAllocMarker AllocMarker{
3870 ComputeNumOperands(Args.size(), IndirectDests.size())};
3871 return new (AllocMarker)
3872 CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, {}, AllocMarker,
3873 NameStr, InsertBefore);
3874 }
3875
3876 static CallBrInst *
3877 Create(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest,
3878 ArrayRef<BasicBlock *> IndirectDests, ArrayRef<Value *> Args,
3879 ArrayRef<OperandBundleDef> Bundles = {}, const Twine &NameStr = "",
3880 InsertPosition InsertBefore = nullptr) {
3881 IntrusiveOperandsAndDescriptorAllocMarker AllocMarker{
3882 ComputeNumOperands(Args.size(), IndirectDests.size(),
3883 CountBundleInputs(Bundles)),
3884 unsigned(Bundles.size() * sizeof(BundleOpInfo))};
3885
3886 return new (AllocMarker)
3887 CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, Bundles,
3888 AllocMarker, NameStr, InsertBefore);
3889 }
3890
3891 static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest,
3892 ArrayRef<BasicBlock *> IndirectDests,
3893 ArrayRef<Value *> Args, const Twine &NameStr,
3894 InsertPosition InsertBefore = nullptr) {
3895 return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest,
3896 IndirectDests, Args, NameStr, InsertBefore);
3897 }
3898
3899 static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest,
3900 ArrayRef<BasicBlock *> IndirectDests,
3901 ArrayRef<Value *> Args,
3902 ArrayRef<OperandBundleDef> Bundles = {},
3903 const Twine &NameStr = "",
3904 InsertPosition InsertBefore = nullptr) {
3905 return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest,
3906 IndirectDests, Args, Bundles, NameStr, InsertBefore);
3907 }
3908
3909
3910
3911
3912
3913
3914
3915 static CallBrInst *Create(CallBrInst *CBI, ArrayRef<OperandBundleDef> Bundles,
3916 InsertPosition InsertBefore = nullptr);
3917
3918
3919
3920 unsigned getNumIndirectDests() const { return NumIndirectDests; }
3921
3922
3923
3924 Value *getIndirectDestLabel(unsigned i) const {
3925 assert(i < getNumIndirectDests() && "Out of bounds!");
3926 return getOperand(i + arg_size() + getNumTotalBundleOperands() + 1);
3927 }
3928
3929 Value *getIndirectDestLabelUse(unsigned i) const {
3930 assert(i < getNumIndirectDests() && "Out of bounds!");
3931 return getOperandUse(i + arg_size() + getNumTotalBundleOperands() + 1);
3932 }
3933
3934
3935 BasicBlock *getDefaultDest() const {
3936 return cast<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() - 1));
3937 }
3938 BasicBlock *getIndirectDest(unsigned i) const {
3939 return cast_or_null<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() + i));
3940 }
3941 SmallVector<BasicBlock *, 16> getIndirectDests() const {
3942 SmallVector<BasicBlock *, 16> IndirectDests;
3943 for (unsigned i = 0, e = getNumIndirectDests(); i < e; ++i)
3944 IndirectDests.push_back(getIndirectDest(i));
3945 return IndirectDests;
3946 }
3947 void setDefaultDest(BasicBlock *B) {
3948 *(&Op<-1>() - getNumIndirectDests() - 1) = reinterpret_cast<Value *>(B);
3949 }
3950 void setIndirectDest(unsigned i, BasicBlock *B) {
3951 *(&Op<-1>() - getNumIndirectDests() + i) = reinterpret_cast<Value *>(B);
3952 }
3953
3954 BasicBlock *getSuccessor(unsigned i) const {
3955 assert(i < getNumSuccessors() + 1 &&
3956 "Successor # out of range for callbr!");
3957 return i == 0 ? getDefaultDest() : getIndirectDest(i - 1);
3958 }
3959
3960 void setSuccessor(unsigned i, BasicBlock *NewSucc) {
3961 assert(i < getNumIndirectDests() + 1 &&
3962 "Successor # out of range for callbr!");
3963 return i == 0 ? setDefaultDest(NewSucc) : setIndirectDest(i - 1, NewSucc);
3964 }
3965
3966 unsigned getNumSuccessors() const { return getNumIndirectDests() + 1; }
3967
3968
3969 static bool classof(const Instruction *I) {
3970 return (I->getOpcode() == Instruction::CallBr);
3971 }
3972 static bool classof(const Value *V) {
3973 return isa<Instruction>(V) && classof(cast<Instruction>(V));
3974 }
3975
3976 private:
3977
3978
3979 template <typename Bitfield>
3980 void setSubclassData(typename Bitfield::Type Value) {
3981 Instruction::setSubclassData<Bitfield>(Value);
3982 }
3983 };
3984
3985 CallBrInst::CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest,
3986 ArrayRef<BasicBlock *> IndirectDests,
3987 ArrayRef<Value *> Args,
3988 ArrayRef<OperandBundleDef> Bundles, AllocInfo AllocInfo,
3989 const Twine &NameStr, InsertPosition InsertBefore)
3990 : CallBase(Ty->getReturnType(), Instruction::CallBr, AllocInfo,
3991 InsertBefore) {
3992 init(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, NameStr);
3993 }
3994
3995
3996
3997
3998
3999
4000
4001
4002 class ResumeInst : public Instruction {
4003 constexpr static IntrusiveOperandsAllocMarker AllocMarker{1};
4004
4005 ResumeInst(const ResumeInst &RI);
4006
4007 explicit ResumeInst(Value *Exn, InsertPosition InsertBefore = nullptr);
4008
4009 protected:
4010
4011 friend class Instruction;
4012
4013 ResumeInst *cloneImpl() const;
4014
4015 public:
4016 static ResumeInst *Create(Value *Exn, InsertPosition InsertBefore = nullptr) {
4017 return new (AllocMarker) ResumeInst(Exn, InsertBefore);
4018 }
4019
4020
4021 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
4022
4023
4024 Value *getValue() const { return Op<0>(); }
4025
4026 unsigned getNumSuccessors() const { return 0; }
4027
4028
4029 static bool classof(const Instruction *I) {
4030 return I->getOpcode() == Instruction::Resume;
4031 }
4032 static bool classof(const Value *V) {
4033 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4034 }
4035
4036 private:
4037 BasicBlock *getSuccessor(unsigned idx) const {
4038 llvm_unreachable("ResumeInst has no successors!");
4039 }
4040
4041 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
4042 llvm_unreachable("ResumeInst has no successors!");
4043 }
4044 };
4045
4046 template <>
4047 struct OperandTraits<ResumeInst> :
4048 public FixedNumOperandTraits<ResumeInst, 1> {
4049 };
4050
4051 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
4052
4053
4054
4055
4056 class CatchSwitchInst : public Instruction {
4057 using UnwindDestField = BoolBitfieldElementT<0>;
4058
4059 constexpr static HungOffOperandsAllocMarker AllocMarker{};
4060
4061
4062
4063 unsigned ReservedSpace;
4064
4065
4066
4067
4068 CatchSwitchInst(const CatchSwitchInst &CSI);
4069
4070
4071
4072
4073
4074 CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest,
4075 unsigned NumHandlers, const Twine &NameStr,
4076 InsertPosition InsertBefore);
4077
4078
4079 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
4080
4081 void init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReserved);
4082 void growOperands(unsigned Size);
4083
4084 protected:
4085
4086 friend class Instruction;
4087
4088 CatchSwitchInst *cloneImpl() const;
4089
4090 public:
4091 void operator delete(void *Ptr) { return User::operator delete(Ptr); }
4092
4093 static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest,
4094 unsigned NumHandlers,
4095 const Twine &NameStr = "",
4096 InsertPosition InsertBefore = nullptr) {
4097 return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr,
4098 InsertBefore);
4099 }
4100
4101
4102 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
4103
4104
4105 Value *getParentPad() const { return getOperand(0); }
4106 void setParentPad(Value *ParentPad) { setOperand(0, ParentPad); }
4107
4108
4109 bool hasUnwindDest() const { return getSubclassData<UnwindDestField>(); }
4110 bool unwindsToCaller() const { return !hasUnwindDest(); }
4111 BasicBlock *getUnwindDest() const {
4112 if (hasUnwindDest())
4113 return cast<BasicBlock>(getOperand(1));
4114 return nullptr;
4115 }
4116 void setUnwindDest(BasicBlock *UnwindDest) {
4117 assert(UnwindDest);
4118 assert(hasUnwindDest());
4119 setOperand(1, UnwindDest);
4120 }
4121
4122
4123
4124 unsigned getNumHandlers() const {
4125 if (hasUnwindDest())
4126 return getNumOperands() - 2;
4127 return getNumOperands() - 1;
4128 }
4129
4130 private:
4131 static BasicBlock *handler_helper(Value *V) { return cast<BasicBlock>(V); }
4132 static const BasicBlock *handler_helper(const Value *V) {
4133 return cast<BasicBlock>(V);
4134 }
4135
4136 public:
4137 using DerefFnTy = BasicBlock *(*)(Value *);
4138 using handler_iterator = mapped_iterator<op_iterator, DerefFnTy>;
4139 using handler_range = iterator_range<handler_iterator>;
4140 using ConstDerefFnTy = const BasicBlock *(*)(const Value *);
4141 using const_handler_iterator =
4142 mapped_iterator<const_op_iterator, ConstDerefFnTy>;
4143 using const_handler_range = iterator_range<const_handler_iterator>;
4144
4145
4146 handler_iterator handler_begin() {
4147 op_iterator It = op_begin() + 1;
4148 if (hasUnwindDest())
4149 ++It;
4150 return handler_iterator(It, DerefFnTy(handler_helper));
4151 }
4152
4153
4154
4155 const_handler_iterator handler_begin() const {
4156 const_op_iterator It = op_begin() + 1;
4157 if (hasUnwindDest())
4158 ++It;
4159 return const_handler_iterator(It, ConstDerefFnTy(handler_helper));
4160 }
4161
4162
4163
4164 handler_iterator handler_end() {
4165 return handler_iterator(op_end(), DerefFnTy(handler_helper));
4166 }
4167
4168
4169
4170 const_handler_iterator handler_end() const {
4171 return const_handler_iterator(op_end(), ConstDerefFnTy(handler_helper));
4172 }
4173
4174
4175 handler_range handlers() {
4176 return make_range(handler_begin(), handler_end());
4177 }
4178
4179
4180 const_handler_range handlers() const {
4181 return make_range(handler_begin(), handler_end());
4182 }
4183
4184
4185
4186
4187
4188 void addHandler(BasicBlock *Dest);
4189
4190 void removeHandler(handler_iterator HI);
4191
4192 unsigned getNumSuccessors() const { return getNumOperands() - 1; }
4193 BasicBlock *getSuccessor(unsigned Idx) const {
4194 assert(Idx < getNumSuccessors() &&
4195 "Successor # out of range for catchswitch!");
4196 return cast<BasicBlock>(getOperand(Idx + 1));
4197 }
4198 void setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
4199 assert(Idx < getNumSuccessors() &&
4200 "Successor # out of range for catchswitch!");
4201 setOperand(Idx + 1, NewSucc);
4202 }
4203
4204
4205 static bool classof(const Instruction *I) {
4206 return I->getOpcode() == Instruction::CatchSwitch;
4207 }
4208 static bool classof(const Value *V) {
4209 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4210 }
4211 };
4212
4213 template <>
4214 struct OperandTraits<CatchSwitchInst> : public HungoffOperandTraits {};
4215
4216 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value)
4217
4218
4219
4220
4221 class CleanupPadInst : public FuncletPadInst {
4222 private:
4223 explicit CleanupPadInst(Value *ParentPad, ArrayRef<Value *> Args,
4224 AllocInfo AllocInfo, const Twine &NameStr,
4225 InsertPosition InsertBefore)
4226 : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, AllocInfo,
4227 NameStr, InsertBefore) {}
4228
4229 public:
4230 static CleanupPadInst *Create(Value *ParentPad, ArrayRef<Value *> Args = {},
4231 const Twine &NameStr = "",
4232 InsertPosition InsertBefore = nullptr) {
4233 IntrusiveOperandsAllocMarker AllocMarker{unsigned(1 + Args.size())};
4234 return new (AllocMarker)
4235 CleanupPadInst(ParentPad, Args, AllocMarker, NameStr, InsertBefore);
4236 }
4237
4238
4239 static bool classof(const Instruction *I) {
4240 return I->getOpcode() == Instruction::CleanupPad;
4241 }
4242 static bool classof(const Value *V) {
4243 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4244 }
4245 };
4246
4247
4248
4249
4250 class CatchPadInst : public FuncletPadInst {
4251 private:
4252 explicit CatchPadInst(Value *CatchSwitch, ArrayRef<Value *> Args,
4253 AllocInfo AllocInfo, const Twine &NameStr,
4254 InsertPosition InsertBefore)
4255 : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, AllocInfo,
4256 NameStr, InsertBefore) {}
4257
4258 public:
4259 static CatchPadInst *Create(Value *CatchSwitch, ArrayRef<Value *> Args,
4260 const Twine &NameStr = "",
4261 InsertPosition InsertBefore = nullptr) {
4262 IntrusiveOperandsAllocMarker AllocMarker{unsigned(1 + Args.size())};
4263 return new (AllocMarker)
4264 CatchPadInst(CatchSwitch, Args, AllocMarker, NameStr, InsertBefore);
4265 }
4266
4267
4268 CatchSwitchInst *getCatchSwitch() const {
4269 return cast<CatchSwitchInst>(Op<-1>());
4270 }
4271 void setCatchSwitch(Value *CatchSwitch) {
4272 assert(CatchSwitch);
4273 Op<-1>() = CatchSwitch;
4274 }
4275
4276
4277 static bool classof(const Instruction *I) {
4278 return I->getOpcode() == Instruction::CatchPad;
4279 }
4280 static bool classof(const Value *V) {
4281 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4282 }
4283 };
4284
4285
4286
4287
4288
4289 class CatchReturnInst : public Instruction {
4290 constexpr static IntrusiveOperandsAllocMarker AllocMarker{2};
4291
4292 CatchReturnInst(const CatchReturnInst &RI);
4293 CatchReturnInst(Value *CatchPad, BasicBlock *BB, InsertPosition InsertBefore);
4294
4295 void init(Value *CatchPad, BasicBlock *BB);
4296
4297 protected:
4298
4299 friend class Instruction;
4300
4301 CatchReturnInst *cloneImpl() const;
4302
4303 public:
4304 static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB,
4305 InsertPosition InsertBefore = nullptr) {
4306 assert(CatchPad);
4307 assert(BB);
4308 return new (AllocMarker) CatchReturnInst(CatchPad, BB, InsertBefore);
4309 }
4310
4311
4312 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
4313
4314
4315 CatchPadInst *getCatchPad() const { return cast<CatchPadInst>(Op<0>()); }
4316 void setCatchPad(CatchPadInst *CatchPad) {
4317 assert(CatchPad);
4318 Op<0>() = CatchPad;
4319 }
4320
4321 BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<1>()); }
4322 void setSuccessor(BasicBlock *NewSucc) {
4323 assert(NewSucc);
4324 Op<1>() = NewSucc;
4325 }
4326 unsigned getNumSuccessors() const { return 1; }
4327
4328
4329
4330 Value *getCatchSwitchParentPad() const {
4331 return getCatchPad()->getCatchSwitch()->getParentPad();
4332 }
4333
4334
4335 static bool classof(const Instruction *I) {
4336 return (I->getOpcode() == Instruction::CatchRet);
4337 }
4338 static bool classof(const Value *V) {
4339 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4340 }
4341
4342 private:
4343 BasicBlock *getSuccessor(unsigned Idx) const {
4344 assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
4345 return getSuccessor();
4346 }
4347
4348 void setSuccessor(unsigned Idx, BasicBlock *B) {
4349 assert(Idx < getNumSuccessors() && "Successor # out of range for catchret!");
4350 setSuccessor(B);
4351 }
4352 };
4353
4354 template <>
4355 struct OperandTraits<CatchReturnInst>
4356 : public FixedNumOperandTraits<CatchReturnInst, 2> {};
4357
4358 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
4359
4360
4361
4362
4363
4364 class CleanupReturnInst : public Instruction {
4365 using UnwindDestField = BoolBitfieldElementT<0>;
4366
4367 private:
4368 CleanupReturnInst(const CleanupReturnInst &RI, AllocInfo AllocInfo);
4369 CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB,
4370 AllocInfo AllocInfo, InsertPosition InsertBefore = nullptr);
4371
4372 void init(Value *CleanupPad, BasicBlock *UnwindBB);
4373
4374 protected:
4375
4376 friend class Instruction;
4377
4378 CleanupReturnInst *cloneImpl() const;
4379
4380 public:
4381 static CleanupReturnInst *Create(Value *CleanupPad,
4382 BasicBlock *UnwindBB = nullptr,
4383 InsertPosition InsertBefore = nullptr) {
4384 assert(CleanupPad);
4385 unsigned Values = 1;
4386 if (UnwindBB)
4387 ++Values;
4388 IntrusiveOperandsAllocMarker AllocMarker{Values};
4389 return new (AllocMarker)
4390 CleanupReturnInst(CleanupPad, UnwindBB, AllocMarker, InsertBefore);
4391 }
4392
4393
4394 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
4395
4396 bool hasUnwindDest() const { return getSubclassData<UnwindDestField>(); }
4397 bool unwindsToCaller() const { return !hasUnwindDest(); }
4398
4399
4400 CleanupPadInst *getCleanupPad() const {
4401 return cast<CleanupPadInst>(Op<0>());
4402 }
4403 void setCleanupPad(CleanupPadInst *CleanupPad) {
4404 assert(CleanupPad);
4405 Op<0>() = CleanupPad;
4406 }
4407
4408 unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
4409
4410 BasicBlock *getUnwindDest() const {
4411 return hasUnwindDest() ? cast<BasicBlock>(Op<1>()) : nullptr;
4412 }
4413 void setUnwindDest(BasicBlock *NewDest) {
4414 assert(NewDest);
4415 assert(hasUnwindDest());
4416 Op<1>() = NewDest;
4417 }
4418
4419
4420 static bool classof(const Instruction *I) {
4421 return (I->getOpcode() == Instruction::CleanupRet);
4422 }
4423 static bool classof(const Value *V) {
4424 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4425 }
4426
4427 private:
4428 BasicBlock *getSuccessor(unsigned Idx) const {
4429 assert(Idx == 0);
4430 return getUnwindDest();
4431 }
4432
4433 void setSuccessor(unsigned Idx, BasicBlock *B) {
4434 assert(Idx == 0);
4435 setUnwindDest(B);
4436 }
4437
4438
4439
4440 template <typename Bitfield>
4441 void setSubclassData(typename Bitfield::Type Value) {
4442 Instruction::setSubclassData<Bitfield>(Value);
4443 }
4444 };
4445
4446 template <>
4447 struct OperandTraits<CleanupReturnInst>
4448 : public VariadicOperandTraits<CleanupReturnInst> {};
4449
4450 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461 class UnreachableInst : public Instruction {
4462 constexpr static IntrusiveOperandsAllocMarker AllocMarker{0};
4463
4464 protected:
4465
4466 friend class Instruction;
4467
4468 UnreachableInst *cloneImpl() const;
4469
4470 public:
4471 explicit UnreachableInst(LLVMContext &C,
4472 InsertPosition InsertBefore = nullptr);
4473
4474
4475 void *operator new(size_t S) { return User::operator new(S, AllocMarker); }
4476 void operator delete(void *Ptr) { User::operator delete(Ptr); }
4477
4478 unsigned getNumSuccessors() const { return 0; }
4479
4480
4481 static bool classof(const Instruction *I) {
4482 return I->getOpcode() == Instruction::Unreachable;
4483 }
4484 static bool classof(const Value *V) {
4485 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4486 }
4487
4488 private:
4489 BasicBlock *getSuccessor(unsigned idx) const {
4490 llvm_unreachable("UnreachableInst has no successors!");
4491 }
4492
4493 void setSuccessor(unsigned idx, BasicBlock *B) {
4494 llvm_unreachable("UnreachableInst has no successors!");
4495 }
4496 };
4497
4498
4499
4500
4501
4502
4503 class TruncInst : public CastInst {
4504 protected:
4505
4506 friend class Instruction;
4507
4508
4509 TruncInst *cloneImpl() const;
4510
4511 public:
4512 enum { AnyWrap = 0, NoUnsignedWrap = (1 << 0), NoSignedWrap = (1 << 1) };
4513
4514
4515 TruncInst(Value *S,
4516 Type *Ty,
4517 const Twine &NameStr = "",
4518 InsertPosition InsertBefore =
4519 nullptr
4520 );
4521
4522
4523 static bool classof(const Instruction *I) {
4524 return I->getOpcode() == Trunc;
4525 }
4526 static bool classof(const Value *V) {
4527 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4528 }
4529
4530 void setHasNoUnsignedWrap(bool B) {
4531 SubclassOptionalData =
4532 (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
4533 }
4534 void setHasNoSignedWrap(bool B) {
4535 SubclassOptionalData =
4536 (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
4537 }
4538
4539
4540
4541 bool hasNoUnsignedWrap() const {
4542 return SubclassOptionalData & NoUnsignedWrap;
4543 }
4544
4545
4546
4547 bool hasNoSignedWrap() const {
4548 return (SubclassOptionalData & NoSignedWrap) != 0;
4549 }
4550
4551
4552 unsigned getNoWrapKind() const {
4553 unsigned NoWrapKind = 0;
4554 if (hasNoUnsignedWrap())
4555 NoWrapKind |= NoUnsignedWrap;
4556
4557 if (hasNoSignedWrap())
4558 NoWrapKind |= NoSignedWrap;
4559
4560 return NoWrapKind;
4561 }
4562 };
4563
4564
4565
4566
4567
4568
4569 class ZExtInst : public CastInst {
4570 protected:
4571
4572 friend class Instruction;
4573
4574
4575 ZExtInst *cloneImpl() const;
4576
4577 public:
4578
4579 ZExtInst(Value *S,
4580 Type *Ty,
4581 const Twine &NameStr = "",
4582 InsertPosition InsertBefore =
4583 nullptr
4584 );
4585
4586
4587 static bool classof(const Instruction *I) {
4588 return I->getOpcode() == ZExt;
4589 }
4590 static bool classof(const Value *V) {
4591 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4592 }
4593 };
4594
4595
4596
4597
4598
4599
4600 class SExtInst : public CastInst {
4601 protected:
4602
4603 friend class Instruction;
4604
4605
4606 SExtInst *cloneImpl() const;
4607
4608 public:
4609
4610 SExtInst(Value *S,
4611 Type *Ty,
4612 const Twine &NameStr = "",
4613 InsertPosition InsertBefore =
4614 nullptr
4615 );
4616
4617
4618 static bool classof(const Instruction *I) {
4619 return I->getOpcode() == SExt;
4620 }
4621 static bool classof(const Value *V) {
4622 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4623 }
4624 };
4625
4626
4627
4628
4629
4630
4631 class FPTruncInst : public CastInst {
4632 protected:
4633
4634 friend class Instruction;
4635
4636
4637 FPTruncInst *cloneImpl() const;
4638
4639 public:
4640 FPTruncInst(Value *S,
4641 Type *Ty,
4642 const Twine &NameStr = "",
4643 InsertPosition InsertBefore =
4644 nullptr
4645 );
4646
4647
4648 static bool classof(const Instruction *I) {
4649 return I->getOpcode() == FPTrunc;
4650 }
4651 static bool classof(const Value *V) {
4652 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4653 }
4654 };
4655
4656
4657
4658
4659
4660
4661 class FPExtInst : public CastInst {
4662 protected:
4663
4664 friend class Instruction;
4665
4666
4667 FPExtInst *cloneImpl() const;
4668
4669 public:
4670
4671 FPExtInst(Value *S,
4672 Type *Ty,
4673 const Twine &NameStr = "",
4674 InsertPosition InsertBefore =
4675 nullptr
4676 );
4677
4678
4679 static bool classof(const Instruction *I) {
4680 return I->getOpcode() == FPExt;
4681 }
4682 static bool classof(const Value *V) {
4683 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4684 }
4685 };
4686
4687
4688
4689
4690
4691
4692 class UIToFPInst : public CastInst {
4693 protected:
4694
4695 friend class Instruction;
4696
4697
4698 UIToFPInst *cloneImpl() const;
4699
4700 public:
4701
4702 UIToFPInst(Value *S,
4703 Type *Ty,
4704 const Twine &NameStr = "",
4705 InsertPosition InsertBefore =
4706 nullptr
4707 );
4708
4709
4710 static bool classof(const Instruction *I) {
4711 return I->getOpcode() == UIToFP;
4712 }
4713 static bool classof(const Value *V) {
4714 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4715 }
4716 };
4717
4718
4719
4720
4721
4722
4723 class SIToFPInst : public CastInst {
4724 protected:
4725
4726 friend class Instruction;
4727
4728
4729 SIToFPInst *cloneImpl() const;
4730
4731 public:
4732
4733 SIToFPInst(Value *S,
4734 Type *Ty,
4735 const Twine &NameStr = "",
4736 InsertPosition InsertBefore =
4737 nullptr
4738 );
4739
4740
4741 static bool classof(const Instruction *I) {
4742 return I->getOpcode() == SIToFP;
4743 }
4744 static bool classof(const Value *V) {
4745 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4746 }
4747 };
4748
4749
4750
4751
4752
4753
4754 class FPToUIInst : public CastInst {
4755 protected:
4756
4757 friend class Instruction;
4758
4759
4760 FPToUIInst *cloneImpl() const;
4761
4762 public:
4763
4764 FPToUIInst(Value *S,
4765 Type *Ty,
4766 const Twine &NameStr = "",
4767 InsertPosition InsertBefore =
4768 nullptr
4769 );
4770
4771
4772 static bool classof(const Instruction *I) {
4773 return I->getOpcode() == FPToUI;
4774 }
4775 static bool classof(const Value *V) {
4776 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4777 }
4778 };
4779
4780
4781
4782
4783
4784
4785 class FPToSIInst : public CastInst {
4786 protected:
4787
4788 friend class Instruction;
4789
4790
4791 FPToSIInst *cloneImpl() const;
4792
4793 public:
4794
4795 FPToSIInst(Value *S,
4796 Type *Ty,
4797 const Twine &NameStr = "",
4798 InsertPosition InsertBefore =
4799 nullptr
4800 );
4801
4802
4803 static bool classof(const Instruction *I) {
4804 return I->getOpcode() == FPToSI;
4805 }
4806 static bool classof(const Value *V) {
4807 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4808 }
4809 };
4810
4811
4812
4813
4814
4815
4816 class IntToPtrInst : public CastInst {
4817 public:
4818
4819 friend class Instruction;
4820
4821
4822 IntToPtrInst(Value *S,
4823 Type *Ty,
4824 const Twine &NameStr = "",
4825 InsertPosition InsertBefore =
4826 nullptr
4827 );
4828
4829
4830 IntToPtrInst *cloneImpl() const;
4831
4832
4833 unsigned getAddressSpace() const {
4834 return getType()->getPointerAddressSpace();
4835 }
4836
4837
4838 static bool classof(const Instruction *I) {
4839 return I->getOpcode() == IntToPtr;
4840 }
4841 static bool classof(const Value *V) {
4842 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4843 }
4844 };
4845
4846
4847
4848
4849
4850
4851 class PtrToIntInst : public CastInst {
4852 protected:
4853
4854 friend class Instruction;
4855
4856
4857 PtrToIntInst *cloneImpl() const;
4858
4859 public:
4860
4861 PtrToIntInst(Value *S,
4862 Type *Ty,
4863 const Twine &NameStr = "",
4864 InsertPosition InsertBefore =
4865 nullptr
4866 );
4867
4868
4869 Value *getPointerOperand() { return getOperand(0); }
4870
4871 const Value *getPointerOperand() const { return getOperand(0); }
4872
4873 static unsigned getPointerOperandIndex() { return 0U; }
4874
4875
4876 unsigned getPointerAddressSpace() const {
4877 return getPointerOperand()->getType()->getPointerAddressSpace();
4878 }
4879
4880
4881 static bool classof(const Instruction *I) {
4882 return I->getOpcode() == PtrToInt;
4883 }
4884 static bool classof(const Value *V) {
4885 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4886 }
4887 };
4888
4889
4890
4891
4892
4893
4894 class BitCastInst : public CastInst {
4895 protected:
4896
4897 friend class Instruction;
4898
4899
4900 BitCastInst *cloneImpl() const;
4901
4902 public:
4903
4904 BitCastInst(Value *S,
4905 Type *Ty,
4906 const Twine &NameStr = "",
4907 InsertPosition InsertBefore =
4908 nullptr
4909 );
4910
4911
4912 static bool classof(const Instruction *I) {
4913 return I->getOpcode() == BitCast;
4914 }
4915 static bool classof(const Value *V) {
4916 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4917 }
4918 };
4919
4920
4921
4922
4923
4924
4925
4926 class AddrSpaceCastInst : public CastInst {
4927 protected:
4928
4929 friend class Instruction;
4930
4931
4932 AddrSpaceCastInst *cloneImpl() const;
4933
4934 public:
4935
4936 AddrSpaceCastInst(
4937 Value *S,
4938 Type *Ty,
4939 const Twine &NameStr = "",
4940 InsertPosition InsertBefore =
4941 nullptr
4942 );
4943
4944
4945 static bool classof(const Instruction *I) {
4946 return I->getOpcode() == AddrSpaceCast;
4947 }
4948 static bool classof(const Value *V) {
4949 return isa<Instruction>(V) && classof(cast<Instruction>(V));
4950 }
4951
4952
4953 Value *getPointerOperand() {
4954 return getOperand(0);
4955 }
4956
4957
4958 const Value *getPointerOperand() const {
4959 return getOperand(0);
4960 }
4961
4962
4963 static unsigned getPointerOperandIndex() {
4964 return 0U;
4965 }
4966
4967
4968 unsigned getSrcAddressSpace() const {
4969 return getPointerOperand()->getType()->getPointerAddressSpace();
4970 }
4971
4972
4973 unsigned getDestAddressSpace() const {
4974 return getType()->getPointerAddressSpace();
4975 }
4976 };
4977
4978
4979
4980
4981
4982
4983
4984 inline const Value *getLoadStorePointerOperand(const Value *V) {
4985 if (auto *Load = dyn_cast<LoadInst>(V))
4986 return Load->getPointerOperand();
4987 if (auto *Store = dyn_cast<StoreInst>(V))
4988 return Store->getPointerOperand();
4989 return nullptr;
4990 }
4991 inline Value *getLoadStorePointerOperand(Value *V) {
4992 return const_cast<Value *>(
4993 getLoadStorePointerOperand(static_cast<const Value *>(V)));
4994 }
4995
4996
4997
4998 inline const Value *getPointerOperand(const Value *V) {
4999 if (auto *Ptr = getLoadStorePointerOperand(V))
5000 return Ptr;
5001 if (auto *Gep = dyn_cast<GetElementPtrInst>(V))
5002 return Gep->getPointerOperand();
5003 return nullptr;
5004 }
5005 inline Value *getPointerOperand(Value *V) {
5006 return const_cast<Value *>(getPointerOperand(static_cast<const Value *>(V)));
5007 }
5008
5009
5010 inline Align getLoadStoreAlignment(const Value *I) {
5011 assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
5012 "Expected Load or Store instruction");
5013 if (auto *LI = dyn_cast<LoadInst>(I))
5014 return LI->getAlign();
5015 return cast<StoreInst>(I)->getAlign();
5016 }
5017
5018
5019 inline void setLoadStoreAlignment(Value *I, Align NewAlign) {
5020 assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
5021 "Expected Load or Store instruction");
5022 if (auto *LI = dyn_cast<LoadInst>(I))
5023 LI->setAlignment(NewAlign);
5024 else
5025 cast<StoreInst>(I)->setAlignment(NewAlign);
5026 }
5027
5028
5029
5030 inline unsigned getLoadStoreAddressSpace(const Value *I) {
5031 assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
5032 "Expected Load or Store instruction");
5033 if (auto *LI = dyn_cast<LoadInst>(I))
5034 return LI->getPointerAddressSpace();
5035 return cast<StoreInst>(I)->getPointerAddressSpace();
5036 }
5037
5038
5039 inline Type *getLoadStoreType(const Value *I) {
5040 assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
5041 "Expected Load or Store instruction");
5042 if (auto *LI = dyn_cast<LoadInst>(I))
5043 return LI->getType();
5044 return cast<StoreInst>(I)->getValueOperand()->getType();
5045 }
5046
5047
5048
5049 inline std::optional<SyncScope::ID> getAtomicSyncScopeID(const Instruction *I) {
5050 if (!I->isAtomic())
5051 return std::nullopt;
5052 if (auto *AI = dyn_cast<LoadInst>(I))
5053 return AI->getSyncScopeID();
5054 if (auto *AI = dyn_cast<StoreInst>(I))
5055 return AI->getSyncScopeID();
5056 if (auto *AI = dyn_cast<FenceInst>(I))
5057 return AI->getSyncScopeID();
5058 if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I))
5059 return AI->getSyncScopeID();
5060 if (auto *AI = dyn_cast<AtomicRMWInst>(I))
5061 return AI->getSyncScopeID();
5062 llvm_unreachable("unhandled atomic operation");
5063 }
5064
5065
5066 inline void setAtomicSyncScopeID(Instruction *I, SyncScope::ID SSID) {
5067 assert(I->isAtomic());
5068 if (auto *AI = dyn_cast<LoadInst>(I))
5069 AI->setSyncScopeID(SSID);
5070 else if (auto *AI = dyn_cast<StoreInst>(I))
5071 AI->setSyncScopeID(SSID);
5072 else if (auto *AI = dyn_cast<FenceInst>(I))
5073 AI->setSyncScopeID(SSID);
5074 else if (auto *AI = dyn_cast<AtomicCmpXchgInst>(I))
5075 AI->setSyncScopeID(SSID);
5076 else if (auto *AI = dyn_cast<AtomicRMWInst>(I))
5077 AI->setSyncScopeID(SSID);
5078 else
5079 llvm_unreachable("unhandled atomic operation");
5080 }
5081
5082
5083
5084
5085
5086
5087
5088 class FreezeInst : public UnaryInstruction {
5089 protected:
5090
5091 friend class Instruction;
5092
5093
5094 FreezeInst *cloneImpl() const;
5095
5096 public:
5097 explicit FreezeInst(Value *S, const Twine &NameStr = "",
5098 InsertPosition InsertBefore = nullptr);
5099
5100
5101 static inline bool classof(const Instruction *I) {
5102 return I->getOpcode() == Freeze;
5103 }
5104 static inline bool classof(const Value *V) {
5105 return isa<Instruction>(V) && classof(cast<Instruction>(V));
5106 }
5107 };
5108
5109 }
5110
5111 #endif