File indexing completed on 2026-05-10 08:43:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
0019 #define LLVM_CODEGEN_SELECTIONDAGNODES_H
0020
0021 #include "llvm/ADT/APFloat.h"
0022 #include "llvm/ADT/ArrayRef.h"
0023 #include "llvm/ADT/BitVector.h"
0024 #include "llvm/ADT/FoldingSet.h"
0025 #include "llvm/ADT/GraphTraits.h"
0026 #include "llvm/ADT/SmallPtrSet.h"
0027 #include "llvm/ADT/SmallVector.h"
0028 #include "llvm/ADT/ilist_node.h"
0029 #include "llvm/ADT/iterator.h"
0030 #include "llvm/ADT/iterator_range.h"
0031 #include "llvm/CodeGen/ISDOpcodes.h"
0032 #include "llvm/CodeGen/MachineMemOperand.h"
0033 #include "llvm/CodeGen/Register.h"
0034 #include "llvm/CodeGen/ValueTypes.h"
0035 #include "llvm/CodeGenTypes/MachineValueType.h"
0036 #include "llvm/IR/Constants.h"
0037 #include "llvm/IR/DebugLoc.h"
0038 #include "llvm/IR/Instruction.h"
0039 #include "llvm/IR/Instructions.h"
0040 #include "llvm/IR/Metadata.h"
0041 #include "llvm/IR/Operator.h"
0042 #include "llvm/Support/AlignOf.h"
0043 #include "llvm/Support/AtomicOrdering.h"
0044 #include "llvm/Support/Casting.h"
0045 #include "llvm/Support/ErrorHandling.h"
0046 #include "llvm/Support/TypeSize.h"
0047 #include <algorithm>
0048 #include <cassert>
0049 #include <climits>
0050 #include <cstddef>
0051 #include <cstdint>
0052 #include <cstring>
0053 #include <iterator>
0054 #include <string>
0055 #include <tuple>
0056 #include <utility>
0057
0058 namespace llvm {
0059
0060 class APInt;
0061 class Constant;
0062 class GlobalValue;
0063 class MachineBasicBlock;
0064 class MachineConstantPoolValue;
0065 class MCSymbol;
0066 class raw_ostream;
0067 class SDNode;
0068 class SelectionDAG;
0069 class Type;
0070 class Value;
0071
0072 void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
0073 bool force = false);
0074
0075
0076
0077
0078
0079 struct SDVTList {
0080 const EVT *VTs;
0081 unsigned int NumVTs;
0082 };
0083
0084 namespace ISD {
0085
0086
0087
0088
0089
0090
0091 bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
0092
0093
0094
0095
0096 bool isConstantSplatVectorAllOnes(const SDNode *N,
0097 bool BuildVectorOnly = false);
0098
0099
0100
0101
0102 bool isConstantSplatVectorAllZeros(const SDNode *N,
0103 bool BuildVectorOnly = false);
0104
0105
0106
0107 bool isBuildVectorAllOnes(const SDNode *N);
0108
0109
0110
0111 bool isBuildVectorAllZeros(const SDNode *N);
0112
0113
0114
0115 bool isBuildVectorOfConstantSDNodes(const SDNode *N);
0116
0117
0118
0119 bool isBuildVectorOfConstantFPSDNodes(const SDNode *N);
0120
0121
0122
0123 bool isVectorShrinkable(const SDNode *N, unsigned NewEltSize, bool Signed);
0124
0125
0126
0127 bool allOperandsUndef(const SDNode *N);
0128
0129
0130 bool isFreezeUndef(const SDNode *N);
0131
0132 }
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 class SDValue {
0146 friend struct DenseMapInfo<SDValue>;
0147
0148 SDNode *Node = nullptr;
0149 unsigned ResNo = 0;
0150
0151 public:
0152 SDValue() = default;
0153 SDValue(SDNode *node, unsigned resno);
0154
0155
0156 unsigned getResNo() const { return ResNo; }
0157
0158
0159 SDNode *getNode() const { return Node; }
0160
0161
0162 void setNode(SDNode *N) { Node = N; }
0163
0164 inline SDNode *operator->() const { return Node; }
0165
0166 bool operator==(const SDValue &O) const {
0167 return Node == O.Node && ResNo == O.ResNo;
0168 }
0169 bool operator!=(const SDValue &O) const {
0170 return !operator==(O);
0171 }
0172 bool operator<(const SDValue &O) const {
0173 return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo);
0174 }
0175 explicit operator bool() const {
0176 return Node != nullptr;
0177 }
0178
0179 SDValue getValue(unsigned R) const {
0180 return SDValue(Node, R);
0181 }
0182
0183
0184 bool isOperandOf(const SDNode *N) const;
0185
0186
0187 inline EVT getValueType() const;
0188
0189
0190 MVT getSimpleValueType() const {
0191 return getValueType().getSimpleVT();
0192 }
0193
0194
0195
0196
0197
0198
0199 TypeSize getValueSizeInBits() const {
0200 return getValueType().getSizeInBits();
0201 }
0202
0203 uint64_t getScalarValueSizeInBits() const {
0204 return getValueType().getScalarType().getFixedSizeInBits();
0205 }
0206
0207
0208 inline unsigned getOpcode() const;
0209 inline unsigned getNumOperands() const;
0210 inline const SDValue &getOperand(unsigned i) const;
0211 inline uint64_t getConstantOperandVal(unsigned i) const;
0212 inline const APInt &getConstantOperandAPInt(unsigned i) const;
0213 inline bool isTargetOpcode() const;
0214 inline bool isMachineOpcode() const;
0215 inline bool isUndef() const;
0216 inline unsigned getMachineOpcode() const;
0217 inline const DebugLoc &getDebugLoc() const;
0218 inline void dump() const;
0219 inline void dump(const SelectionDAG *G) const;
0220 inline void dumpr() const;
0221 inline void dumpr(const SelectionDAG *G) const;
0222
0223
0224
0225
0226
0227
0228 bool reachesChainWithoutSideEffects(SDValue Dest,
0229 unsigned Depth = 2) const;
0230
0231
0232 inline bool use_empty() const;
0233
0234
0235 inline bool hasOneUse() const;
0236 };
0237
0238 template<> struct DenseMapInfo<SDValue> {
0239 static inline SDValue getEmptyKey() {
0240 SDValue V;
0241 V.ResNo = -1U;
0242 return V;
0243 }
0244
0245 static inline SDValue getTombstoneKey() {
0246 SDValue V;
0247 V.ResNo = -2U;
0248 return V;
0249 }
0250
0251 static unsigned getHashValue(const SDValue &Val) {
0252 return ((unsigned)((uintptr_t)Val.getNode() >> 4) ^
0253 (unsigned)((uintptr_t)Val.getNode() >> 9)) + Val.getResNo();
0254 }
0255
0256 static bool isEqual(const SDValue &LHS, const SDValue &RHS) {
0257 return LHS == RHS;
0258 }
0259 };
0260
0261
0262
0263 template<> struct simplify_type<SDValue> {
0264 using SimpleType = SDNode *;
0265
0266 static SimpleType getSimplifiedValue(SDValue &Val) {
0267 return Val.getNode();
0268 }
0269 };
0270 template<> struct simplify_type<const SDValue> {
0271 using SimpleType = SDNode *;
0272
0273 static SimpleType getSimplifiedValue(const SDValue &Val) {
0274 return Val.getNode();
0275 }
0276 };
0277
0278
0279
0280
0281
0282
0283 class SDUse {
0284
0285 SDValue Val;
0286
0287 SDNode *User = nullptr;
0288
0289
0290 SDUse **Prev = nullptr;
0291 SDUse *Next = nullptr;
0292
0293 public:
0294 SDUse() = default;
0295 SDUse(const SDUse &U) = delete;
0296 SDUse &operator=(const SDUse &) = delete;
0297
0298
0299 operator const SDValue&() const { return Val; }
0300
0301
0302
0303 const SDValue &get() const { return Val; }
0304
0305
0306 SDNode *getUser() { return User; }
0307 const SDNode *getUser() const { return User; }
0308
0309
0310 SDUse *getNext() const { return Next; }
0311
0312
0313 inline unsigned getOperandNo() const;
0314
0315
0316 SDNode *getNode() const { return Val.getNode(); }
0317
0318 unsigned getResNo() const { return Val.getResNo(); }
0319
0320 EVT getValueType() const { return Val.getValueType(); }
0321
0322
0323 bool operator==(const SDValue &V) const {
0324 return Val == V;
0325 }
0326
0327
0328 bool operator!=(const SDValue &V) const {
0329 return Val != V;
0330 }
0331
0332
0333 bool operator<(const SDValue &V) const {
0334 return Val < V;
0335 }
0336
0337 private:
0338 friend class SelectionDAG;
0339 friend class SDNode;
0340
0341 friend class HandleSDNode;
0342
0343 void setUser(SDNode *p) { User = p; }
0344
0345
0346
0347 inline void set(const SDValue &V);
0348
0349
0350 inline void setInitial(const SDValue &V);
0351
0352
0353 inline void setNode(SDNode *N);
0354
0355 void addToList(SDUse **List) {
0356 Next = *List;
0357 if (Next) Next->Prev = &Next;
0358 Prev = List;
0359 *List = this;
0360 }
0361
0362 void removeFromList() {
0363 *Prev = Next;
0364 if (Next) Next->Prev = Prev;
0365 }
0366 };
0367
0368
0369
0370 template<> struct simplify_type<SDUse> {
0371 using SimpleType = SDNode *;
0372
0373 static SimpleType getSimplifiedValue(SDUse &Val) {
0374 return Val.getNode();
0375 }
0376 };
0377
0378
0379
0380
0381 struct SDNodeFlags {
0382 private:
0383 friend class SDNode;
0384
0385 unsigned Flags = 0;
0386
0387 template <unsigned Flag> void setFlag(bool B) {
0388 Flags = (Flags & ~Flag) | (B ? Flag : 0);
0389 }
0390
0391 public:
0392 enum : unsigned {
0393 None = 0,
0394 NoUnsignedWrap = 1 << 0,
0395 NoSignedWrap = 1 << 1,
0396 NoWrap = NoUnsignedWrap | NoSignedWrap,
0397 Exact = 1 << 2,
0398 Disjoint = 1 << 3,
0399 NonNeg = 1 << 4,
0400 NoNaNs = 1 << 5,
0401 NoInfs = 1 << 6,
0402 NoSignedZeros = 1 << 7,
0403 AllowReciprocal = 1 << 8,
0404 AllowContract = 1 << 9,
0405 ApproximateFuncs = 1 << 10,
0406 AllowReassociation = 1 << 11,
0407
0408
0409
0410
0411
0412
0413 NoFPExcept = 1 << 12,
0414
0415 Unpredictable = 1 << 13,
0416
0417 SameSign = 1 << 14,
0418
0419
0420
0421
0422 PoisonGeneratingFlags = NoUnsignedWrap | NoSignedWrap | Exact | Disjoint |
0423 NonNeg | NoNaNs | NoInfs | SameSign,
0424 };
0425
0426
0427 SDNodeFlags(unsigned Flags = SDNodeFlags::None) : Flags(Flags) {}
0428
0429
0430 void copyFMF(const FPMathOperator &FPMO) {
0431 setNoNaNs(FPMO.hasNoNaNs());
0432 setNoInfs(FPMO.hasNoInfs());
0433 setNoSignedZeros(FPMO.hasNoSignedZeros());
0434 setAllowReciprocal(FPMO.hasAllowReciprocal());
0435 setAllowContract(FPMO.hasAllowContract());
0436 setApproximateFuncs(FPMO.hasApproxFunc());
0437 setAllowReassociation(FPMO.hasAllowReassoc());
0438 }
0439
0440
0441 void setNoUnsignedWrap(bool b) { setFlag<NoUnsignedWrap>(b); }
0442 void setNoSignedWrap(bool b) { setFlag<NoSignedWrap>(b); }
0443 void setExact(bool b) { setFlag<Exact>(b); }
0444 void setDisjoint(bool b) { setFlag<Disjoint>(b); }
0445 void setSameSign(bool b) { setFlag<SameSign>(b); }
0446 void setNonNeg(bool b) { setFlag<NonNeg>(b); }
0447 void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
0448 void setNoInfs(bool b) { setFlag<NoInfs>(b); }
0449 void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
0450 void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
0451 void setAllowContract(bool b) { setFlag<AllowContract>(b); }
0452 void setApproximateFuncs(bool b) { setFlag<ApproximateFuncs>(b); }
0453 void setAllowReassociation(bool b) { setFlag<AllowReassociation>(b); }
0454 void setNoFPExcept(bool b) { setFlag<NoFPExcept>(b); }
0455 void setUnpredictable(bool b) { setFlag<Unpredictable>(b); }
0456
0457
0458 bool hasNoUnsignedWrap() const { return Flags & NoUnsignedWrap; }
0459 bool hasNoSignedWrap() const { return Flags & NoSignedWrap; }
0460 bool hasExact() const { return Flags & Exact; }
0461 bool hasDisjoint() const { return Flags & Disjoint; }
0462 bool hasSameSign() const { return Flags & SameSign; }
0463 bool hasNonNeg() const { return Flags & NonNeg; }
0464 bool hasNoNaNs() const { return Flags & NoNaNs; }
0465 bool hasNoInfs() const { return Flags & NoInfs; }
0466 bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
0467 bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }
0468 bool hasAllowContract() const { return Flags & AllowContract; }
0469 bool hasApproximateFuncs() const { return Flags & ApproximateFuncs; }
0470 bool hasAllowReassociation() const { return Flags & AllowReassociation; }
0471 bool hasNoFPExcept() const { return Flags & NoFPExcept; }
0472 bool hasUnpredictable() const { return Flags & Unpredictable; }
0473
0474 bool operator==(const SDNodeFlags &Other) const {
0475 return Flags == Other.Flags;
0476 }
0477 void operator&=(const SDNodeFlags &OtherFlags) { Flags &= OtherFlags.Flags; }
0478 void operator|=(const SDNodeFlags &OtherFlags) { Flags |= OtherFlags.Flags; }
0479 };
0480
0481 LLVM_DECLARE_ENUM_AS_BITMASK(decltype(SDNodeFlags::None),
0482 SDNodeFlags::SameSign);
0483
0484 inline SDNodeFlags operator|(SDNodeFlags LHS, SDNodeFlags RHS) {
0485 LHS |= RHS;
0486 return LHS;
0487 }
0488
0489 inline SDNodeFlags operator&(SDNodeFlags LHS, SDNodeFlags RHS) {
0490 LHS &= RHS;
0491 return LHS;
0492 }
0493
0494
0495
0496 class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
0497 private:
0498
0499 int32_t NodeType;
0500
0501 SDNodeFlags Flags;
0502
0503 protected:
0504
0505
0506
0507
0508 #if defined(_AIX) && (!defined(__GNUC__) || defined(__clang__))
0509
0510
0511 #define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")
0512 #define END_TWO_BYTE_PACK() _Pragma("pack(pop)")
0513 #else
0514 #define BEGIN_TWO_BYTE_PACK()
0515 #define END_TWO_BYTE_PACK()
0516 #endif
0517
0518 BEGIN_TWO_BYTE_PACK()
0519 class SDNodeBitfields {
0520 friend class SDNode;
0521 friend class MemIntrinsicSDNode;
0522 friend class MemSDNode;
0523 friend class SelectionDAG;
0524
0525 uint16_t HasDebugValue : 1;
0526 uint16_t IsMemIntrinsic : 1;
0527 uint16_t IsDivergent : 1;
0528 };
0529 enum { NumSDNodeBits = 3 };
0530
0531 class ConstantSDNodeBitfields {
0532 friend class ConstantSDNode;
0533
0534 uint16_t : NumSDNodeBits;
0535
0536 uint16_t IsOpaque : 1;
0537 };
0538
0539 class MemSDNodeBitfields {
0540 friend class MemSDNode;
0541 friend class MemIntrinsicSDNode;
0542 friend class AtomicSDNode;
0543
0544 uint16_t : NumSDNodeBits;
0545
0546 uint16_t IsVolatile : 1;
0547 uint16_t IsNonTemporal : 1;
0548 uint16_t IsDereferenceable : 1;
0549 uint16_t IsInvariant : 1;
0550 };
0551 enum { NumMemSDNodeBits = NumSDNodeBits + 4 };
0552
0553 class LSBaseSDNodeBitfields {
0554 friend class LSBaseSDNode;
0555 friend class VPBaseLoadStoreSDNode;
0556 friend class MaskedLoadStoreSDNode;
0557 friend class MaskedGatherScatterSDNode;
0558 friend class VPGatherScatterSDNode;
0559 friend class MaskedHistogramSDNode;
0560
0561 uint16_t : NumMemSDNodeBits;
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571 uint16_t AddressingMode : 3;
0572 };
0573 enum { NumLSBaseSDNodeBits = NumMemSDNodeBits + 3 };
0574
0575 class LoadSDNodeBitfields {
0576 friend class LoadSDNode;
0577 friend class AtomicSDNode;
0578 friend class VPLoadSDNode;
0579 friend class VPStridedLoadSDNode;
0580 friend class MaskedLoadSDNode;
0581 friend class MaskedGatherSDNode;
0582 friend class VPGatherSDNode;
0583 friend class MaskedHistogramSDNode;
0584
0585 uint16_t : NumLSBaseSDNodeBits;
0586
0587 uint16_t ExtTy : 2;
0588 uint16_t IsExpanding : 1;
0589 };
0590
0591 class StoreSDNodeBitfields {
0592 friend class StoreSDNode;
0593 friend class VPStoreSDNode;
0594 friend class VPStridedStoreSDNode;
0595 friend class MaskedStoreSDNode;
0596 friend class MaskedScatterSDNode;
0597 friend class VPScatterSDNode;
0598
0599 uint16_t : NumLSBaseSDNodeBits;
0600
0601 uint16_t IsTruncating : 1;
0602 uint16_t IsCompressing : 1;
0603 };
0604
0605 union {
0606 char RawSDNodeBits[sizeof(uint16_t)];
0607 SDNodeBitfields SDNodeBits;
0608 ConstantSDNodeBitfields ConstantSDNodeBits;
0609 MemSDNodeBitfields MemSDNodeBits;
0610 LSBaseSDNodeBitfields LSBaseSDNodeBits;
0611 LoadSDNodeBitfields LoadSDNodeBits;
0612 StoreSDNodeBitfields StoreSDNodeBits;
0613 };
0614 END_TWO_BYTE_PACK()
0615 #undef BEGIN_TWO_BYTE_PACK
0616 #undef END_TWO_BYTE_PACK
0617
0618
0619
0620
0621 static_assert(sizeof(SDNodeBitfields) <= 2, "field too wide");
0622 static_assert(sizeof(ConstantSDNodeBitfields) <= 2, "field too wide");
0623 static_assert(sizeof(MemSDNodeBitfields) <= 2, "field too wide");
0624 static_assert(sizeof(LSBaseSDNodeBitfields) <= 2, "field too wide");
0625 static_assert(sizeof(LoadSDNodeBitfields) <= 2, "field too wide");
0626 static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide");
0627
0628 public:
0629
0630
0631
0632
0633
0634 uint16_t PersistentId = 0xffff;
0635
0636 private:
0637 friend class SelectionDAG;
0638
0639 friend class HandleSDNode;
0640
0641
0642 int NodeId = -1;
0643
0644
0645 SDUse *OperandList = nullptr;
0646
0647
0648
0649 const EVT *ValueList;
0650
0651
0652 SDUse *UseList = nullptr;
0653
0654
0655 unsigned short NumOperands = 0;
0656 unsigned short NumValues;
0657
0658
0659
0660
0661
0662
0663 unsigned IROrder;
0664
0665
0666 DebugLoc debugLoc;
0667
0668
0669 static const EVT *getValueTypeList(MVT VT);
0670
0671
0672
0673
0674 int CombinerWorklistIndex = -1;
0675
0676 uint32_t CFIType = 0;
0677
0678 public:
0679
0680
0681
0682
0683
0684
0685
0686
0687 unsigned getOpcode() const { return (unsigned)NodeType; }
0688
0689
0690
0691 bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
0692
0693
0694 bool isUndef() const { return NodeType == ISD::UNDEF; }
0695
0696
0697 bool isMemIntrinsic() const { return SDNodeBits.IsMemIntrinsic; }
0698
0699
0700 bool isStrictFPOpcode() {
0701 switch (NodeType) {
0702 default:
0703 return false;
0704 case ISD::STRICT_FP16_TO_FP:
0705 case ISD::STRICT_FP_TO_FP16:
0706 case ISD::STRICT_BF16_TO_FP:
0707 case ISD::STRICT_FP_TO_BF16:
0708 #define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
0709 case ISD::STRICT_##DAGN:
0710 #include "llvm/IR/ConstrainedOps.def"
0711 return true;
0712 }
0713 }
0714
0715
0716 bool isVPOpcode() const { return ISD::isVPOpcode(getOpcode()); }
0717
0718
0719
0720 bool isMachineOpcode() const { return NodeType < 0; }
0721
0722
0723
0724
0725 unsigned getMachineOpcode() const {
0726 assert(isMachineOpcode() && "Not a MachineInstr opcode!");
0727 return ~NodeType;
0728 }
0729
0730 bool getHasDebugValue() const { return SDNodeBits.HasDebugValue; }
0731 void setHasDebugValue(bool b) { SDNodeBits.HasDebugValue = b; }
0732
0733 bool isDivergent() const { return SDNodeBits.IsDivergent; }
0734
0735
0736 bool use_empty() const { return UseList == nullptr; }
0737
0738
0739 bool hasOneUse() const { return hasSingleElement(uses()); }
0740
0741
0742
0743 size_t use_size() const { return std::distance(use_begin(), use_end()); }
0744
0745
0746 int getNodeId() const { return NodeId; }
0747
0748
0749 void setNodeId(int Id) { NodeId = Id; }
0750
0751
0752 int getCombinerWorklistIndex() const { return CombinerWorklistIndex; }
0753
0754
0755 void setCombinerWorklistIndex(int Index) { CombinerWorklistIndex = Index; }
0756
0757
0758 unsigned getIROrder() const { return IROrder; }
0759
0760
0761 void setIROrder(unsigned Order) { IROrder = Order; }
0762
0763
0764 const DebugLoc &getDebugLoc() const { return debugLoc; }
0765
0766
0767
0768 void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); }
0769
0770
0771
0772 class use_iterator {
0773 friend class SDNode;
0774
0775 SDUse *Op = nullptr;
0776
0777 explicit use_iterator(SDUse *op) : Op(op) {}
0778
0779 public:
0780 using iterator_category = std::forward_iterator_tag;
0781 using value_type = SDUse;
0782 using difference_type = std::ptrdiff_t;
0783 using pointer = value_type *;
0784 using reference = value_type &;
0785
0786 use_iterator() = default;
0787 use_iterator(const use_iterator &I) = default;
0788 use_iterator &operator=(const use_iterator &) = default;
0789
0790 bool operator==(const use_iterator &x) const { return Op == x.Op; }
0791 bool operator!=(const use_iterator &x) const {
0792 return !operator==(x);
0793 }
0794
0795
0796 use_iterator &operator++() {
0797 assert(Op && "Cannot increment end iterator!");
0798 Op = Op->getNext();
0799 return *this;
0800 }
0801
0802 use_iterator operator++(int) {
0803 use_iterator tmp = *this; ++*this; return tmp;
0804 }
0805
0806
0807 SDUse &operator*() const {
0808 assert(Op && "Cannot dereference end iterator!");
0809 return *Op;
0810 }
0811
0812 SDUse *operator->() const { return &operator*(); }
0813 };
0814
0815 class user_iterator {
0816 friend class SDNode;
0817 use_iterator UI;
0818
0819 explicit user_iterator(SDUse *op) : UI(op) {};
0820
0821 public:
0822 using iterator_category = std::forward_iterator_tag;
0823 using value_type = SDNode *;
0824 using difference_type = std::ptrdiff_t;
0825 using pointer = value_type *;
0826 using reference = value_type &;
0827
0828 user_iterator() = default;
0829
0830 bool operator==(const user_iterator &x) const { return UI == x.UI; }
0831 bool operator!=(const user_iterator &x) const { return !operator==(x); }
0832
0833 user_iterator &operator++() {
0834 ++UI;
0835 return *this;
0836 }
0837
0838 user_iterator operator++(int) {
0839 auto tmp = *this;
0840 ++*this;
0841 return tmp;
0842 }
0843
0844
0845 SDNode *operator*() const { return UI->getUser(); }
0846
0847 SDNode *operator->() const { return operator*(); }
0848
0849 SDUse &getUse() const { return *UI; }
0850 };
0851
0852
0853 use_iterator use_begin() const {
0854 return use_iterator(UseList);
0855 }
0856
0857 static use_iterator use_end() { return use_iterator(nullptr); }
0858
0859 inline iterator_range<use_iterator> uses() {
0860 return make_range(use_begin(), use_end());
0861 }
0862 inline iterator_range<use_iterator> uses() const {
0863 return make_range(use_begin(), use_end());
0864 }
0865
0866
0867 user_iterator user_begin() const { return user_iterator(UseList); }
0868
0869 static user_iterator user_end() { return user_iterator(nullptr); }
0870
0871 inline iterator_range<user_iterator> users() {
0872 return make_range(user_begin(), user_end());
0873 }
0874 inline iterator_range<user_iterator> users() const {
0875 return make_range(user_begin(), user_end());
0876 }
0877
0878
0879
0880 bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
0881
0882
0883
0884 bool hasAnyUseOfValue(unsigned Value) const;
0885
0886
0887 bool isOnlyUserOf(const SDNode *N) const;
0888
0889
0890 bool isOperandOf(const SDNode *N) const;
0891
0892
0893
0894
0895 bool isPredecessorOf(const SDNode *N) const {
0896 return N->hasPredecessor(this);
0897 }
0898
0899
0900
0901
0902
0903 bool hasPredecessor(const SDNode *N) const;
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 static bool hasPredecessorHelper(const SDNode *N,
0915 SmallPtrSetImpl<const SDNode *> &Visited,
0916 SmallVectorImpl<const SDNode *> &Worklist,
0917 unsigned int MaxSteps = 0,
0918 bool TopologicalPrune = false) {
0919 if (Visited.count(N))
0920 return true;
0921
0922 SmallVector<const SDNode *, 8> DeferredNodes;
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934 int NId = N->getNodeId();
0935
0936 if (NId < -1)
0937 NId = -(NId + 1);
0938
0939 bool Found = false;
0940 while (!Worklist.empty()) {
0941 const SDNode *M = Worklist.pop_back_val();
0942 int MId = M->getNodeId();
0943 if (TopologicalPrune && M->getOpcode() != ISD::TokenFactor && (NId > 0) &&
0944 (MId > 0) && (MId < NId)) {
0945 DeferredNodes.push_back(M);
0946 continue;
0947 }
0948 for (const SDValue &OpV : M->op_values()) {
0949 SDNode *Op = OpV.getNode();
0950 if (Visited.insert(Op).second)
0951 Worklist.push_back(Op);
0952 if (Op == N)
0953 Found = true;
0954 }
0955 if (Found)
0956 break;
0957 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
0958 break;
0959 }
0960
0961 Worklist.append(DeferredNodes.begin(), DeferredNodes.end());
0962
0963 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
0964 return true;
0965 return Found;
0966 }
0967
0968
0969
0970 static bool areOnlyUsersOf(ArrayRef<const SDNode *> Nodes, const SDNode *N);
0971
0972
0973 unsigned getNumOperands() const { return NumOperands; }
0974
0975
0976 static constexpr size_t getMaxNumOperands() {
0977 return std::numeric_limits<decltype(SDNode::NumOperands)>::max();
0978 }
0979
0980
0981 inline uint64_t getConstantOperandVal(unsigned Num) const;
0982
0983
0984 inline uint64_t getAsZExtVal() const;
0985
0986
0987 inline const APInt &getConstantOperandAPInt(unsigned Num) const;
0988
0989
0990 inline const APInt &getAsAPIntVal() const;
0991
0992 const SDValue &getOperand(unsigned Num) const {
0993 assert(Num < NumOperands && "Invalid child # of SDNode!");
0994 return OperandList[Num];
0995 }
0996
0997 using op_iterator = SDUse *;
0998
0999 op_iterator op_begin() const { return OperandList; }
1000 op_iterator op_end() const { return OperandList+NumOperands; }
1001 ArrayRef<SDUse> ops() const { return ArrayRef(op_begin(), op_end()); }
1002
1003
1004 struct value_op_iterator
1005 : iterator_adaptor_base<value_op_iterator, op_iterator,
1006 std::random_access_iterator_tag, SDValue,
1007 ptrdiff_t, value_op_iterator *,
1008 value_op_iterator *> {
1009 explicit value_op_iterator(SDUse *U = nullptr)
1010 : iterator_adaptor_base(U) {}
1011
1012 const SDValue &operator*() const { return I->get(); }
1013 };
1014
1015 iterator_range<value_op_iterator> op_values() const {
1016 return make_range(value_op_iterator(op_begin()),
1017 value_op_iterator(op_end()));
1018 }
1019
1020 SDVTList getVTList() const {
1021 SDVTList X = { ValueList, NumValues };
1022 return X;
1023 }
1024
1025
1026
1027 SDNode *getGluedNode() const {
1028 if (getNumOperands() != 0 &&
1029 getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
1030 return getOperand(getNumOperands()-1).getNode();
1031 return nullptr;
1032 }
1033
1034
1035
1036 SDNode *getGluedUser() const {
1037 for (SDUse &U : uses())
1038 if (U.getValueType() == MVT::Glue)
1039 return U.getUser();
1040 return nullptr;
1041 }
1042
1043 SDNodeFlags getFlags() const { return Flags; }
1044 void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
1045 void dropFlags(unsigned Mask) { Flags &= ~Mask; }
1046
1047
1048
1049 void intersectFlagsWith(const SDNodeFlags Flags);
1050
1051 bool hasPoisonGeneratingFlags() const {
1052 return Flags.Flags & SDNodeFlags::PoisonGeneratingFlags;
1053 }
1054
1055 void setCFIType(uint32_t Type) { CFIType = Type; }
1056 uint32_t getCFIType() const { return CFIType; }
1057
1058
1059 unsigned getNumValues() const { return NumValues; }
1060
1061
1062 EVT getValueType(unsigned ResNo) const {
1063 assert(ResNo < NumValues && "Illegal result number!");
1064 return ValueList[ResNo];
1065 }
1066
1067
1068 MVT getSimpleValueType(unsigned ResNo) const {
1069 return getValueType(ResNo).getSimpleVT();
1070 }
1071
1072
1073
1074
1075
1076
1077 TypeSize getValueSizeInBits(unsigned ResNo) const {
1078 return getValueType(ResNo).getSizeInBits();
1079 }
1080
1081 using value_iterator = const EVT *;
1082
1083 value_iterator value_begin() const { return ValueList; }
1084 value_iterator value_end() const { return ValueList+NumValues; }
1085 iterator_range<value_iterator> values() const {
1086 return llvm::make_range(value_begin(), value_end());
1087 }
1088
1089
1090 std::string getOperationName(const SelectionDAG *G = nullptr) const;
1091 static const char* getIndexedModeName(ISD::MemIndexedMode AM);
1092 void print_types(raw_ostream &OS, const SelectionDAG *G) const;
1093 void print_details(raw_ostream &OS, const SelectionDAG *G) const;
1094 void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1095 void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1096
1097
1098
1099
1100
1101
1102
1103 void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const;
1104
1105
1106
1107
1108
1109
1110
1111 void printrWithDepth(raw_ostream &O, const SelectionDAG *G = nullptr,
1112 unsigned depth = 100) const;
1113
1114
1115 void dump() const;
1116
1117
1118 void dumpr() const;
1119
1120
1121
1122
1123 void dump(const SelectionDAG *G) const;
1124
1125
1126
1127
1128 void dumpr(const SelectionDAG *G) const;
1129
1130
1131
1132
1133
1134 void dumprFull(const SelectionDAG *G = nullptr) const;
1135
1136
1137
1138
1139
1140
1141 void dumprWithDepth(const SelectionDAG *G = nullptr,
1142 unsigned depth = 100) const;
1143
1144
1145 void Profile(FoldingSetNodeID &ID) const;
1146
1147
1148 void addUse(SDUse &U) { U.addToList(&UseList); }
1149
1150 protected:
1151 static SDVTList getSDVTList(MVT VT) {
1152 SDVTList Ret = { getValueTypeList(VT), 1 };
1153 return Ret;
1154 }
1155
1156
1157
1158
1159
1160 SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs)
1161 : NodeType(Opc), ValueList(VTs.VTs), NumValues(VTs.NumVTs),
1162 IROrder(Order), debugLoc(std::move(dl)) {
1163 memset(&RawSDNodeBits, 0, sizeof(RawSDNodeBits));
1164 assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
1165 assert(NumValues == VTs.NumVTs &&
1166 "NumValues wasn't wide enough for its operands!");
1167 }
1168
1169
1170 void DropOperands();
1171 };
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182 class SDLoc {
1183 private:
1184 DebugLoc DL;
1185 int IROrder = 0;
1186
1187 public:
1188 SDLoc() = default;
1189 SDLoc(const SDNode *N) : DL(N->getDebugLoc()), IROrder(N->getIROrder()) {}
1190 SDLoc(const SDValue V) : SDLoc(V.getNode()) {}
1191 SDLoc(const Instruction *I, int Order) : IROrder(Order) {
1192 assert(Order >= 0 && "bad IROrder");
1193 if (I)
1194 DL = I->getDebugLoc();
1195 }
1196
1197 unsigned getIROrder() const { return IROrder; }
1198 const DebugLoc &getDebugLoc() const { return DL; }
1199 };
1200
1201
1202
1203 inline SDValue::SDValue(SDNode *node, unsigned resno)
1204 : Node(node), ResNo(resno) {
1205
1206
1207
1208 assert((!Node || !ResNo || ResNo < Node->getNumValues()) &&
1209 "Invalid result number for the given node!");
1210 assert(ResNo < -2U && "Cannot use result numbers reserved for DenseMaps.");
1211 }
1212
1213 inline unsigned SDValue::getOpcode() const {
1214 return Node->getOpcode();
1215 }
1216
1217 inline EVT SDValue::getValueType() const {
1218 return Node->getValueType(ResNo);
1219 }
1220
1221 inline unsigned SDValue::getNumOperands() const {
1222 return Node->getNumOperands();
1223 }
1224
1225 inline const SDValue &SDValue::getOperand(unsigned i) const {
1226 return Node->getOperand(i);
1227 }
1228
1229 inline uint64_t SDValue::getConstantOperandVal(unsigned i) const {
1230 return Node->getConstantOperandVal(i);
1231 }
1232
1233 inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const {
1234 return Node->getConstantOperandAPInt(i);
1235 }
1236
1237 inline bool SDValue::isTargetOpcode() const {
1238 return Node->isTargetOpcode();
1239 }
1240
1241 inline bool SDValue::isMachineOpcode() const {
1242 return Node->isMachineOpcode();
1243 }
1244
1245 inline unsigned SDValue::getMachineOpcode() const {
1246 return Node->getMachineOpcode();
1247 }
1248
1249 inline bool SDValue::isUndef() const {
1250 return Node->isUndef();
1251 }
1252
1253 inline bool SDValue::use_empty() const {
1254 return !Node->hasAnyUseOfValue(ResNo);
1255 }
1256
1257 inline bool SDValue::hasOneUse() const {
1258 return Node->hasNUsesOfValue(1, ResNo);
1259 }
1260
1261 inline const DebugLoc &SDValue::getDebugLoc() const {
1262 return Node->getDebugLoc();
1263 }
1264
1265 inline void SDValue::dump() const {
1266 return Node->dump();
1267 }
1268
1269 inline void SDValue::dump(const SelectionDAG *G) const {
1270 return Node->dump(G);
1271 }
1272
1273 inline void SDValue::dumpr() const {
1274 return Node->dumpr();
1275 }
1276
1277 inline void SDValue::dumpr(const SelectionDAG *G) const {
1278 return Node->dumpr(G);
1279 }
1280
1281
1282 inline unsigned SDUse::getOperandNo() const {
1283 return this - getUser()->op_begin();
1284 }
1285
1286 inline void SDUse::set(const SDValue &V) {
1287 if (Val.getNode()) removeFromList();
1288 Val = V;
1289 if (V.getNode())
1290 V->addUse(*this);
1291 }
1292
1293 inline void SDUse::setInitial(const SDValue &V) {
1294 Val = V;
1295 V->addUse(*this);
1296 }
1297
1298 inline void SDUse::setNode(SDNode *N) {
1299 if (Val.getNode()) removeFromList();
1300 Val.setNode(N);
1301 if (N) N->addUse(*this);
1302 }
1303
1304
1305
1306
1307
1308 class HandleSDNode : public SDNode {
1309 SDUse Op;
1310
1311 public:
1312 explicit HandleSDNode(SDValue X)
1313 : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) {
1314
1315
1316 PersistentId = 0xffff;
1317
1318
1319
1320
1321
1322 Op.setUser(this);
1323 Op.setInitial(X);
1324 NumOperands = 1;
1325 OperandList = &Op;
1326 }
1327 ~HandleSDNode();
1328
1329 const SDValue &getValue() const { return Op; }
1330 };
1331
1332 class AddrSpaceCastSDNode : public SDNode {
1333 private:
1334 unsigned SrcAddrSpace;
1335 unsigned DestAddrSpace;
1336
1337 public:
1338 AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
1339 unsigned SrcAS, unsigned DestAS)
1340 : SDNode(ISD::ADDRSPACECAST, Order, dl, VTs), SrcAddrSpace(SrcAS),
1341 DestAddrSpace(DestAS) {}
1342
1343 unsigned getSrcAddressSpace() const { return SrcAddrSpace; }
1344 unsigned getDestAddressSpace() const { return DestAddrSpace; }
1345
1346 static bool classof(const SDNode *N) {
1347 return N->getOpcode() == ISD::ADDRSPACECAST;
1348 }
1349 };
1350
1351
1352 class MemSDNode : public SDNode {
1353 private:
1354
1355 EVT MemoryVT;
1356
1357 protected:
1358
1359 MachineMemOperand *MMO;
1360
1361 public:
1362 MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs,
1363 EVT memvt, MachineMemOperand *MMO);
1364
1365 bool readMem() const { return MMO->isLoad(); }
1366 bool writeMem() const { return MMO->isStore(); }
1367
1368
1369 Align getOriginalAlign() const { return MMO->getBaseAlign(); }
1370 Align getAlign() const { return MMO->getAlign(); }
1371
1372
1373
1374
1375
1376
1377
1378 unsigned getRawSubclassData() const {
1379 uint16_t Data;
1380 union {
1381 char RawSDNodeBits[sizeof(uint16_t)];
1382 SDNodeBitfields SDNodeBits;
1383 };
1384 memcpy(&RawSDNodeBits, &this->RawSDNodeBits, sizeof(this->RawSDNodeBits));
1385 SDNodeBits.HasDebugValue = 0;
1386 SDNodeBits.IsDivergent = false;
1387 memcpy(&Data, &RawSDNodeBits, sizeof(RawSDNodeBits));
1388 return Data;
1389 }
1390
1391 bool isVolatile() const { return MemSDNodeBits.IsVolatile; }
1392 bool isNonTemporal() const { return MemSDNodeBits.IsNonTemporal; }
1393 bool isDereferenceable() const { return MemSDNodeBits.IsDereferenceable; }
1394 bool isInvariant() const { return MemSDNodeBits.IsInvariant; }
1395
1396
1397 int64_t getSrcValueOffset() const { return MMO->getOffset(); }
1398
1399
1400 AAMDNodes getAAInfo() const { return MMO->getAAInfo(); }
1401
1402
1403 const MDNode *getRanges() const { return MMO->getRanges(); }
1404
1405
1406 SyncScope::ID getSyncScopeID() const { return MMO->getSyncScopeID(); }
1407
1408
1409
1410
1411 AtomicOrdering getSuccessOrdering() const {
1412 return MMO->getSuccessOrdering();
1413 }
1414
1415
1416
1417
1418 AtomicOrdering getMergedOrdering() const { return MMO->getMergedOrdering(); }
1419
1420
1421 bool isAtomic() const { return MMO->isAtomic(); }
1422
1423
1424
1425
1426 bool isUnordered() const { return MMO->isUnordered(); }
1427
1428
1429 bool isSimple() const { return !isAtomic() && !isVolatile(); }
1430
1431
1432 EVT getMemoryVT() const { return MemoryVT; }
1433
1434
1435
1436 MachineMemOperand *getMemOperand() const { return MMO; }
1437
1438 const MachinePointerInfo &getPointerInfo() const {
1439 return MMO->getPointerInfo();
1440 }
1441
1442
1443 unsigned getAddressSpace() const {
1444 return getPointerInfo().getAddrSpace();
1445 }
1446
1447
1448
1449
1450
1451 void refineAlignment(const MachineMemOperand *NewMMO) {
1452 MMO->refineAlignment(NewMMO);
1453 }
1454
1455 const SDValue &getChain() const { return getOperand(0); }
1456
1457 const SDValue &getBasePtr() const {
1458 switch (getOpcode()) {
1459 case ISD::STORE:
1460 case ISD::ATOMIC_STORE:
1461 case ISD::VP_STORE:
1462 case ISD::MSTORE:
1463 case ISD::VP_SCATTER:
1464 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1465 return getOperand(2);
1466 case ISD::MGATHER:
1467 case ISD::MSCATTER:
1468 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
1469 return getOperand(3);
1470 default:
1471 return getOperand(1);
1472 }
1473 }
1474
1475
1476 static bool classof(const SDNode *N) {
1477
1478
1479 switch (N->getOpcode()) {
1480 case ISD::LOAD:
1481 case ISD::STORE:
1482 case ISD::ATOMIC_CMP_SWAP:
1483 case ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS:
1484 case ISD::ATOMIC_SWAP:
1485 case ISD::ATOMIC_LOAD_ADD:
1486 case ISD::ATOMIC_LOAD_SUB:
1487 case ISD::ATOMIC_LOAD_AND:
1488 case ISD::ATOMIC_LOAD_CLR:
1489 case ISD::ATOMIC_LOAD_OR:
1490 case ISD::ATOMIC_LOAD_XOR:
1491 case ISD::ATOMIC_LOAD_NAND:
1492 case ISD::ATOMIC_LOAD_MIN:
1493 case ISD::ATOMIC_LOAD_MAX:
1494 case ISD::ATOMIC_LOAD_UMIN:
1495 case ISD::ATOMIC_LOAD_UMAX:
1496 case ISD::ATOMIC_LOAD_FADD:
1497 case ISD::ATOMIC_LOAD_FSUB:
1498 case ISD::ATOMIC_LOAD_FMAX:
1499 case ISD::ATOMIC_LOAD_FMIN:
1500 case ISD::ATOMIC_LOAD_UINC_WRAP:
1501 case ISD::ATOMIC_LOAD_UDEC_WRAP:
1502 case ISD::ATOMIC_LOAD_USUB_COND:
1503 case ISD::ATOMIC_LOAD_USUB_SAT:
1504 case ISD::ATOMIC_LOAD:
1505 case ISD::ATOMIC_STORE:
1506 case ISD::MLOAD:
1507 case ISD::MSTORE:
1508 case ISD::MGATHER:
1509 case ISD::MSCATTER:
1510 case ISD::VP_LOAD:
1511 case ISD::VP_STORE:
1512 case ISD::VP_GATHER:
1513 case ISD::VP_SCATTER:
1514 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1515 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1516 case ISD::GET_FPENV_MEM:
1517 case ISD::SET_FPENV_MEM:
1518 case ISD::EXPERIMENTAL_VECTOR_HISTOGRAM:
1519 return true;
1520 default:
1521 return N->isMemIntrinsic();
1522 }
1523 }
1524 };
1525
1526
1527 class AtomicSDNode : public MemSDNode {
1528 public:
1529 AtomicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTL,
1530 EVT MemVT, MachineMemOperand *MMO)
1531 : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
1532 assert(((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) ||
1533 MMO->isAtomic()) && "then why are we using an AtomicSDNode?");
1534 }
1535
1536 void setExtensionType(ISD::LoadExtType ETy) {
1537 assert(getOpcode() == ISD::ATOMIC_LOAD && "Only used for atomic loads.");
1538 LoadSDNodeBits.ExtTy = ETy;
1539 }
1540
1541 ISD::LoadExtType getExtensionType() const {
1542 assert(getOpcode() == ISD::ATOMIC_LOAD && "Only used for atomic loads.");
1543 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
1544 }
1545
1546 const SDValue &getBasePtr() const {
1547 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(2) : getOperand(1);
1548 }
1549 const SDValue &getVal() const {
1550 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(1) : getOperand(2);
1551 }
1552
1553
1554
1555 bool isCompareAndSwap() const {
1556 unsigned Op = getOpcode();
1557 return Op == ISD::ATOMIC_CMP_SWAP ||
1558 Op == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS;
1559 }
1560
1561
1562
1563 AtomicOrdering getFailureOrdering() const {
1564 assert(isCompareAndSwap() && "Must be cmpxchg operation");
1565 return MMO->getFailureOrdering();
1566 }
1567
1568
1569 static bool classof(const SDNode *N) {
1570 return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
1571 N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
1572 N->getOpcode() == ISD::ATOMIC_SWAP ||
1573 N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1574 N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1575 N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1576 N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1577 N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1578 N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1579 N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1580 N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1581 N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1582 N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1583 N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1584 N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1585 N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1586 N->getOpcode() == ISD::ATOMIC_LOAD_FMAX ||
1587 N->getOpcode() == ISD::ATOMIC_LOAD_FMIN ||
1588 N->getOpcode() == ISD::ATOMIC_LOAD_UINC_WRAP ||
1589 N->getOpcode() == ISD::ATOMIC_LOAD_UDEC_WRAP ||
1590 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_COND ||
1591 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_SAT ||
1592 N->getOpcode() == ISD::ATOMIC_LOAD ||
1593 N->getOpcode() == ISD::ATOMIC_STORE;
1594 }
1595 };
1596
1597
1598
1599
1600
1601 class MemIntrinsicSDNode : public MemSDNode {
1602 public:
1603 MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
1604 SDVTList VTs, EVT MemoryVT, MachineMemOperand *MMO)
1605 : MemSDNode(Opc, Order, dl, VTs, MemoryVT, MMO) {
1606 SDNodeBits.IsMemIntrinsic = true;
1607 }
1608
1609
1610 static bool classof(const SDNode *N) {
1611
1612
1613 return N->isMemIntrinsic();
1614 }
1615 };
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625 class ShuffleVectorSDNode : public SDNode {
1626
1627
1628 const int *Mask;
1629
1630 protected:
1631 friend class SelectionDAG;
1632
1633 ShuffleVectorSDNode(SDVTList VTs, unsigned Order, const DebugLoc &dl,
1634 const int *M)
1635 : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, VTs), Mask(M) {}
1636
1637 public:
1638 ArrayRef<int> getMask() const {
1639 EVT VT = getValueType(0);
1640 return ArrayRef(Mask, VT.getVectorNumElements());
1641 }
1642
1643 int getMaskElt(unsigned Idx) const {
1644 assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!");
1645 return Mask[Idx];
1646 }
1647
1648 bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
1649
1650 int getSplatIndex() const {
1651 assert(isSplat() && "Cannot get splat index for non-splat!");
1652 EVT VT = getValueType(0);
1653 for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i)
1654 if (Mask[i] >= 0)
1655 return Mask[i];
1656
1657
1658
1659 return 0;
1660 }
1661
1662 static bool isSplatMask(const int *Mask, EVT VT);
1663
1664
1665
1666 static void commuteMask(MutableArrayRef<int> Mask) {
1667 unsigned NumElems = Mask.size();
1668 for (unsigned i = 0; i != NumElems; ++i) {
1669 int idx = Mask[i];
1670 if (idx < 0)
1671 continue;
1672 else if (idx < (int)NumElems)
1673 Mask[i] = idx + NumElems;
1674 else
1675 Mask[i] = idx - NumElems;
1676 }
1677 }
1678
1679 static bool classof(const SDNode *N) {
1680 return N->getOpcode() == ISD::VECTOR_SHUFFLE;
1681 }
1682 };
1683
1684 class ConstantSDNode : public SDNode {
1685 friend class SelectionDAG;
1686
1687 const ConstantInt *Value;
1688
1689 ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val,
1690 SDVTList VTs)
1691 : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(),
1692 VTs),
1693 Value(val) {
1694 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1695 ConstantSDNodeBits.IsOpaque = isOpaque;
1696 }
1697
1698 public:
1699 const ConstantInt *getConstantIntValue() const { return Value; }
1700 const APInt &getAPIntValue() const { return Value->getValue(); }
1701 uint64_t getZExtValue() const { return Value->getZExtValue(); }
1702 int64_t getSExtValue() const { return Value->getSExtValue(); }
1703 uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX) {
1704 return Value->getLimitedValue(Limit);
1705 }
1706 MaybeAlign getMaybeAlignValue() const { return Value->getMaybeAlignValue(); }
1707 Align getAlignValue() const { return Value->getAlignValue(); }
1708
1709 bool isOne() const { return Value->isOne(); }
1710 bool isZero() const { return Value->isZero(); }
1711 bool isAllOnes() const { return Value->isMinusOne(); }
1712 bool isMaxSignedValue() const { return Value->isMaxValue(true); }
1713 bool isMinSignedValue() const { return Value->isMinValue(true); }
1714
1715 bool isOpaque() const { return ConstantSDNodeBits.IsOpaque; }
1716
1717 static bool classof(const SDNode *N) {
1718 return N->getOpcode() == ISD::Constant ||
1719 N->getOpcode() == ISD::TargetConstant;
1720 }
1721 };
1722
1723 uint64_t SDNode::getConstantOperandVal(unsigned Num) const {
1724 return cast<ConstantSDNode>(getOperand(Num))->getZExtValue();
1725 }
1726
1727 uint64_t SDNode::getAsZExtVal() const {
1728 return cast<ConstantSDNode>(this)->getZExtValue();
1729 }
1730
1731 const APInt &SDNode::getConstantOperandAPInt(unsigned Num) const {
1732 return cast<ConstantSDNode>(getOperand(Num))->getAPIntValue();
1733 }
1734
1735 const APInt &SDNode::getAsAPIntVal() const {
1736 return cast<ConstantSDNode>(this)->getAPIntValue();
1737 }
1738
1739 class ConstantFPSDNode : public SDNode {
1740 friend class SelectionDAG;
1741
1742 const ConstantFP *Value;
1743
1744 ConstantFPSDNode(bool isTarget, const ConstantFP *val, SDVTList VTs)
1745 : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0,
1746 DebugLoc(), VTs),
1747 Value(val) {
1748 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1749 }
1750
1751 public:
1752 const APFloat& getValueAPF() const { return Value->getValueAPF(); }
1753 const ConstantFP *getConstantFPValue() const { return Value; }
1754
1755
1756 bool isZero() const { return Value->isZero(); }
1757
1758
1759 bool isNaN() const { return Value->isNaN(); }
1760
1761
1762 bool isInfinity() const { return Value->isInfinity(); }
1763
1764
1765 bool isNegative() const { return Value->isNegative(); }
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775 bool isExactlyValue(double V) const {
1776 return Value->getValueAPF().isExactlyValue(V);
1777 }
1778 bool isExactlyValue(const APFloat& V) const;
1779
1780 static bool isValueValidForType(EVT VT, const APFloat& Val);
1781
1782 static bool classof(const SDNode *N) {
1783 return N->getOpcode() == ISD::ConstantFP ||
1784 N->getOpcode() == ISD::TargetConstantFP;
1785 }
1786 };
1787
1788
1789 bool isNullConstant(SDValue V);
1790
1791
1792 bool isNullConstantOrUndef(SDValue V);
1793
1794
1795 bool isNullFPConstant(SDValue V);
1796
1797
1798 bool isAllOnesConstant(SDValue V);
1799
1800
1801 bool isOneConstant(SDValue V);
1802
1803
1804 bool isMinSignedConstant(SDValue V);
1805
1806
1807
1808
1809 bool isNeutralConstant(unsigned Opc, SDNodeFlags Flags, SDValue V,
1810 unsigned OperandNo);
1811
1812
1813
1814 SDValue peekThroughBitcasts(SDValue V);
1815
1816
1817
1818 SDValue peekThroughOneUseBitcasts(SDValue V);
1819
1820
1821
1822 SDValue peekThroughExtractSubvectors(SDValue V);
1823
1824
1825
1826 SDValue peekThroughTruncates(SDValue V);
1827
1828
1829
1830 bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
1831
1832
1833
1834
1835 SDValue getBitwiseNotOperand(SDValue V, SDValue Mask, bool AllowUndefs);
1836
1837
1838 ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false,
1839 bool AllowTruncation = false);
1840
1841
1842
1843 ConstantSDNode *isConstOrConstSplat(SDValue N, const APInt &DemandedElts,
1844 bool AllowUndefs = false,
1845 bool AllowTruncation = false);
1846
1847
1848 ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false);
1849
1850
1851
1852 ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, const APInt &DemandedElts,
1853 bool AllowUndefs = false);
1854
1855
1856
1857
1858 bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false);
1859
1860
1861
1862
1863
1864 bool isOneOrOneSplat(SDValue V, bool AllowUndefs = false);
1865
1866
1867
1868
1869 bool isAllOnesOrAllOnesSplat(SDValue V, bool AllowUndefs = false);
1870
1871
1872 inline bool isIntOrFPConstant(SDValue V) {
1873 return isa<ConstantSDNode>(V) || isa<ConstantFPSDNode>(V);
1874 }
1875
1876 class GlobalAddressSDNode : public SDNode {
1877 friend class SelectionDAG;
1878
1879 const GlobalValue *TheGlobal;
1880 int64_t Offset;
1881 unsigned TargetFlags;
1882
1883 GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL,
1884 const GlobalValue *GA, SDVTList VTs, int64_t o,
1885 unsigned TF)
1886 : SDNode(Opc, Order, DL, VTs), TheGlobal(GA), Offset(o), TargetFlags(TF) {
1887 }
1888
1889 public:
1890 const GlobalValue *getGlobal() const { return TheGlobal; }
1891 int64_t getOffset() const { return Offset; }
1892 unsigned getTargetFlags() const { return TargetFlags; }
1893
1894 unsigned getAddressSpace() const;
1895
1896 static bool classof(const SDNode *N) {
1897 return N->getOpcode() == ISD::GlobalAddress ||
1898 N->getOpcode() == ISD::TargetGlobalAddress ||
1899 N->getOpcode() == ISD::GlobalTLSAddress ||
1900 N->getOpcode() == ISD::TargetGlobalTLSAddress;
1901 }
1902 };
1903
1904 class FrameIndexSDNode : public SDNode {
1905 friend class SelectionDAG;
1906
1907 int FI;
1908
1909 FrameIndexSDNode(int fi, SDVTList VTs, bool isTarg)
1910 : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, 0, DebugLoc(),
1911 VTs),
1912 FI(fi) {}
1913
1914 public:
1915 int getIndex() const { return FI; }
1916
1917 static bool classof(const SDNode *N) {
1918 return N->getOpcode() == ISD::FrameIndex ||
1919 N->getOpcode() == ISD::TargetFrameIndex;
1920 }
1921 };
1922
1923
1924
1925 class LifetimeSDNode : public SDNode {
1926 friend class SelectionDAG;
1927 int64_t Size;
1928 int64_t Offset;
1929
1930 LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl,
1931 SDVTList VTs, int64_t Size, int64_t Offset)
1932 : SDNode(Opcode, Order, dl, VTs), Size(Size), Offset(Offset) {}
1933 public:
1934 int64_t getFrameIndex() const {
1935 return cast<FrameIndexSDNode>(getOperand(1))->getIndex();
1936 }
1937
1938 bool hasOffset() const { return Offset >= 0; }
1939 int64_t getOffset() const {
1940 assert(hasOffset() && "offset is unknown");
1941 return Offset;
1942 }
1943 int64_t getSize() const {
1944 assert(hasOffset() && "offset is unknown");
1945 return Size;
1946 }
1947
1948
1949 static bool classof(const SDNode *N) {
1950 return N->getOpcode() == ISD::LIFETIME_START ||
1951 N->getOpcode() == ISD::LIFETIME_END;
1952 }
1953 };
1954
1955
1956
1957
1958
1959 class PseudoProbeSDNode : public SDNode {
1960 friend class SelectionDAG;
1961 uint64_t Guid;
1962 uint64_t Index;
1963 uint32_t Attributes;
1964
1965 PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl,
1966 SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr)
1967 : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index),
1968 Attributes(Attr) {}
1969
1970 public:
1971 uint64_t getGuid() const { return Guid; }
1972 uint64_t getIndex() const { return Index; }
1973 uint32_t getAttributes() const { return Attributes; }
1974
1975
1976 static bool classof(const SDNode *N) {
1977 return N->getOpcode() == ISD::PSEUDO_PROBE;
1978 }
1979 };
1980
1981 class JumpTableSDNode : public SDNode {
1982 friend class SelectionDAG;
1983
1984 int JTI;
1985 unsigned TargetFlags;
1986
1987 JumpTableSDNode(int jti, SDVTList VTs, bool isTarg, unsigned TF)
1988 : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, 0, DebugLoc(),
1989 VTs),
1990 JTI(jti), TargetFlags(TF) {}
1991
1992 public:
1993 int getIndex() const { return JTI; }
1994 unsigned getTargetFlags() const { return TargetFlags; }
1995
1996 static bool classof(const SDNode *N) {
1997 return N->getOpcode() == ISD::JumpTable ||
1998 N->getOpcode() == ISD::TargetJumpTable;
1999 }
2000 };
2001
2002 class ConstantPoolSDNode : public SDNode {
2003 friend class SelectionDAG;
2004
2005 union {
2006 const Constant *ConstVal;
2007 MachineConstantPoolValue *MachineCPVal;
2008 } Val;
2009 int Offset;
2010 Align Alignment;
2011 unsigned TargetFlags;
2012
2013 ConstantPoolSDNode(bool isTarget, const Constant *c, SDVTList VTs, int o,
2014 Align Alignment, unsigned TF)
2015 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2016 DebugLoc(), VTs),
2017 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2018 assert(Offset >= 0 && "Offset is too large");
2019 Val.ConstVal = c;
2020 }
2021
2022 ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, SDVTList VTs,
2023 int o, Align Alignment, unsigned TF)
2024 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2025 DebugLoc(), VTs),
2026 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2027 assert(Offset >= 0 && "Offset is too large");
2028 Val.MachineCPVal = v;
2029 Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
2030 }
2031
2032 public:
2033 bool isMachineConstantPoolEntry() const {
2034 return Offset < 0;
2035 }
2036
2037 const Constant *getConstVal() const {
2038 assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
2039 return Val.ConstVal;
2040 }
2041
2042 MachineConstantPoolValue *getMachineCPVal() const {
2043 assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
2044 return Val.MachineCPVal;
2045 }
2046
2047 int getOffset() const {
2048 return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
2049 }
2050
2051
2052
2053 Align getAlign() const { return Alignment; }
2054 unsigned getTargetFlags() const { return TargetFlags; }
2055
2056 Type *getType() const;
2057
2058 static bool classof(const SDNode *N) {
2059 return N->getOpcode() == ISD::ConstantPool ||
2060 N->getOpcode() == ISD::TargetConstantPool;
2061 }
2062 };
2063
2064
2065 class TargetIndexSDNode : public SDNode {
2066 friend class SelectionDAG;
2067
2068 unsigned TargetFlags;
2069 int Index;
2070 int64_t Offset;
2071
2072 public:
2073 TargetIndexSDNode(int Idx, SDVTList VTs, int64_t Ofs, unsigned TF)
2074 : SDNode(ISD::TargetIndex, 0, DebugLoc(), VTs), TargetFlags(TF),
2075 Index(Idx), Offset(Ofs) {}
2076
2077 unsigned getTargetFlags() const { return TargetFlags; }
2078 int getIndex() const { return Index; }
2079 int64_t getOffset() const { return Offset; }
2080
2081 static bool classof(const SDNode *N) {
2082 return N->getOpcode() == ISD::TargetIndex;
2083 }
2084 };
2085
2086 class BasicBlockSDNode : public SDNode {
2087 friend class SelectionDAG;
2088
2089 MachineBasicBlock *MBB;
2090
2091
2092
2093
2094 explicit BasicBlockSDNode(MachineBasicBlock *mbb)
2095 : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb)
2096 {}
2097
2098 public:
2099 MachineBasicBlock *getBasicBlock() const { return MBB; }
2100
2101 static bool classof(const SDNode *N) {
2102 return N->getOpcode() == ISD::BasicBlock;
2103 }
2104 };
2105
2106
2107 class BuildVectorSDNode : public SDNode {
2108 public:
2109
2110 explicit BuildVectorSDNode() = delete;
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121 bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
2122 unsigned &SplatBitSize, bool &HasAnyUndefs,
2123 unsigned MinSplatBits = 0,
2124 bool isBigEndian = false) const;
2125
2126
2127
2128
2129
2130
2131
2132 SDValue getSplatValue(const APInt &DemandedElts,
2133 BitVector *UndefElements = nullptr) const;
2134
2135
2136
2137
2138
2139 SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152 bool getRepeatedSequence(const APInt &DemandedElts,
2153 SmallVectorImpl<SDValue> &Sequence,
2154 BitVector *UndefElements = nullptr) const;
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165 bool getRepeatedSequence(SmallVectorImpl<SDValue> &Sequence,
2166 BitVector *UndefElements = nullptr) const;
2167
2168
2169
2170
2171
2172
2173
2174 ConstantSDNode *
2175 getConstantSplatNode(const APInt &DemandedElts,
2176 BitVector *UndefElements = nullptr) const;
2177
2178
2179
2180
2181
2182
2183 ConstantSDNode *
2184 getConstantSplatNode(BitVector *UndefElements = nullptr) const;
2185
2186
2187
2188
2189
2190
2191
2192 ConstantFPSDNode *
2193 getConstantFPSplatNode(const APInt &DemandedElts,
2194 BitVector *UndefElements = nullptr) const;
2195
2196
2197
2198
2199
2200
2201 ConstantFPSDNode *
2202 getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
2203
2204
2205
2206
2207
2208
2209 int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements,
2210 uint32_t BitWidth) const;
2211
2212
2213
2214
2215
2216 bool getConstantRawBits(bool IsLittleEndian, unsigned DstEltSizeInBits,
2217 SmallVectorImpl<APInt> &RawBitElements,
2218 BitVector &UndefElements) const;
2219
2220 bool isConstant() const;
2221
2222
2223
2224
2225 std::optional<std::pair<APInt, APInt>> isConstantSequence() const;
2226
2227
2228
2229
2230 static void recastRawBits(bool IsLittleEndian, unsigned DstEltSizeInBits,
2231 SmallVectorImpl<APInt> &DstBitElements,
2232 ArrayRef<APInt> SrcBitElements,
2233 BitVector &DstUndefElements,
2234 const BitVector &SrcUndefElements);
2235
2236 static bool classof(const SDNode *N) {
2237 return N->getOpcode() == ISD::BUILD_VECTOR;
2238 }
2239 };
2240
2241
2242
2243
2244
2245 class SrcValueSDNode : public SDNode {
2246 friend class SelectionDAG;
2247
2248 const Value *V;
2249
2250
2251 explicit SrcValueSDNode(const Value *v)
2252 : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
2253
2254 public:
2255
2256 const Value *getValue() const { return V; }
2257
2258 static bool classof(const SDNode *N) {
2259 return N->getOpcode() == ISD::SRCVALUE;
2260 }
2261 };
2262
2263 class MDNodeSDNode : public SDNode {
2264 friend class SelectionDAG;
2265
2266 const MDNode *MD;
2267
2268 explicit MDNodeSDNode(const MDNode *md)
2269 : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md)
2270 {}
2271
2272 public:
2273 const MDNode *getMD() const { return MD; }
2274
2275 static bool classof(const SDNode *N) {
2276 return N->getOpcode() == ISD::MDNODE_SDNODE;
2277 }
2278 };
2279
2280 class RegisterSDNode : public SDNode {
2281 friend class SelectionDAG;
2282
2283 Register Reg;
2284
2285 RegisterSDNode(Register reg, SDVTList VTs)
2286 : SDNode(ISD::Register, 0, DebugLoc(), VTs), Reg(reg) {}
2287
2288 public:
2289 Register getReg() const { return Reg; }
2290
2291 static bool classof(const SDNode *N) {
2292 return N->getOpcode() == ISD::Register;
2293 }
2294 };
2295
2296 class RegisterMaskSDNode : public SDNode {
2297 friend class SelectionDAG;
2298
2299
2300 const uint32_t *RegMask;
2301
2302 RegisterMaskSDNode(const uint32_t *mask)
2303 : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)),
2304 RegMask(mask) {}
2305
2306 public:
2307 const uint32_t *getRegMask() const { return RegMask; }
2308
2309 static bool classof(const SDNode *N) {
2310 return N->getOpcode() == ISD::RegisterMask;
2311 }
2312 };
2313
2314 class BlockAddressSDNode : public SDNode {
2315 friend class SelectionDAG;
2316
2317 const BlockAddress *BA;
2318 int64_t Offset;
2319 unsigned TargetFlags;
2320
2321 BlockAddressSDNode(unsigned NodeTy, SDVTList VTs, const BlockAddress *ba,
2322 int64_t o, unsigned Flags)
2323 : SDNode(NodeTy, 0, DebugLoc(), VTs), BA(ba), Offset(o),
2324 TargetFlags(Flags) {}
2325
2326 public:
2327 const BlockAddress *getBlockAddress() const { return BA; }
2328 int64_t getOffset() const { return Offset; }
2329 unsigned getTargetFlags() const { return TargetFlags; }
2330
2331 static bool classof(const SDNode *N) {
2332 return N->getOpcode() == ISD::BlockAddress ||
2333 N->getOpcode() == ISD::TargetBlockAddress;
2334 }
2335 };
2336
2337 class LabelSDNode : public SDNode {
2338 friend class SelectionDAG;
2339
2340 MCSymbol *Label;
2341
2342 LabelSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, MCSymbol *L)
2343 : SDNode(Opcode, Order, dl, getSDVTList(MVT::Other)), Label(L) {
2344 assert(LabelSDNode::classof(this) && "not a label opcode");
2345 }
2346
2347 public:
2348 MCSymbol *getLabel() const { return Label; }
2349
2350 static bool classof(const SDNode *N) {
2351 return N->getOpcode() == ISD::EH_LABEL ||
2352 N->getOpcode() == ISD::ANNOTATION_LABEL;
2353 }
2354 };
2355
2356 class ExternalSymbolSDNode : public SDNode {
2357 friend class SelectionDAG;
2358
2359 const char *Symbol;
2360 unsigned TargetFlags;
2361
2362 ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF,
2363 SDVTList VTs)
2364 : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0,
2365 DebugLoc(), VTs),
2366 Symbol(Sym), TargetFlags(TF) {}
2367
2368 public:
2369 const char *getSymbol() const { return Symbol; }
2370 unsigned getTargetFlags() const { return TargetFlags; }
2371
2372 static bool classof(const SDNode *N) {
2373 return N->getOpcode() == ISD::ExternalSymbol ||
2374 N->getOpcode() == ISD::TargetExternalSymbol;
2375 }
2376 };
2377
2378 class MCSymbolSDNode : public SDNode {
2379 friend class SelectionDAG;
2380
2381 MCSymbol *Symbol;
2382
2383 MCSymbolSDNode(MCSymbol *Symbol, SDVTList VTs)
2384 : SDNode(ISD::MCSymbol, 0, DebugLoc(), VTs), Symbol(Symbol) {}
2385
2386 public:
2387 MCSymbol *getMCSymbol() const { return Symbol; }
2388
2389 static bool classof(const SDNode *N) {
2390 return N->getOpcode() == ISD::MCSymbol;
2391 }
2392 };
2393
2394 class CondCodeSDNode : public SDNode {
2395 friend class SelectionDAG;
2396
2397 ISD::CondCode Condition;
2398
2399 explicit CondCodeSDNode(ISD::CondCode Cond)
2400 : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2401 Condition(Cond) {}
2402
2403 public:
2404 ISD::CondCode get() const { return Condition; }
2405
2406 static bool classof(const SDNode *N) {
2407 return N->getOpcode() == ISD::CONDCODE;
2408 }
2409 };
2410
2411
2412
2413 class VTSDNode : public SDNode {
2414 friend class SelectionDAG;
2415
2416 EVT ValueType;
2417
2418 explicit VTSDNode(EVT VT)
2419 : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2420 ValueType(VT) {}
2421
2422 public:
2423 EVT getVT() const { return ValueType; }
2424
2425 static bool classof(const SDNode *N) {
2426 return N->getOpcode() == ISD::VALUETYPE;
2427 }
2428 };
2429
2430
2431 class LSBaseSDNode : public MemSDNode {
2432 public:
2433 LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl,
2434 SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT,
2435 MachineMemOperand *MMO)
2436 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2437 LSBaseSDNodeBits.AddressingMode = AM;
2438 assert(getAddressingMode() == AM && "Value truncated");
2439 }
2440
2441 const SDValue &getOffset() const {
2442 return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
2443 }
2444
2445
2446
2447 ISD::MemIndexedMode getAddressingMode() const {
2448 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2449 }
2450
2451
2452 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2453
2454
2455 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2456
2457 static bool classof(const SDNode *N) {
2458 return N->getOpcode() == ISD::LOAD ||
2459 N->getOpcode() == ISD::STORE;
2460 }
2461 };
2462
2463
2464 class LoadSDNode : public LSBaseSDNode {
2465 friend class SelectionDAG;
2466
2467 LoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2468 ISD::MemIndexedMode AM, ISD::LoadExtType ETy, EVT MemVT,
2469 MachineMemOperand *MMO)
2470 : LSBaseSDNode(ISD::LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2471 LoadSDNodeBits.ExtTy = ETy;
2472 assert(readMem() && "Load MachineMemOperand is not a load!");
2473 assert(!writeMem() && "Load MachineMemOperand is a store!");
2474 }
2475
2476 public:
2477
2478
2479 ISD::LoadExtType getExtensionType() const {
2480 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2481 }
2482
2483 const SDValue &getBasePtr() const { return getOperand(1); }
2484 const SDValue &getOffset() const { return getOperand(2); }
2485
2486 static bool classof(const SDNode *N) {
2487 return N->getOpcode() == ISD::LOAD;
2488 }
2489 };
2490
2491
2492 class StoreSDNode : public LSBaseSDNode {
2493 friend class SelectionDAG;
2494
2495 StoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2496 ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT,
2497 MachineMemOperand *MMO)
2498 : LSBaseSDNode(ISD::STORE, Order, dl, VTs, AM, MemVT, MMO) {
2499 StoreSDNodeBits.IsTruncating = isTrunc;
2500 assert(!readMem() && "Store MachineMemOperand is a load!");
2501 assert(writeMem() && "Store MachineMemOperand is not a store!");
2502 }
2503
2504 public:
2505
2506
2507
2508 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2509 void setTruncatingStore(bool Truncating) {
2510 StoreSDNodeBits.IsTruncating = Truncating;
2511 }
2512
2513 const SDValue &getValue() const { return getOperand(1); }
2514 const SDValue &getBasePtr() const { return getOperand(2); }
2515 const SDValue &getOffset() const { return getOperand(3); }
2516
2517 static bool classof(const SDNode *N) {
2518 return N->getOpcode() == ISD::STORE;
2519 }
2520 };
2521
2522
2523
2524 class VPBaseLoadStoreSDNode : public MemSDNode {
2525 public:
2526 friend class SelectionDAG;
2527
2528 VPBaseLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2529 const DebugLoc &DL, SDVTList VTs,
2530 ISD::MemIndexedMode AM, EVT MemVT,
2531 MachineMemOperand *MMO)
2532 : MemSDNode(NodeTy, Order, DL, VTs, MemVT, MMO) {
2533 LSBaseSDNodeBits.AddressingMode = AM;
2534 assert(getAddressingMode() == AM && "Value truncated");
2535 }
2536
2537
2538
2539
2540
2541
2542
2543 const SDValue &getOffset() const {
2544 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2545 getOpcode() == ISD::VP_LOAD)
2546 ? 2
2547 : 3);
2548 }
2549 const SDValue &getBasePtr() const {
2550 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2551 getOpcode() == ISD::VP_LOAD)
2552 ? 1
2553 : 2);
2554 }
2555 const SDValue &getMask() const {
2556 switch (getOpcode()) {
2557 default:
2558 llvm_unreachable("Invalid opcode");
2559 case ISD::VP_LOAD:
2560 return getOperand(3);
2561 case ISD::VP_STORE:
2562 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2563 return getOperand(4);
2564 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2565 return getOperand(5);
2566 }
2567 }
2568 const SDValue &getVectorLength() const {
2569 switch (getOpcode()) {
2570 default:
2571 llvm_unreachable("Invalid opcode");
2572 case ISD::VP_LOAD:
2573 return getOperand(4);
2574 case ISD::VP_STORE:
2575 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2576 return getOperand(5);
2577 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2578 return getOperand(6);
2579 }
2580 }
2581
2582
2583
2584 ISD::MemIndexedMode getAddressingMode() const {
2585 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2586 }
2587
2588
2589 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2590
2591
2592 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2593
2594 static bool classof(const SDNode *N) {
2595 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2596 N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE ||
2597 N->getOpcode() == ISD::VP_LOAD || N->getOpcode() == ISD::VP_STORE;
2598 }
2599 };
2600
2601
2602 class VPLoadSDNode : public VPBaseLoadStoreSDNode {
2603 public:
2604 friend class SelectionDAG;
2605
2606 VPLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2607 ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool isExpanding,
2608 EVT MemVT, MachineMemOperand *MMO)
2609 : VPBaseLoadStoreSDNode(ISD::VP_LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2610 LoadSDNodeBits.ExtTy = ETy;
2611 LoadSDNodeBits.IsExpanding = isExpanding;
2612 }
2613
2614 ISD::LoadExtType getExtensionType() const {
2615 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2616 }
2617
2618 const SDValue &getBasePtr() const { return getOperand(1); }
2619 const SDValue &getOffset() const { return getOperand(2); }
2620 const SDValue &getMask() const { return getOperand(3); }
2621 const SDValue &getVectorLength() const { return getOperand(4); }
2622
2623 static bool classof(const SDNode *N) {
2624 return N->getOpcode() == ISD::VP_LOAD;
2625 }
2626 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2627 };
2628
2629
2630 class VPStridedLoadSDNode : public VPBaseLoadStoreSDNode {
2631 public:
2632 friend class SelectionDAG;
2633
2634 VPStridedLoadSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2635 ISD::MemIndexedMode AM, ISD::LoadExtType ETy,
2636 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2637 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_LOAD, Order, DL, VTs,
2638 AM, MemVT, MMO) {
2639 LoadSDNodeBits.ExtTy = ETy;
2640 LoadSDNodeBits.IsExpanding = IsExpanding;
2641 }
2642
2643 ISD::LoadExtType getExtensionType() const {
2644 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2645 }
2646
2647 const SDValue &getBasePtr() const { return getOperand(1); }
2648 const SDValue &getOffset() const { return getOperand(2); }
2649 const SDValue &getStride() const { return getOperand(3); }
2650 const SDValue &getMask() const { return getOperand(4); }
2651 const SDValue &getVectorLength() const { return getOperand(5); }
2652
2653 static bool classof(const SDNode *N) {
2654 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD;
2655 }
2656 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2657 };
2658
2659
2660 class VPStoreSDNode : public VPBaseLoadStoreSDNode {
2661 public:
2662 friend class SelectionDAG;
2663
2664 VPStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2665 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
2666 EVT MemVT, MachineMemOperand *MMO)
2667 : VPBaseLoadStoreSDNode(ISD::VP_STORE, Order, dl, VTs, AM, MemVT, MMO) {
2668 StoreSDNodeBits.IsTruncating = isTrunc;
2669 StoreSDNodeBits.IsCompressing = isCompressing;
2670 }
2671
2672
2673
2674
2675 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2676
2677
2678
2679
2680
2681 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2682
2683 const SDValue &getValue() const { return getOperand(1); }
2684 const SDValue &getBasePtr() const { return getOperand(2); }
2685 const SDValue &getOffset() const { return getOperand(3); }
2686 const SDValue &getMask() const { return getOperand(4); }
2687 const SDValue &getVectorLength() const { return getOperand(5); }
2688
2689 static bool classof(const SDNode *N) {
2690 return N->getOpcode() == ISD::VP_STORE;
2691 }
2692 };
2693
2694
2695 class VPStridedStoreSDNode : public VPBaseLoadStoreSDNode {
2696 public:
2697 friend class SelectionDAG;
2698
2699 VPStridedStoreSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2700 ISD::MemIndexedMode AM, bool IsTrunc, bool IsCompressing,
2701 EVT MemVT, MachineMemOperand *MMO)
2702 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_STORE, Order, DL,
2703 VTs, AM, MemVT, MMO) {
2704 StoreSDNodeBits.IsTruncating = IsTrunc;
2705 StoreSDNodeBits.IsCompressing = IsCompressing;
2706 }
2707
2708
2709
2710
2711 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2712
2713
2714
2715
2716
2717 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2718
2719 const SDValue &getValue() const { return getOperand(1); }
2720 const SDValue &getBasePtr() const { return getOperand(2); }
2721 const SDValue &getOffset() const { return getOperand(3); }
2722 const SDValue &getStride() const { return getOperand(4); }
2723 const SDValue &getMask() const { return getOperand(5); }
2724 const SDValue &getVectorLength() const { return getOperand(6); }
2725
2726 static bool classof(const SDNode *N) {
2727 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE;
2728 }
2729 };
2730
2731
2732 class MaskedLoadStoreSDNode : public MemSDNode {
2733 public:
2734 friend class SelectionDAG;
2735
2736 MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2737 const DebugLoc &dl, SDVTList VTs,
2738 ISD::MemIndexedMode AM, EVT MemVT,
2739 MachineMemOperand *MMO)
2740 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2741 LSBaseSDNodeBits.AddressingMode = AM;
2742 assert(getAddressingMode() == AM && "Value truncated");
2743 }
2744
2745
2746
2747
2748 const SDValue &getOffset() const {
2749 return getOperand(getOpcode() == ISD::MLOAD ? 2 : 3);
2750 }
2751 const SDValue &getMask() const {
2752 return getOperand(getOpcode() == ISD::MLOAD ? 3 : 4);
2753 }
2754
2755
2756
2757 ISD::MemIndexedMode getAddressingMode() const {
2758 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2759 }
2760
2761
2762 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2763
2764
2765 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2766
2767 static bool classof(const SDNode *N) {
2768 return N->getOpcode() == ISD::MLOAD ||
2769 N->getOpcode() == ISD::MSTORE;
2770 }
2771 };
2772
2773
2774 class MaskedLoadSDNode : public MaskedLoadStoreSDNode {
2775 public:
2776 friend class SelectionDAG;
2777
2778 MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2779 ISD::MemIndexedMode AM, ISD::LoadExtType ETy,
2780 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2781 : MaskedLoadStoreSDNode(ISD::MLOAD, Order, dl, VTs, AM, MemVT, MMO) {
2782 LoadSDNodeBits.ExtTy = ETy;
2783 LoadSDNodeBits.IsExpanding = IsExpanding;
2784 }
2785
2786 ISD::LoadExtType getExtensionType() const {
2787 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2788 }
2789
2790 const SDValue &getBasePtr() const { return getOperand(1); }
2791 const SDValue &getOffset() const { return getOperand(2); }
2792 const SDValue &getMask() const { return getOperand(3); }
2793 const SDValue &getPassThru() const { return getOperand(4); }
2794
2795 static bool classof(const SDNode *N) {
2796 return N->getOpcode() == ISD::MLOAD;
2797 }
2798
2799 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2800 };
2801
2802
2803 class MaskedStoreSDNode : public MaskedLoadStoreSDNode {
2804 public:
2805 friend class SelectionDAG;
2806
2807 MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2808 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
2809 EVT MemVT, MachineMemOperand *MMO)
2810 : MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, VTs, AM, MemVT, MMO) {
2811 StoreSDNodeBits.IsTruncating = isTrunc;
2812 StoreSDNodeBits.IsCompressing = isCompressing;
2813 }
2814
2815
2816
2817
2818 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2819
2820
2821
2822
2823
2824 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2825
2826 const SDValue &getValue() const { return getOperand(1); }
2827 const SDValue &getBasePtr() const { return getOperand(2); }
2828 const SDValue &getOffset() const { return getOperand(3); }
2829 const SDValue &getMask() const { return getOperand(4); }
2830
2831 static bool classof(const SDNode *N) {
2832 return N->getOpcode() == ISD::MSTORE;
2833 }
2834 };
2835
2836
2837
2838
2839 class VPGatherScatterSDNode : public MemSDNode {
2840 public:
2841 friend class SelectionDAG;
2842
2843 VPGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
2844 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2845 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
2846 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2847 LSBaseSDNodeBits.AddressingMode = IndexType;
2848 assert(getIndexType() == IndexType && "Value truncated");
2849 }
2850
2851
2852 ISD::MemIndexType getIndexType() const {
2853 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
2854 }
2855 bool isIndexScaled() const {
2856 return !cast<ConstantSDNode>(getScale())->isOne();
2857 }
2858 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
2859
2860
2861
2862
2863
2864 const SDValue &getBasePtr() const {
2865 return getOperand((getOpcode() == ISD::VP_GATHER) ? 1 : 2);
2866 }
2867 const SDValue &getIndex() const {
2868 return getOperand((getOpcode() == ISD::VP_GATHER) ? 2 : 3);
2869 }
2870 const SDValue &getScale() const {
2871 return getOperand((getOpcode() == ISD::VP_GATHER) ? 3 : 4);
2872 }
2873 const SDValue &getMask() const {
2874 return getOperand((getOpcode() == ISD::VP_GATHER) ? 4 : 5);
2875 }
2876 const SDValue &getVectorLength() const {
2877 return getOperand((getOpcode() == ISD::VP_GATHER) ? 5 : 6);
2878 }
2879
2880 static bool classof(const SDNode *N) {
2881 return N->getOpcode() == ISD::VP_GATHER ||
2882 N->getOpcode() == ISD::VP_SCATTER;
2883 }
2884 };
2885
2886
2887
2888 class VPGatherSDNode : public VPGatherScatterSDNode {
2889 public:
2890 friend class SelectionDAG;
2891
2892 VPGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2893 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
2894 : VPGatherScatterSDNode(ISD::VP_GATHER, Order, dl, VTs, MemVT, MMO,
2895 IndexType) {}
2896
2897 static bool classof(const SDNode *N) {
2898 return N->getOpcode() == ISD::VP_GATHER;
2899 }
2900 };
2901
2902
2903
2904 class VPScatterSDNode : public VPGatherScatterSDNode {
2905 public:
2906 friend class SelectionDAG;
2907
2908 VPScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2909 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
2910 : VPGatherScatterSDNode(ISD::VP_SCATTER, Order, dl, VTs, MemVT, MMO,
2911 IndexType) {}
2912
2913 const SDValue &getValue() const { return getOperand(1); }
2914
2915 static bool classof(const SDNode *N) {
2916 return N->getOpcode() == ISD::VP_SCATTER;
2917 }
2918 };
2919
2920
2921
2922
2923 class MaskedGatherScatterSDNode : public MemSDNode {
2924 public:
2925 friend class SelectionDAG;
2926
2927 MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
2928 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2929 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
2930 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2931 LSBaseSDNodeBits.AddressingMode = IndexType;
2932 assert(getIndexType() == IndexType && "Value truncated");
2933 }
2934
2935
2936 ISD::MemIndexType getIndexType() const {
2937 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
2938 }
2939 bool isIndexScaled() const {
2940 return !cast<ConstantSDNode>(getScale())->isOne();
2941 }
2942 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
2943
2944
2945
2946
2947
2948 const SDValue &getBasePtr() const { return getOperand(3); }
2949 const SDValue &getIndex() const { return getOperand(4); }
2950 const SDValue &getMask() const { return getOperand(2); }
2951 const SDValue &getScale() const { return getOperand(5); }
2952
2953 static bool classof(const SDNode *N) {
2954 return N->getOpcode() == ISD::MGATHER || N->getOpcode() == ISD::MSCATTER ||
2955 N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
2956 }
2957 };
2958
2959
2960
2961 class MaskedGatherSDNode : public MaskedGatherScatterSDNode {
2962 public:
2963 friend class SelectionDAG;
2964
2965 MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2966 EVT MemVT, MachineMemOperand *MMO,
2967 ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
2968 : MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, VTs, MemVT, MMO,
2969 IndexType) {
2970 LoadSDNodeBits.ExtTy = ETy;
2971 }
2972
2973 const SDValue &getPassThru() const { return getOperand(1); }
2974
2975 ISD::LoadExtType getExtensionType() const {
2976 return ISD::LoadExtType(LoadSDNodeBits.ExtTy);
2977 }
2978
2979 static bool classof(const SDNode *N) {
2980 return N->getOpcode() == ISD::MGATHER;
2981 }
2982 };
2983
2984
2985
2986 class MaskedScatterSDNode : public MaskedGatherScatterSDNode {
2987 public:
2988 friend class SelectionDAG;
2989
2990 MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2991 EVT MemVT, MachineMemOperand *MMO,
2992 ISD::MemIndexType IndexType, bool IsTrunc)
2993 : MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, VTs, MemVT, MMO,
2994 IndexType) {
2995 StoreSDNodeBits.IsTruncating = IsTrunc;
2996 }
2997
2998
2999
3000
3001 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
3002
3003 const SDValue &getValue() const { return getOperand(1); }
3004
3005 static bool classof(const SDNode *N) {
3006 return N->getOpcode() == ISD::MSCATTER;
3007 }
3008 };
3009
3010 class MaskedHistogramSDNode : public MaskedGatherScatterSDNode {
3011 public:
3012 friend class SelectionDAG;
3013
3014 MaskedHistogramSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
3015 EVT MemVT, MachineMemOperand *MMO,
3016 ISD::MemIndexType IndexType)
3017 : MaskedGatherScatterSDNode(ISD::EXPERIMENTAL_VECTOR_HISTOGRAM, Order, DL,
3018 VTs, MemVT, MMO, IndexType) {}
3019
3020 ISD::MemIndexType getIndexType() const {
3021 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3022 }
3023
3024 const SDValue &getBasePtr() const { return getOperand(3); }
3025 const SDValue &getIndex() const { return getOperand(4); }
3026 const SDValue &getMask() const { return getOperand(2); }
3027 const SDValue &getScale() const { return getOperand(5); }
3028 const SDValue &getInc() const { return getOperand(1); }
3029 const SDValue &getIntID() const { return getOperand(6); }
3030
3031 static bool classof(const SDNode *N) {
3032 return N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
3033 }
3034 };
3035
3036 class FPStateAccessSDNode : public MemSDNode {
3037 public:
3038 friend class SelectionDAG;
3039
3040 FPStateAccessSDNode(unsigned NodeTy, unsigned Order, const DebugLoc &dl,
3041 SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
3042 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3043 assert((NodeTy == ISD::GET_FPENV_MEM || NodeTy == ISD::SET_FPENV_MEM) &&
3044 "Expected FP state access node");
3045 }
3046
3047 static bool classof(const SDNode *N) {
3048 return N->getOpcode() == ISD::GET_FPENV_MEM ||
3049 N->getOpcode() == ISD::SET_FPENV_MEM;
3050 }
3051 };
3052
3053
3054
3055
3056
3057
3058
3059
3060 class MachineSDNode : public SDNode {
3061 private:
3062 friend class SelectionDAG;
3063
3064 MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, SDVTList VTs)
3065 : SDNode(Opc, Order, DL, VTs) {}
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081 PointerUnion<MachineMemOperand *, MachineMemOperand **> MemRefs = {};
3082
3083
3084
3085
3086
3087 int NumMemRefs = 0;
3088
3089 public:
3090 using mmo_iterator = ArrayRef<MachineMemOperand *>::const_iterator;
3091
3092 ArrayRef<MachineMemOperand *> memoperands() const {
3093
3094 if (NumMemRefs == 0)
3095 return {};
3096 if (NumMemRefs == 1)
3097 return ArrayRef(MemRefs.getAddrOfPtr1(), 1);
3098
3099
3100 return ArrayRef(cast<MachineMemOperand **>(MemRefs), NumMemRefs);
3101 }
3102 mmo_iterator memoperands_begin() const { return memoperands().begin(); }
3103 mmo_iterator memoperands_end() const { return memoperands().end(); }
3104 bool memoperands_empty() const { return memoperands().empty(); }
3105
3106
3107 void clearMemRefs() {
3108 MemRefs = nullptr;
3109 NumMemRefs = 0;
3110 }
3111
3112 static bool classof(const SDNode *N) {
3113 return N->isMachineOpcode();
3114 }
3115 };
3116
3117
3118
3119 class AssertAlignSDNode : public SDNode {
3120 Align Alignment;
3121
3122 public:
3123 AssertAlignSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, Align A)
3124 : SDNode(ISD::AssertAlign, Order, DL, VTs), Alignment(A) {}
3125
3126 Align getAlign() const { return Alignment; }
3127
3128 static bool classof(const SDNode *N) {
3129 return N->getOpcode() == ISD::AssertAlign;
3130 }
3131 };
3132
3133 class SDNodeIterator {
3134 const SDNode *Node;
3135 unsigned Operand;
3136
3137 SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
3138
3139 public:
3140 using iterator_category = std::forward_iterator_tag;
3141 using value_type = SDNode;
3142 using difference_type = std::ptrdiff_t;
3143 using pointer = value_type *;
3144 using reference = value_type &;
3145
3146 bool operator==(const SDNodeIterator& x) const {
3147 return Operand == x.Operand;
3148 }
3149 bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
3150
3151 pointer operator*() const {
3152 return Node->getOperand(Operand).getNode();
3153 }
3154 pointer operator->() const { return operator*(); }
3155
3156 SDNodeIterator& operator++() {
3157 ++Operand;
3158 return *this;
3159 }
3160 SDNodeIterator operator++(int) {
3161 SDNodeIterator tmp = *this; ++*this; return tmp;
3162 }
3163 size_t operator-(SDNodeIterator Other) const {
3164 assert(Node == Other.Node &&
3165 "Cannot compare iterators of two different nodes!");
3166 return Operand - Other.Operand;
3167 }
3168
3169 static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); }
3170 static SDNodeIterator end (const SDNode *N) {
3171 return SDNodeIterator(N, N->getNumOperands());
3172 }
3173
3174 unsigned getOperand() const { return Operand; }
3175 const SDNode *getNode() const { return Node; }
3176 };
3177
3178 template <> struct GraphTraits<SDNode*> {
3179 using NodeRef = SDNode *;
3180 using ChildIteratorType = SDNodeIterator;
3181
3182 static NodeRef getEntryNode(SDNode *N) { return N; }
3183
3184 static ChildIteratorType child_begin(NodeRef N) {
3185 return SDNodeIterator::begin(N);
3186 }
3187
3188 static ChildIteratorType child_end(NodeRef N) {
3189 return SDNodeIterator::end(N);
3190 }
3191 };
3192
3193
3194
3195
3196
3197 using LargestSDNode = AlignedCharArrayUnion<AtomicSDNode, TargetIndexSDNode,
3198 BlockAddressSDNode,
3199 GlobalAddressSDNode,
3200 PseudoProbeSDNode>;
3201
3202
3203 using MostAlignedSDNode = GlobalAddressSDNode;
3204
3205 namespace ISD {
3206
3207
3208 inline bool isNormalLoad(const SDNode *N) {
3209 auto *Ld = dyn_cast<LoadSDNode>(N);
3210 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
3211 Ld->getAddressingMode() == ISD::UNINDEXED;
3212 }
3213
3214
3215 inline bool isNON_EXTLoad(const SDNode *N) {
3216 auto *Ld = dyn_cast<LoadSDNode>(N);
3217 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD;
3218 }
3219
3220
3221 inline bool isEXTLoad(const SDNode *N) {
3222 auto *Ld = dyn_cast<LoadSDNode>(N);
3223 return Ld && Ld->getExtensionType() == ISD::EXTLOAD;
3224 }
3225
3226
3227 inline bool isSEXTLoad(const SDNode *N) {
3228 auto *Ld = dyn_cast<LoadSDNode>(N);
3229 return Ld && Ld->getExtensionType() == ISD::SEXTLOAD;
3230 }
3231
3232
3233 inline bool isZEXTLoad(const SDNode *N) {
3234 auto *Ld = dyn_cast<LoadSDNode>(N);
3235 return Ld && Ld->getExtensionType() == ISD::ZEXTLOAD;
3236 }
3237
3238
3239 inline bool isUNINDEXEDLoad(const SDNode *N) {
3240 auto *Ld = dyn_cast<LoadSDNode>(N);
3241 return Ld && Ld->getAddressingMode() == ISD::UNINDEXED;
3242 }
3243
3244
3245
3246 inline bool isNormalStore(const SDNode *N) {
3247 auto *St = dyn_cast<StoreSDNode>(N);
3248 return St && !St->isTruncatingStore() &&
3249 St->getAddressingMode() == ISD::UNINDEXED;
3250 }
3251
3252
3253 inline bool isUNINDEXEDStore(const SDNode *N) {
3254 auto *St = dyn_cast<StoreSDNode>(N);
3255 return St && St->getAddressingMode() == ISD::UNINDEXED;
3256 }
3257
3258
3259
3260
3261 template <typename ConstNodeType>
3262 bool matchUnaryPredicateImpl(SDValue Op,
3263 std::function<bool(ConstNodeType *)> Match,
3264 bool AllowUndefs = false);
3265
3266
3267 inline bool matchUnaryPredicate(SDValue Op,
3268 std::function<bool(ConstantSDNode *)> Match,
3269 bool AllowUndefs = false) {
3270 return matchUnaryPredicateImpl<ConstantSDNode>(Op, Match, AllowUndefs);
3271 }
3272
3273
3274 inline bool
3275 matchUnaryFpPredicate(SDValue Op,
3276 std::function<bool(ConstantFPSDNode *)> Match,
3277 bool AllowUndefs = false) {
3278 return matchUnaryPredicateImpl<ConstantFPSDNode>(Op, Match, AllowUndefs);
3279 }
3280
3281
3282
3283
3284
3285 bool matchBinaryPredicate(
3286 SDValue LHS, SDValue RHS,
3287 std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
3288 bool AllowUndefs = false, bool AllowTypeMismatch = false);
3289
3290
3291
3292 inline bool isOverflowIntrOpRes(SDValue Op) {
3293 unsigned Opc = Op.getOpcode();
3294 return (Op.getResNo() == 1 &&
3295 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
3296 Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO));
3297 }
3298
3299 }
3300
3301 }
3302
3303 #endif