LLVM 20.0.0git
SelectionDAGNodes.h
Go to the documentation of this file.
1//===- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the SDNode class and derived classes, which are used to
10// represent the nodes and operations present in a SelectionDAG. These nodes
11// and operations are machine code level operations, with some similarities to
12// the GCC RTL representation.
13//
14// Clients should include the SelectionDAG.h file instead of this file directly.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
19#define LLVM_CODEGEN_SELECTIONDAGNODES_H
20
21#include "llvm/ADT/APFloat.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/BitVector.h"
24#include "llvm/ADT/FoldingSet.h"
28#include "llvm/ADT/ilist_node.h"
29#include "llvm/ADT/iterator.h"
36#include "llvm/IR/Constants.h"
37#include "llvm/IR/DebugLoc.h"
38#include "llvm/IR/Instruction.h"
40#include "llvm/IR/Metadata.h"
41#include "llvm/IR/Operator.h"
47#include <algorithm>
48#include <cassert>
49#include <climits>
50#include <cstddef>
51#include <cstdint>
52#include <cstring>
53#include <iterator>
54#include <string>
55#include <tuple>
56#include <utility>
57
58namespace llvm {
59
60class APInt;
61class Constant;
62class GlobalValue;
63class MachineBasicBlock;
64class MachineConstantPoolValue;
65class MCSymbol;
66class raw_ostream;
67class SDNode;
68class SelectionDAG;
69class Type;
70class Value;
71
72void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
73 bool force = false);
74
75/// This represents a list of ValueType's that has been intern'd by
76/// a SelectionDAG. Instances of this simple value class are returned by
77/// SelectionDAG::getVTList(...).
78///
79struct SDVTList {
80 const EVT *VTs;
81 unsigned int NumVTs;
82};
83
84namespace ISD {
85
86 /// Node predicates
87
88/// If N is a BUILD_VECTOR or SPLAT_VECTOR node whose elements are all the
89/// same constant or undefined, return true and return the constant value in
90/// \p SplatValue.
91bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
92
93/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
94/// all of the elements are ~0 or undef. If \p BuildVectorOnly is set to
95/// true, it only checks BUILD_VECTOR.
97 bool BuildVectorOnly = false);
98
99/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
100/// all of the elements are 0 or undef. If \p BuildVectorOnly is set to true, it
101/// only checks BUILD_VECTOR.
103 bool BuildVectorOnly = false);
104
105/// Return true if the specified node is a BUILD_VECTOR where all of the
106/// elements are ~0 or undef.
107bool isBuildVectorAllOnes(const SDNode *N);
108
109/// Return true if the specified node is a BUILD_VECTOR where all of the
110/// elements are 0 or undef.
111bool isBuildVectorAllZeros(const SDNode *N);
112
113/// Return true if the specified node is a BUILD_VECTOR node of all
114/// ConstantSDNode or undef.
116
117/// Return true if the specified node is a BUILD_VECTOR node of all
118/// ConstantFPSDNode or undef.
120
121/// Returns true if the specified node is a vector where all elements can
122/// be truncated to the specified element size without a loss in meaning.
123bool isVectorShrinkable(const SDNode *N, unsigned NewEltSize, bool Signed);
124
125/// Return true if the node has at least one operand and all operands of the
126/// specified node are ISD::UNDEF.
127bool allOperandsUndef(const SDNode *N);
128
129/// Return true if the specified node is FREEZE(UNDEF).
130bool isFreezeUndef(const SDNode *N);
131
132} // end namespace ISD
133
134//===----------------------------------------------------------------------===//
135/// Unlike LLVM values, Selection DAG nodes may return multiple
136/// values as the result of a computation. Many nodes return multiple values,
137/// from loads (which define a token and a return value) to ADDC (which returns
138/// a result and a carry value), to calls (which may return an arbitrary number
139/// of values).
140///
141/// As such, each use of a SelectionDAG computation must indicate the node that
142/// computes it as well as which return value to use from that node. This pair
143/// of information is represented with the SDValue value type.
144///
145class SDValue {
146 friend struct DenseMapInfo<SDValue>;
147
148 SDNode *Node = nullptr; // The node defining the value we are using.
149 unsigned ResNo = 0; // Which return value of the node we are using.
150
151public:
152 SDValue() = default;
153 SDValue(SDNode *node, unsigned resno);
154
155 /// get the index which selects a specific result in the SDNode
156 unsigned getResNo() const { return ResNo; }
157
158 /// get the SDNode which holds the desired result
159 SDNode *getNode() const { return Node; }
160
161 /// set the SDNode
162 void setNode(SDNode *N) { Node = N; }
163
164 inline SDNode *operator->() const { return Node; }
165
166 bool operator==(const SDValue &O) const {
167 return Node == O.Node && ResNo == O.ResNo;
168 }
169 bool operator!=(const SDValue &O) const {
170 return !operator==(O);
171 }
172 bool operator<(const SDValue &O) const {
173 return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo);
174 }
175 explicit operator bool() const {
176 return Node != nullptr;
177 }
178
179 SDValue getValue(unsigned R) const {
180 return SDValue(Node, R);
181 }
182
183 /// Return true if this node is an operand of N.
184 bool isOperandOf(const SDNode *N) const;
185
186 /// Return the ValueType of the referenced return value.
187 inline EVT getValueType() const;
188
189 /// Return the simple ValueType of the referenced return value.
191 return getValueType().getSimpleVT();
192 }
193
194 /// Returns the size of the value in bits.
195 ///
196 /// If the value type is a scalable vector type, the scalable property will
197 /// be set and the runtime size will be a positive integer multiple of the
198 /// base size.
200 return getValueType().getSizeInBits();
201 }
202
205 }
206
207 // Forwarding methods - These forward to the corresponding methods in SDNode.
208 inline unsigned getOpcode() const;
209 inline unsigned getNumOperands() const;
210 inline const SDValue &getOperand(unsigned i) const;
211 inline uint64_t getConstantOperandVal(unsigned i) const;
212 inline const APInt &getConstantOperandAPInt(unsigned i) const;
213 inline bool isTargetMemoryOpcode() const;
214 inline bool isTargetOpcode() const;
215 inline bool isMachineOpcode() const;
216 inline bool isUndef() const;
217 inline unsigned getMachineOpcode() const;
218 inline const DebugLoc &getDebugLoc() const;
219 inline void dump() const;
220 inline void dump(const SelectionDAG *G) const;
221 inline void dumpr() const;
222 inline void dumpr(const SelectionDAG *G) const;
223
224 /// Return true if this operand (which must be a chain) reaches the
225 /// specified operand without crossing any side-effecting instructions.
226 /// In practice, this looks through token factors and non-volatile loads.
227 /// In order to remain efficient, this only
228 /// looks a couple of nodes in, it does not do an exhaustive search.
230 unsigned Depth = 2) const;
231
232 /// Return true if there are no nodes using value ResNo of Node.
233 inline bool use_empty() const;
234
235 /// Return true if there is exactly one node using value ResNo of Node.
236 inline bool hasOneUse() const;
237};
238
239template<> struct DenseMapInfo<SDValue> {
240 static inline SDValue getEmptyKey() {
241 SDValue V;
242 V.ResNo = -1U;
243 return V;
244 }
245
246 static inline SDValue getTombstoneKey() {
247 SDValue V;
248 V.ResNo = -2U;
249 return V;
250 }
251
252 static unsigned getHashValue(const SDValue &Val) {
253 return ((unsigned)((uintptr_t)Val.getNode() >> 4) ^
254 (unsigned)((uintptr_t)Val.getNode() >> 9)) + Val.getResNo();
255 }
256
257 static bool isEqual(const SDValue &LHS, const SDValue &RHS) {
258 return LHS == RHS;
259 }
260};
261
262/// Allow casting operators to work directly on
263/// SDValues as if they were SDNode*'s.
264template<> struct simplify_type<SDValue> {
266
268 return Val.getNode();
269 }
270};
271template<> struct simplify_type<const SDValue> {
272 using SimpleType = /*const*/ SDNode *;
273
275 return Val.getNode();
276 }
277};
278
279/// Represents a use of a SDNode. This class holds an SDValue,
280/// which records the SDNode being used and the result number, a
281/// pointer to the SDNode using the value, and Next and Prev pointers,
282/// which link together all the uses of an SDNode.
283///
284class SDUse {
285 /// Val - The value being used.
286 SDValue Val;
287 /// User - The user of this value.
288 SDNode *User = nullptr;
289 /// Prev, Next - Pointers to the uses list of the SDNode referred by
290 /// this operand.
291 SDUse **Prev = nullptr;
292 SDUse *Next = nullptr;
293
294public:
295 SDUse() = default;
296 SDUse(const SDUse &U) = delete;
297 SDUse &operator=(const SDUse &) = delete;
298
299 /// Normally SDUse will just implicitly convert to an SDValue that it holds.
300 operator const SDValue&() const { return Val; }
301
302 /// If implicit conversion to SDValue doesn't work, the get() method returns
303 /// the SDValue.
304 const SDValue &get() const { return Val; }
305
306 /// This returns the SDNode that contains this Use.
307 SDNode *getUser() { return User; }
308 const SDNode *getUser() const { return User; }
309
310 /// Get the next SDUse in the use list.
311 SDUse *getNext() const { return Next; }
312
313 /// Return the operand # of this use in its user.
314 inline unsigned getOperandNo() const;
315
316 /// Convenience function for get().getNode().
317 SDNode *getNode() const { return Val.getNode(); }
318 /// Convenience function for get().getResNo().
319 unsigned getResNo() const { return Val.getResNo(); }
320 /// Convenience function for get().getValueType().
321 EVT getValueType() const { return Val.getValueType(); }
322
323 /// Convenience function for get().operator==
324 bool operator==(const SDValue &V) const {
325 return Val == V;
326 }
327
328 /// Convenience function for get().operator!=
329 bool operator!=(const SDValue &V) const {
330 return Val != V;
331 }
332
333 /// Convenience function for get().operator<
334 bool operator<(const SDValue &V) const {
335 return Val < V;
336 }
337
338private:
339 friend class SelectionDAG;
340 friend class SDNode;
341 // TODO: unfriend HandleSDNode once we fix its operand handling.
342 friend class HandleSDNode;
343
344 void setUser(SDNode *p) { User = p; }
345
346 /// Remove this use from its existing use list, assign it the
347 /// given value, and add it to the new value's node's use list.
348 inline void set(const SDValue &V);
349 /// Like set, but only supports initializing a newly-allocated
350 /// SDUse with a non-null value.
351 inline void setInitial(const SDValue &V);
352 /// Like set, but only sets the Node portion of the value,
353 /// leaving the ResNo portion unmodified.
354 inline void setNode(SDNode *N);
355
356 void addToList(SDUse **List) {
357 Next = *List;
358 if (Next) Next->Prev = &Next;
359 Prev = List;
360 *List = this;
361 }
362
363 void removeFromList() {
364 *Prev = Next;
365 if (Next) Next->Prev = Prev;
366 }
367};
368
369/// simplify_type specializations - Allow casting operators to work directly on
370/// SDValues as if they were SDNode*'s.
371template<> struct simplify_type<SDUse> {
373
375 return Val.getNode();
376 }
377};
378
379/// These are IR-level optimization flags that may be propagated to SDNodes.
380/// TODO: This data structure should be shared by the IR optimizer and the
381/// the backend.
383private:
384 friend class SDNode;
385
386 unsigned Flags = 0;
387
388 template <unsigned Flag> void setFlag(bool B) {
389 Flags = (Flags & ~Flag) | (B ? Flag : 0);
390 }
391
392public:
393 enum : unsigned {
394 None = 0,
396 NoSignedWrap = 1 << 1,
398 Exact = 1 << 2,
399 Disjoint = 1 << 3,
400 NonNeg = 1 << 4,
401 NoNaNs = 1 << 5,
402 NoInfs = 1 << 6,
408
409 // We assume instructions do not raise floating-point exceptions by default,
410 // and only those marked explicitly may do so. We could choose to represent
411 // this via a positive "FPExcept" flags like on the MI level, but having a
412 // negative "NoFPExcept" flag here makes the flag intersection logic more
413 // straightforward.
414 NoFPExcept = 1 << 12,
415 // Instructions with attached 'unpredictable' metadata on IR level.
416 Unpredictable = 1 << 13,
417 // Compare instructions which may carry the samesign flag.
418 SameSign = 1 << 14,
419
420 // NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
421 // the class definition when adding new flags.
422
425 };
426
427 /// Default constructor turns off all optimization flags.
428 SDNodeFlags(unsigned Flags = SDNodeFlags::None) : Flags(Flags) {}
429
430 /// Propagate the fast-math-flags from an IR FPMathOperator.
431 void copyFMF(const FPMathOperator &FPMO) {
432 setNoNaNs(FPMO.hasNoNaNs());
433 setNoInfs(FPMO.hasNoInfs());
439 }
440
441 // These are mutators for each flag.
442 void setNoUnsignedWrap(bool b) { setFlag<NoUnsignedWrap>(b); }
443 void setNoSignedWrap(bool b) { setFlag<NoSignedWrap>(b); }
444 void setExact(bool b) { setFlag<Exact>(b); }
445 void setDisjoint(bool b) { setFlag<Disjoint>(b); }
446 void setSameSign(bool b) { setFlag<SameSign>(b); }
447 void setNonNeg(bool b) { setFlag<NonNeg>(b); }
448 void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
449 void setNoInfs(bool b) { setFlag<NoInfs>(b); }
450 void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
451 void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
452 void setAllowContract(bool b) { setFlag<AllowContract>(b); }
453 void setApproximateFuncs(bool b) { setFlag<ApproximateFuncs>(b); }
454 void setAllowReassociation(bool b) { setFlag<AllowReassociation>(b); }
455 void setNoFPExcept(bool b) { setFlag<NoFPExcept>(b); }
456 void setUnpredictable(bool b) { setFlag<Unpredictable>(b); }
457
458 // These are accessors for each flag.
459 bool hasNoUnsignedWrap() const { return Flags & NoUnsignedWrap; }
460 bool hasNoSignedWrap() const { return Flags & NoSignedWrap; }
461 bool hasExact() const { return Flags & Exact; }
462 bool hasDisjoint() const { return Flags & Disjoint; }
463 bool hasSameSign() const { return Flags & SameSign; }
464 bool hasNonNeg() const { return Flags & NonNeg; }
465 bool hasNoNaNs() const { return Flags & NoNaNs; }
466 bool hasNoInfs() const { return Flags & NoInfs; }
467 bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
468 bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }
469 bool hasAllowContract() const { return Flags & AllowContract; }
470 bool hasApproximateFuncs() const { return Flags & ApproximateFuncs; }
471 bool hasAllowReassociation() const { return Flags & AllowReassociation; }
472 bool hasNoFPExcept() const { return Flags & NoFPExcept; }
473 bool hasUnpredictable() const { return Flags & Unpredictable; }
474
475 bool operator==(const SDNodeFlags &Other) const {
476 return Flags == Other.Flags;
477 }
478 void operator&=(const SDNodeFlags &OtherFlags) { Flags &= OtherFlags.Flags; }
479 void operator|=(const SDNodeFlags &OtherFlags) { Flags |= OtherFlags.Flags; }
480};
481
484
486 LHS |= RHS;
487 return LHS;
488}
489
491 LHS &= RHS;
492 return LHS;
493}
494
495/// Represents one node in the SelectionDAG.
496///
497class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
498private:
499 /// The operation that this node performs.
500 int32_t NodeType;
501
502 SDNodeFlags Flags;
503
504protected:
505 // We define a set of mini-helper classes to help us interpret the bits in our
506 // SubclassData. These are designed to fit within a uint16_t so they pack
507 // with SDNodeFlags.
508
509#if defined(_AIX) && (!defined(__GNUC__) || defined(__clang__))
510// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words
511// and give the `pack` pragma push semantics.
512#define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")
513#define END_TWO_BYTE_PACK() _Pragma("pack(pop)")
514#else
515#define BEGIN_TWO_BYTE_PACK()
516#define END_TWO_BYTE_PACK()
517#endif
518
521 friend class SDNode;
522 friend class MemIntrinsicSDNode;
523 friend class MemSDNode;
524 friend class SelectionDAG;
525
526 uint16_t HasDebugValue : 1;
527 uint16_t IsMemIntrinsic : 1;
528 uint16_t IsDivergent : 1;
529 };
530 enum { NumSDNodeBits = 3 };
531
533 friend class ConstantSDNode;
534
536
537 uint16_t IsOpaque : 1;
538 };
539
541 friend class MemSDNode;
542 friend class MemIntrinsicSDNode;
543 friend class AtomicSDNode;
544
546
547 uint16_t IsVolatile : 1;
548 uint16_t IsNonTemporal : 1;
549 uint16_t IsDereferenceable : 1;
550 uint16_t IsInvariant : 1;
551 };
553
555 friend class LSBaseSDNode;
561
563
564 // This storage is shared between disparate class hierarchies to hold an
565 // enumeration specific to the class hierarchy in use.
566 // LSBaseSDNode => enum ISD::MemIndexedMode
567 // VPLoadStoreBaseSDNode => enum ISD::MemIndexedMode
568 // MaskedLoadStoreBaseSDNode => enum ISD::MemIndexedMode
569 // VPGatherScatterSDNode => enum ISD::MemIndexType
570 // MaskedGatherScatterSDNode => enum ISD::MemIndexType
571 // MaskedHistogramSDNode => enum ISD::MemIndexType
573 };
575
577 friend class LoadSDNode;
578 friend class AtomicSDNode;
579 friend class VPLoadSDNode;
581 friend class MaskedLoadSDNode;
582 friend class MaskedGatherSDNode;
583 friend class VPGatherSDNode;
585
587
588 uint16_t ExtTy : 2; // enum ISD::LoadExtType
589 uint16_t IsExpanding : 1;
590 };
591
593 friend class StoreSDNode;
594 friend class VPStoreSDNode;
596 friend class MaskedStoreSDNode;
598 friend class VPScatterSDNode;
599
601
602 uint16_t IsTruncating : 1;
603 uint16_t IsCompressing : 1;
604 };
605
606 union {
607 char RawSDNodeBits[sizeof(uint16_t)];
614 };
616#undef BEGIN_TWO_BYTE_PACK
617#undef END_TWO_BYTE_PACK
618
619 // RawSDNodeBits must cover the entirety of the union. This means that all of
620 // the union's members must have size <= RawSDNodeBits. We write the RHS as
621 // "2" instead of sizeof(RawSDNodeBits) because MSVC can't handle the latter.
622 static_assert(sizeof(SDNodeBitfields) <= 2, "field too wide");
623 static_assert(sizeof(ConstantSDNodeBitfields) <= 2, "field too wide");
624 static_assert(sizeof(MemSDNodeBitfields) <= 2, "field too wide");
625 static_assert(sizeof(LSBaseSDNodeBitfields) <= 2, "field too wide");
626 static_assert(sizeof(LoadSDNodeBitfields) <= 2, "field too wide");
627 static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide");
628
629public:
630 /// Unique and persistent id per SDNode in the DAG. Used for debug printing.
631 /// We do not place that under `#if LLVM_ENABLE_ABI_BREAKING_CHECKS`
632 /// intentionally because it adds unneeded complexity without noticeable
633 /// benefits (see discussion with @thakis in D120714). Currently, there are
634 /// two padding bytes after this field.
636
637private:
638 friend class SelectionDAG;
639 // TODO: unfriend HandleSDNode once we fix its operand handling.
640 friend class HandleSDNode;
641
642 /// Unique id per SDNode in the DAG.
643 int NodeId = -1;
644
645 /// The values that are used by this operation.
646 SDUse *OperandList = nullptr;
647
648 /// The types of the values this node defines. SDNode's may
649 /// define multiple values simultaneously.
650 const EVT *ValueList;
651
652 /// List of uses for this SDNode.
653 SDUse *UseList = nullptr;
654
655 /// The number of entries in the Operand/Value list.
656 unsigned short NumOperands = 0;
657 unsigned short NumValues;
658
659 // The ordering of the SDNodes. It roughly corresponds to the ordering of the
660 // original LLVM instructions.
661 // This is used for turning off scheduling, because we'll forgo
662 // the normal scheduling algorithms and output the instructions according to
663 // this ordering.
664 unsigned IROrder;
665
666 /// Source line information.
667 DebugLoc debugLoc;
668
669 /// Return a pointer to the specified value type.
670 static const EVT *getValueTypeList(MVT VT);
671
672 /// Index in worklist of DAGCombiner, or negative if the node is not in the
673 /// worklist. -1 = not in worklist; -2 = not in worklist, but has already been
674 /// combined at least once.
675 int CombinerWorklistIndex = -1;
676
677 uint32_t CFIType = 0;
678
679public:
680 //===--------------------------------------------------------------------===//
681 // Accessors
682 //
683
684 /// Return the SelectionDAG opcode value for this node. For
685 /// pre-isel nodes (those for which isMachineOpcode returns false), these
686 /// are the opcode values in the ISD and <target>ISD namespaces. For
687 /// post-isel opcodes, see getMachineOpcode.
688 unsigned getOpcode() const { return (unsigned)NodeType; }
689
690 /// Test if this node has a target-specific opcode (in the
691 /// <target>ISD namespace).
692 bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
693
694 /// Test if this node has a target-specific opcode that may raise
695 /// FP exceptions (in the <target>ISD namespace and greater than
696 /// FIRST_TARGET_STRICTFP_OPCODE). Note that all target memory
697 /// opcode are currently automatically considered to possibly raise
698 /// FP exceptions as well.
700 return NodeType >= ISD::FIRST_TARGET_STRICTFP_OPCODE;
701 }
702
703 /// Test if this node has a target-specific
704 /// memory-referencing opcode (in the <target>ISD namespace and
705 /// greater than FIRST_TARGET_MEMORY_OPCODE).
706 bool isTargetMemoryOpcode() const {
707 return NodeType >= ISD::FIRST_TARGET_MEMORY_OPCODE;
708 }
709
710 /// Return true if the type of the node type undefined.
711 bool isUndef() const { return NodeType == ISD::UNDEF; }
712
713 /// Test if this node is a memory intrinsic (with valid pointer information).
714 bool isMemIntrinsic() const { return SDNodeBits.IsMemIntrinsic; }
715
716 /// Test if this node is a strict floating point pseudo-op.
718 switch (NodeType) {
719 default:
720 return false;
725#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
726 case ISD::STRICT_##DAGN:
727#include "llvm/IR/ConstrainedOps.def"
728 return true;
729 }
730 }
731
732 /// Test if this node is a vector predication operation.
733 bool isVPOpcode() const { return ISD::isVPOpcode(getOpcode()); }
734
735 /// Test if this node has a post-isel opcode, directly
736 /// corresponding to a MachineInstr opcode.
737 bool isMachineOpcode() const { return NodeType < 0; }
738
739 /// This may only be called if isMachineOpcode returns
740 /// true. It returns the MachineInstr opcode value that the node's opcode
741 /// corresponds to.
742 unsigned getMachineOpcode() const {
743 assert(isMachineOpcode() && "Not a MachineInstr opcode!");
744 return ~NodeType;
745 }
746
747 bool getHasDebugValue() const { return SDNodeBits.HasDebugValue; }
748 void setHasDebugValue(bool b) { SDNodeBits.HasDebugValue = b; }
749
750 bool isDivergent() const { return SDNodeBits.IsDivergent; }
751
752 /// Return true if there are no uses of this node.
753 bool use_empty() const { return UseList == nullptr; }
754
755 /// Return true if there is exactly one use of this node.
756 bool hasOneUse() const { return hasSingleElement(uses()); }
757
758 /// Return the number of uses of this node. This method takes
759 /// time proportional to the number of uses.
760 size_t use_size() const { return std::distance(use_begin(), use_end()); }
761
762 /// Return the unique node id.
763 int getNodeId() const { return NodeId; }
764
765 /// Set unique node id.
766 void setNodeId(int Id) { NodeId = Id; }
767
768 /// Get worklist index for DAGCombiner
769 int getCombinerWorklistIndex() const { return CombinerWorklistIndex; }
770
771 /// Set worklist index for DAGCombiner
772 void setCombinerWorklistIndex(int Index) { CombinerWorklistIndex = Index; }
773
774 /// Return the node ordering.
775 unsigned getIROrder() const { return IROrder; }
776
777 /// Set the node ordering.
778 void setIROrder(unsigned Order) { IROrder = Order; }
779
780 /// Return the source location info.
781 const DebugLoc &getDebugLoc() const { return debugLoc; }
782
783 /// Set source location info. Try to avoid this, putting
784 /// it in the constructor is preferable.
785 void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); }
786
787 /// This class provides iterator support for SDUse
788 /// operands that use a specific SDNode.
790 friend class SDNode;
791
792 SDUse *Op = nullptr;
793
794 explicit use_iterator(SDUse *op) : Op(op) {}
795
796 public:
797 using iterator_category = std::forward_iterator_tag;
799 using difference_type = std::ptrdiff_t;
802
803 use_iterator() = default;
804 use_iterator(const use_iterator &I) = default;
806
807 bool operator==(const use_iterator &x) const { return Op == x.Op; }
808 bool operator!=(const use_iterator &x) const {
809 return !operator==(x);
810 }
811
812 // Iterator traversal: forward iteration only.
813 use_iterator &operator++() { // Preincrement
814 assert(Op && "Cannot increment end iterator!");
815 Op = Op->getNext();
816 return *this;
817 }
818
819 use_iterator operator++(int) { // Postincrement
820 use_iterator tmp = *this; ++*this; return tmp;
821 }
822
823 /// Retrieve a pointer to the current user node.
824 SDUse &operator*() const {
825 assert(Op && "Cannot dereference end iterator!");
826 return *Op;
827 }
828
829 SDUse *operator->() const { return &operator*(); }
830 };
831
833 friend class SDNode;
834 use_iterator UI;
835
836 explicit user_iterator(SDUse *op) : UI(op) {};
837
838 public:
839 using iterator_category = std::forward_iterator_tag;
841 using difference_type = std::ptrdiff_t;
844
845 user_iterator() = default;
846
847 bool operator==(const user_iterator &x) const { return UI == x.UI; }
848 bool operator!=(const user_iterator &x) const { return !operator==(x); }
849
850 user_iterator &operator++() { // Preincrement
851 ++UI;
852 return *this;
853 }
854
855 user_iterator operator++(int) { // Postincrement
856 auto tmp = *this;
857 ++*this;
858 return tmp;
859 }
860
861 // Retrieve a pointer to the current User.
862 SDNode *operator*() const { return UI->getUser(); }
863
864 SDNode *operator->() const { return operator*(); }
865
866 SDUse &getUse() const { return *UI; }
867 };
868
869 /// Provide iteration support to walk over all uses of an SDNode.
871 return use_iterator(UseList);
872 }
873
874 static use_iterator use_end() { return use_iterator(nullptr); }
875
877 return make_range(use_begin(), use_end());
878 }
880 return make_range(use_begin(), use_end());
881 }
882
883 /// Provide iteration support to walk over all users of an SDNode.
884 user_iterator user_begin() const { return user_iterator(UseList); }
885
886 static user_iterator user_end() { return user_iterator(nullptr); }
887
889 return make_range(user_begin(), user_end());
890 }
892 return make_range(user_begin(), user_end());
893 }
894
895 /// Return true if there are exactly NUSES uses of the indicated value.
896 /// This method ignores uses of other values defined by this operation.
897 bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
898
899 /// Return true if there are any use of the indicated value.
900 /// This method ignores uses of other values defined by this operation.
901 bool hasAnyUseOfValue(unsigned Value) const;
902
903 /// Return true if this node is the only use of N.
904 bool isOnlyUserOf(const SDNode *N) const;
905
906 /// Return true if this node is an operand of N.
907 bool isOperandOf(const SDNode *N) const;
908
909 /// Return true if this node is a predecessor of N.
910 /// NOTE: Implemented on top of hasPredecessor and every bit as
911 /// expensive. Use carefully.
912 bool isPredecessorOf(const SDNode *N) const {
913 return N->hasPredecessor(this);
914 }
915
916 /// Return true if N is a predecessor of this node.
917 /// N is either an operand of this node, or can be reached by recursively
918 /// traversing up the operands.
919 /// NOTE: This is an expensive method. Use it carefully.
920 bool hasPredecessor(const SDNode *N) const;
921
922 /// Returns true if N is a predecessor of any node in Worklist. This
923 /// helper keeps Visited and Worklist sets externally to allow unions
924 /// searches to be performed in parallel, caching of results across
925 /// queries and incremental addition to Worklist. Stops early if N is
926 /// found but will resume. Remember to clear Visited and Worklists
927 /// if DAG changes. MaxSteps gives a maximum number of nodes to visit before
928 /// giving up. The TopologicalPrune flag signals that positive NodeIds are
929 /// topologically ordered (Operands have strictly smaller node id) and search
930 /// can be pruned leveraging this.
931 static bool hasPredecessorHelper(const SDNode *N,
934 unsigned int MaxSteps = 0,
935 bool TopologicalPrune = false) {
936 SmallVector<const SDNode *, 8> DeferredNodes;
937 if (Visited.count(N))
938 return true;
939
940 // Node Id's are assigned in three places: As a topological
941 // ordering (> 0), during legalization (results in values set to
942 // 0), new nodes (set to -1). If N has a topolgical id then we
943 // know that all nodes with ids smaller than it cannot be
944 // successors and we need not check them. Filter out all node
945 // that can't be matches. We add them to the worklist before exit
946 // in case of multiple calls. Note that during selection the topological id
947 // may be violated if a node's predecessor is selected before it. We mark
948 // this at selection negating the id of unselected successors and
949 // restricting topological pruning to positive ids.
950
951 int NId = N->getNodeId();
952 // If we Invalidated the Id, reconstruct original NId.
953 if (NId < -1)
954 NId = -(NId + 1);
955
956 bool Found = false;
957 while (!Worklist.empty()) {
958 const SDNode *M = Worklist.pop_back_val();
959 int MId = M->getNodeId();
960 if (TopologicalPrune && M->getOpcode() != ISD::TokenFactor && (NId > 0) &&
961 (MId > 0) && (MId < NId)) {
962 DeferredNodes.push_back(M);
963 continue;
964 }
965 for (const SDValue &OpV : M->op_values()) {
966 SDNode *Op = OpV.getNode();
967 if (Visited.insert(Op).second)
968 Worklist.push_back(Op);
969 if (Op == N)
970 Found = true;
971 }
972 if (Found)
973 break;
974 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
975 break;
976 }
977 // Push deferred nodes back on worklist.
978 Worklist.append(DeferredNodes.begin(), DeferredNodes.end());
979 // If we bailed early, conservatively return found.
980 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
981 return true;
982 return Found;
983 }
984
985 /// Return true if all the users of N are contained in Nodes.
986 /// NOTE: Requires at least one match, but doesn't require them all.
987 static bool areOnlyUsersOf(ArrayRef<const SDNode *> Nodes, const SDNode *N);
988
989 /// Return the number of values used by this operation.
990 unsigned getNumOperands() const { return NumOperands; }
991
992 /// Return the maximum number of operands that a SDNode can hold.
993 static constexpr size_t getMaxNumOperands() {
994 return std::numeric_limits<decltype(SDNode::NumOperands)>::max();
995 }
996
997 /// Helper method returns the integer value of a ConstantSDNode operand.
998 inline uint64_t getConstantOperandVal(unsigned Num) const;
999
1000 /// Helper method returns the zero-extended integer value of a ConstantSDNode.
1001 inline uint64_t getAsZExtVal() const;
1002
1003 /// Helper method returns the APInt of a ConstantSDNode operand.
1004 inline const APInt &getConstantOperandAPInt(unsigned Num) const;
1005
1006 /// Helper method returns the APInt value of a ConstantSDNode.
1007 inline const APInt &getAsAPIntVal() const;
1008
1009 const SDValue &getOperand(unsigned Num) const {
1010 assert(Num < NumOperands && "Invalid child # of SDNode!");
1011 return OperandList[Num];
1012 }
1013
1015
1016 op_iterator op_begin() const { return OperandList; }
1017 op_iterator op_end() const { return OperandList+NumOperands; }
1018 ArrayRef<SDUse> ops() const { return ArrayRef(op_begin(), op_end()); }
1019
1020 /// Iterator for directly iterating over the operand SDValue's.
1022 : iterator_adaptor_base<value_op_iterator, op_iterator,
1023 std::random_access_iterator_tag, SDValue,
1024 ptrdiff_t, value_op_iterator *,
1025 value_op_iterator *> {
1026 explicit value_op_iterator(SDUse *U = nullptr)
1027 : iterator_adaptor_base(U) {}
1028
1029 const SDValue &operator*() const { return I->get(); }
1030 };
1031
1035 }
1036
1038 SDVTList X = { ValueList, NumValues };
1039 return X;
1040 }
1041
1042 /// If this node has a glue operand, return the node
1043 /// to which the glue operand points. Otherwise return NULL.
1045 if (getNumOperands() != 0 &&
1046 getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
1047 return getOperand(getNumOperands()-1).getNode();
1048 return nullptr;
1049 }
1050
1051 /// If this node has a glue value with a user, return
1052 /// the user (there is at most one). Otherwise return NULL.
1054 for (SDUse &U : uses())
1055 if (U.getValueType() == MVT::Glue)
1056 return U.getUser();
1057 return nullptr;
1058 }
1059
1060 SDNodeFlags getFlags() const { return Flags; }
1061 void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
1062 void dropFlags(unsigned Mask) { Flags &= ~Mask; }
1063
1064 /// Clear any flags in this node that aren't also set in Flags.
1065 /// If Flags is not in a defined state then this has no effect.
1066 void intersectFlagsWith(const SDNodeFlags Flags);
1067
1069 return Flags.Flags & SDNodeFlags::PoisonGeneratingFlags;
1070 }
1071
1072 void setCFIType(uint32_t Type) { CFIType = Type; }
1073 uint32_t getCFIType() const { return CFIType; }
1074
1075 /// Return the number of values defined/returned by this operator.
1076 unsigned getNumValues() const { return NumValues; }
1077
1078 /// Return the type of a specified result.
1079 EVT getValueType(unsigned ResNo) const {
1080 assert(ResNo < NumValues && "Illegal result number!");
1081 return ValueList[ResNo];
1082 }
1083
1084 /// Return the type of a specified result as a simple type.
1085 MVT getSimpleValueType(unsigned ResNo) const {
1086 return getValueType(ResNo).getSimpleVT();
1087 }
1088
1089 /// Returns MVT::getSizeInBits(getValueType(ResNo)).
1090 ///
1091 /// If the value type is a scalable vector type, the scalable property will
1092 /// be set and the runtime size will be a positive integer multiple of the
1093 /// base size.
1094 TypeSize getValueSizeInBits(unsigned ResNo) const {
1095 return getValueType(ResNo).getSizeInBits();
1096 }
1097
1098 using value_iterator = const EVT *;
1099
1100 value_iterator value_begin() const { return ValueList; }
1101 value_iterator value_end() const { return ValueList+NumValues; }
1104 }
1105
1106 /// Return the opcode of this operation for printing.
1107 std::string getOperationName(const SelectionDAG *G = nullptr) const;
1108 static const char* getIndexedModeName(ISD::MemIndexedMode AM);
1109 void print_types(raw_ostream &OS, const SelectionDAG *G) const;
1110 void print_details(raw_ostream &OS, const SelectionDAG *G) const;
1111 void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1112 void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1113
1114 /// Print a SelectionDAG node and all children down to
1115 /// the leaves. The given SelectionDAG allows target-specific nodes
1116 /// to be printed in human-readable form. Unlike printr, this will
1117 /// print the whole DAG, including children that appear multiple
1118 /// times.
1119 ///
1120 void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const;
1121
1122 /// Print a SelectionDAG node and children up to
1123 /// depth "depth." The given SelectionDAG allows target-specific
1124 /// nodes to be printed in human-readable form. Unlike printr, this
1125 /// will print children that appear multiple times wherever they are
1126 /// used.
1127 ///
1128 void printrWithDepth(raw_ostream &O, const SelectionDAG *G = nullptr,
1129 unsigned depth = 100) const;
1130
1131 /// Dump this node, for debugging.
1132 void dump() const;
1133
1134 /// Dump (recursively) this node and its use-def subgraph.
1135 void dumpr() const;
1136
1137 /// Dump this node, for debugging.
1138 /// The given SelectionDAG allows target-specific nodes to be printed
1139 /// in human-readable form.
1140 void dump(const SelectionDAG *G) const;
1141
1142 /// Dump (recursively) this node and its use-def subgraph.
1143 /// The given SelectionDAG allows target-specific nodes to be printed
1144 /// in human-readable form.
1145 void dumpr(const SelectionDAG *G) const;
1146
1147 /// printrFull to dbgs(). The given SelectionDAG allows
1148 /// target-specific nodes to be printed in human-readable form.
1149 /// Unlike dumpr, this will print the whole DAG, including children
1150 /// that appear multiple times.
1151 void dumprFull(const SelectionDAG *G = nullptr) const;
1152
1153 /// printrWithDepth to dbgs(). The given
1154 /// SelectionDAG allows target-specific nodes to be printed in
1155 /// human-readable form. Unlike dumpr, this will print children
1156 /// that appear multiple times wherever they are used.
1157 ///
1158 void dumprWithDepth(const SelectionDAG *G = nullptr,
1159 unsigned depth = 100) const;
1160
1161 /// Gather unique data for the node.
1162 void Profile(FoldingSetNodeID &ID) const;
1163
1164 /// This method should only be used by the SDUse class.
1165 void addUse(SDUse &U) { U.addToList(&UseList); }
1166
1167protected:
1169 SDVTList Ret = { getValueTypeList(VT), 1 };
1170 return Ret;
1171 }
1172
1173 /// Create an SDNode.
1174 ///
1175 /// SDNodes are created without any operands, and never own the operand
1176 /// storage. To add operands, see SelectionDAG::createOperands.
1177 SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs)
1178 : NodeType(Opc), ValueList(VTs.VTs), NumValues(VTs.NumVTs),
1179 IROrder(Order), debugLoc(std::move(dl)) {
1180 memset(&RawSDNodeBits, 0, sizeof(RawSDNodeBits));
1181 assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
1182 assert(NumValues == VTs.NumVTs &&
1183 "NumValues wasn't wide enough for its operands!");
1184 }
1185
1186 /// Release the operands and set this node to have zero operands.
1187 void DropOperands();
1188};
1189
1190/// Wrapper class for IR location info (IR ordering and DebugLoc) to be passed
1191/// into SDNode creation functions.
1192/// When an SDNode is created from the DAGBuilder, the DebugLoc is extracted
1193/// from the original Instruction, and IROrder is the ordinal position of
1194/// the instruction.
1195/// When an SDNode is created after the DAG is being built, both DebugLoc and
1196/// the IROrder are propagated from the original SDNode.
1197/// So SDLoc class provides two constructors besides the default one, one to
1198/// be used by the DAGBuilder, the other to be used by others.
1199class SDLoc {
1200private:
1201 DebugLoc DL;
1202 int IROrder = 0;
1203
1204public:
1205 SDLoc() = default;
1206 SDLoc(const SDNode *N) : DL(N->getDebugLoc()), IROrder(N->getIROrder()) {}
1207 SDLoc(const SDValue V) : SDLoc(V.getNode()) {}
1208 SDLoc(const Instruction *I, int Order) : IROrder(Order) {
1209 assert(Order >= 0 && "bad IROrder");
1210 if (I)
1211 DL = I->getDebugLoc();
1212 }
1213
1214 unsigned getIROrder() const { return IROrder; }
1215 const DebugLoc &getDebugLoc() const { return DL; }
1216};
1217
1218// Define inline functions from the SDValue class.
1219
1220inline SDValue::SDValue(SDNode *node, unsigned resno)
1221 : Node(node), ResNo(resno) {
1222 // Explicitly check for !ResNo to avoid use-after-free, because there are
1223 // callers that use SDValue(N, 0) with a deleted N to indicate successful
1224 // combines.
1225 assert((!Node || !ResNo || ResNo < Node->getNumValues()) &&
1226 "Invalid result number for the given node!");
1227 assert(ResNo < -2U && "Cannot use result numbers reserved for DenseMaps.");
1228}
1229
1230inline unsigned SDValue::getOpcode() const {
1231 return Node->getOpcode();
1232}
1233
1235 return Node->getValueType(ResNo);
1236}
1237
1238inline unsigned SDValue::getNumOperands() const {
1239 return Node->getNumOperands();
1240}
1241
1242inline const SDValue &SDValue::getOperand(unsigned i) const {
1243 return Node->getOperand(i);
1244}
1245
1247 return Node->getConstantOperandVal(i);
1248}
1249
1250inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const {
1251 return Node->getConstantOperandAPInt(i);
1252}
1253
1254inline bool SDValue::isTargetOpcode() const {
1255 return Node->isTargetOpcode();
1256}
1257
1259 return Node->isTargetMemoryOpcode();
1260}
1261
1262inline bool SDValue::isMachineOpcode() const {
1263 return Node->isMachineOpcode();
1264}
1265
1266inline unsigned SDValue::getMachineOpcode() const {
1267 return Node->getMachineOpcode();
1268}
1269
1270inline bool SDValue::isUndef() const {
1271 return Node->isUndef();
1272}
1273
1274inline bool SDValue::use_empty() const {
1275 return !Node->hasAnyUseOfValue(ResNo);
1276}
1277
1278inline bool SDValue::hasOneUse() const {
1279 return Node->hasNUsesOfValue(1, ResNo);
1280}
1281
1282inline const DebugLoc &SDValue::getDebugLoc() const {
1283 return Node->getDebugLoc();
1284}
1285
1286inline void SDValue::dump() const {
1287 return Node->dump();
1288}
1289
1290inline void SDValue::dump(const SelectionDAG *G) const {
1291 return Node->dump(G);
1292}
1293
1294inline void SDValue::dumpr() const {
1295 return Node->dumpr();
1296}
1297
1298inline void SDValue::dumpr(const SelectionDAG *G) const {
1299 return Node->dumpr(G);
1300}
1301
1302// Define inline functions from the SDUse class.
1303inline unsigned SDUse::getOperandNo() const {
1304 return this - getUser()->op_begin();
1305}
1306
1307inline void SDUse::set(const SDValue &V) {
1308 if (Val.getNode()) removeFromList();
1309 Val = V;
1310 if (V.getNode())
1311 V->addUse(*this);
1312}
1313
1314inline void SDUse::setInitial(const SDValue &V) {
1315 Val = V;
1316 V->addUse(*this);
1317}
1318
1319inline void SDUse::setNode(SDNode *N) {
1320 if (Val.getNode()) removeFromList();
1321 Val.setNode(N);
1322 if (N) N->addUse(*this);
1323}
1324
1325/// This class is used to form a handle around another node that
1326/// is persistent and is updated across invocations of replaceAllUsesWith on its
1327/// operand. This node should be directly created by end-users and not added to
1328/// the AllNodes list.
1329class HandleSDNode : public SDNode {
1330 SDUse Op;
1331
1332public:
1334 : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) {
1335 // HandleSDNodes are never inserted into the DAG, so they won't be
1336 // auto-numbered. Use ID 65535 as a sentinel.
1337 PersistentId = 0xffff;
1338
1339 // Manually set up the operand list. This node type is special in that it's
1340 // always stack allocated and SelectionDAG does not manage its operands.
1341 // TODO: This should either (a) not be in the SDNode hierarchy, or (b) not
1342 // be so special.
1343 Op.setUser(this);
1344 Op.setInitial(X);
1345 NumOperands = 1;
1346 OperandList = &Op;
1347 }
1348 ~HandleSDNode();
1349
1350 const SDValue &getValue() const { return Op; }
1351};
1352
1354private:
1355 unsigned SrcAddrSpace;
1356 unsigned DestAddrSpace;
1357
1358public:
1359 AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
1360 unsigned SrcAS, unsigned DestAS)
1361 : SDNode(ISD::ADDRSPACECAST, Order, dl, VTs), SrcAddrSpace(SrcAS),
1362 DestAddrSpace(DestAS) {}
1363
1364 unsigned getSrcAddressSpace() const { return SrcAddrSpace; }
1365 unsigned getDestAddressSpace() const { return DestAddrSpace; }
1366
1367 static bool classof(const SDNode *N) {
1368 return N->getOpcode() == ISD::ADDRSPACECAST;
1369 }
1370};
1371
1372/// This is an abstract virtual class for memory operations.
1373class MemSDNode : public SDNode {
1374private:
1375 // VT of in-memory value.
1376 EVT MemoryVT;
1377
1378protected:
1379 /// Memory reference information.
1381
1382public:
1383 MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs,
1384 EVT memvt, MachineMemOperand *MMO);
1385
1386 bool readMem() const { return MMO->isLoad(); }
1387 bool writeMem() const { return MMO->isStore(); }
1388
1389 /// Returns alignment and volatility of the memory access
1391 Align getAlign() const { return MMO->getAlign(); }
1392
1393 /// Return the SubclassData value, without HasDebugValue. This contains an
1394 /// encoding of the volatile flag, as well as bits used by subclasses. This
1395 /// function should only be used to compute a FoldingSetNodeID value.
1396 /// The HasDebugValue bit is masked out because CSE map needs to match
1397 /// nodes with debug info with nodes without debug info. Same is about
1398 /// isDivergent bit.
1399 unsigned getRawSubclassData() const {
1400 uint16_t Data;
1401 union {
1402 char RawSDNodeBits[sizeof(uint16_t)];
1404 };
1405 memcpy(&RawSDNodeBits, &this->RawSDNodeBits, sizeof(this->RawSDNodeBits));
1406 SDNodeBits.HasDebugValue = 0;
1407 SDNodeBits.IsDivergent = false;
1408 memcpy(&Data, &RawSDNodeBits, sizeof(RawSDNodeBits));
1409 return Data;
1410 }
1411
1412 bool isVolatile() const { return MemSDNodeBits.IsVolatile; }
1413 bool isNonTemporal() const { return MemSDNodeBits.IsNonTemporal; }
1414 bool isDereferenceable() const { return MemSDNodeBits.IsDereferenceable; }
1415 bool isInvariant() const { return MemSDNodeBits.IsInvariant; }
1416
1417 // Returns the offset from the location of the access.
1418 int64_t getSrcValueOffset() const { return MMO->getOffset(); }
1419
1420 /// Returns the AA info that describes the dereference.
1421 AAMDNodes getAAInfo() const { return MMO->getAAInfo(); }
1422
1423 /// Returns the Ranges that describes the dereference.
1424 const MDNode *getRanges() const { return MMO->getRanges(); }
1425
1426 /// Returns the synchronization scope ID for this memory operation.
1428
1429 /// Return the atomic ordering requirements for this memory operation. For
1430 /// cmpxchg atomic operations, return the atomic ordering requirements when
1431 /// store occurs.
1433 return MMO->getSuccessOrdering();
1434 }
1435
1436 /// Return a single atomic ordering that is at least as strong as both the
1437 /// success and failure orderings for an atomic operation. (For operations
1438 /// other than cmpxchg, this is equivalent to getSuccessOrdering().)
1440
1441 /// Return true if the memory operation ordering is Unordered or higher.
1442 bool isAtomic() const { return MMO->isAtomic(); }
1443
1444 /// Returns true if the memory operation doesn't imply any ordering
1445 /// constraints on surrounding memory operations beyond the normal memory
1446 /// aliasing rules.
1447 bool isUnordered() const { return MMO->isUnordered(); }
1448
1449 /// Returns true if the memory operation is neither atomic or volatile.
1450 bool isSimple() const { return !isAtomic() && !isVolatile(); }
1451
1452 /// Return the type of the in-memory value.
1453 EVT getMemoryVT() const { return MemoryVT; }
1454
1455 /// Return a MachineMemOperand object describing the memory
1456 /// reference performed by operation.
1458
1460 return MMO->getPointerInfo();
1461 }
1462
1463 /// Return the address space for the associated pointer
1464 unsigned getAddressSpace() const {
1465 return getPointerInfo().getAddrSpace();
1466 }
1467
1468 /// Update this MemSDNode's MachineMemOperand information
1469 /// to reflect the alignment of NewMMO, if it has a greater alignment.
1470 /// This must only be used when the new alignment applies to all users of
1471 /// this MachineMemOperand.
1473 MMO->refineAlignment(NewMMO);
1474 }
1475
1476 const SDValue &getChain() const { return getOperand(0); }
1477
1478 const SDValue &getBasePtr() const {
1479 switch (getOpcode()) {
1480 case ISD::STORE:
1481 case ISD::ATOMIC_STORE:
1482 case ISD::VP_STORE:
1483 case ISD::MSTORE:
1484 case ISD::VP_SCATTER:
1485 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1486 return getOperand(2);
1487 case ISD::MGATHER:
1488 case ISD::MSCATTER:
1490 return getOperand(3);
1491 default:
1492 return getOperand(1);
1493 }
1494 }
1495
1496 // Methods to support isa and dyn_cast
1497 static bool classof(const SDNode *N) {
1498 // For some targets, we lower some target intrinsics to a MemIntrinsicNode
1499 // with either an intrinsic or a target opcode.
1500 switch (N->getOpcode()) {
1501 case ISD::LOAD:
1502 case ISD::STORE:
1505 case ISD::ATOMIC_SWAP:
1525 case ISD::ATOMIC_LOAD:
1526 case ISD::ATOMIC_STORE:
1527 case ISD::MLOAD:
1528 case ISD::MSTORE:
1529 case ISD::MGATHER:
1530 case ISD::MSCATTER:
1531 case ISD::VP_LOAD:
1532 case ISD::VP_STORE:
1533 case ISD::VP_GATHER:
1534 case ISD::VP_SCATTER:
1535 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1536 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1537 case ISD::GET_FPENV_MEM:
1538 case ISD::SET_FPENV_MEM:
1540 return true;
1541 default:
1542 return N->isMemIntrinsic();
1543 }
1544 }
1545};
1546
1547/// This is an SDNode representing atomic operations.
1548class AtomicSDNode : public MemSDNode {
1549public:
1550 AtomicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTL,
1551 EVT MemVT, MachineMemOperand *MMO)
1552 : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
1553 assert(((Opc != ISD::ATOMIC_LOAD && Opc != ISD::ATOMIC_STORE) ||
1554 MMO->isAtomic()) && "then why are we using an AtomicSDNode?");
1555 }
1556
1558 assert(getOpcode() == ISD::ATOMIC_LOAD && "Only used for atomic loads.");
1559 LoadSDNodeBits.ExtTy = ETy;
1560 }
1561
1563 assert(getOpcode() == ISD::ATOMIC_LOAD && "Only used for atomic loads.");
1564 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
1565 }
1566
1567 const SDValue &getBasePtr() const {
1568 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(2) : getOperand(1);
1569 }
1570 const SDValue &getVal() const {
1571 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(1) : getOperand(2);
1572 }
1573
1574 /// Returns true if this SDNode represents cmpxchg atomic operation, false
1575 /// otherwise.
1576 bool isCompareAndSwap() const {
1577 unsigned Op = getOpcode();
1578 return Op == ISD::ATOMIC_CMP_SWAP ||
1580 }
1581
1582 /// For cmpxchg atomic operations, return the atomic ordering requirements
1583 /// when store does not occur.
1585 assert(isCompareAndSwap() && "Must be cmpxchg operation");
1586 return MMO->getFailureOrdering();
1587 }
1588
1589 // Methods to support isa and dyn_cast
1590 static bool classof(const SDNode *N) {
1591 return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
1592 N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
1593 N->getOpcode() == ISD::ATOMIC_SWAP ||
1594 N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1595 N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1596 N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1597 N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1598 N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1599 N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1600 N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1601 N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1602 N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1603 N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1604 N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1605 N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1606 N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1607 N->getOpcode() == ISD::ATOMIC_LOAD_FMAX ||
1608 N->getOpcode() == ISD::ATOMIC_LOAD_FMIN ||
1609 N->getOpcode() == ISD::ATOMIC_LOAD_UINC_WRAP ||
1610 N->getOpcode() == ISD::ATOMIC_LOAD_UDEC_WRAP ||
1611 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_COND ||
1612 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_SAT ||
1613 N->getOpcode() == ISD::ATOMIC_LOAD ||
1614 N->getOpcode() == ISD::ATOMIC_STORE;
1615 }
1616};
1617
1618/// This SDNode is used for target intrinsics that touch
1619/// memory and need an associated MachineMemOperand. Its opcode may be
1620/// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode
1621/// with a value not less than FIRST_TARGET_MEMORY_OPCODE.
1623public:
1624 MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl,
1625 SDVTList VTs, EVT MemoryVT, MachineMemOperand *MMO)
1626 : MemSDNode(Opc, Order, dl, VTs, MemoryVT, MMO) {
1627 SDNodeBits.IsMemIntrinsic = true;
1628 }
1629
1630 // Methods to support isa and dyn_cast
1631 static bool classof(const SDNode *N) {
1632 // We lower some target intrinsics to their target opcode
1633 // early a node with a target opcode can be of this class
1634 return N->isMemIntrinsic();
1635 }
1636};
1637
1638/// This SDNode is used to implement the code generator
1639/// support for the llvm IR shufflevector instruction. It combines elements
1640/// from two input vectors into a new input vector, with the selection and
1641/// ordering of elements determined by an array of integers, referred to as
1642/// the shuffle mask. For input vectors of width N, mask indices of 0..N-1
1643/// refer to elements from the LHS input, and indices from N to 2N-1 the RHS.
1644/// An index of -1 is treated as undef, such that the code generator may put
1645/// any value in the corresponding element of the result.
1647 // The memory for Mask is owned by the SelectionDAG's OperandAllocator, and
1648 // is freed when the SelectionDAG object is destroyed.
1649 const int *Mask;
1650
1651protected:
1652 friend class SelectionDAG;
1653
1654 ShuffleVectorSDNode(SDVTList VTs, unsigned Order, const DebugLoc &dl,
1655 const int *M)
1656 : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, VTs), Mask(M) {}
1657
1658public:
1660 EVT VT = getValueType(0);
1661 return ArrayRef(Mask, VT.getVectorNumElements());
1662 }
1663
1664 int getMaskElt(unsigned Idx) const {
1665 assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!");
1666 return Mask[Idx];
1667 }
1668
1669 bool isSplat() const { return isSplatMask(Mask, getValueType(0)); }
1670
1671 int getSplatIndex() const {
1672 assert(isSplat() && "Cannot get splat index for non-splat!");
1673 EVT VT = getValueType(0);
1674 for (unsigned i = 0, e = VT.getVectorNumElements(); i != e; ++i)
1675 if (Mask[i] >= 0)
1676 return Mask[i];
1677
1678 // We can choose any index value here and be correct because all elements
1679 // are undefined. Return 0 for better potential for callers to simplify.
1680 return 0;
1681 }
1682
1683 static bool isSplatMask(const int *Mask, EVT VT);
1684
1685 /// Change values in a shuffle permute mask assuming
1686 /// the two vector operands have swapped position.
1688 unsigned NumElems = Mask.size();
1689 for (unsigned i = 0; i != NumElems; ++i) {
1690 int idx = Mask[i];
1691 if (idx < 0)
1692 continue;
1693 else if (idx < (int)NumElems)
1694 Mask[i] = idx + NumElems;
1695 else
1696 Mask[i] = idx - NumElems;
1697 }
1698 }
1699
1700 static bool classof(const SDNode *N) {
1701 return N->getOpcode() == ISD::VECTOR_SHUFFLE;
1702 }
1703};
1704
1705class ConstantSDNode : public SDNode {
1706 friend class SelectionDAG;
1707
1708 const ConstantInt *Value;
1709
1710 ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val,
1711 SDVTList VTs)
1712 : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(),
1713 VTs),
1714 Value(val) {
1715 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1716 ConstantSDNodeBits.IsOpaque = isOpaque;
1717 }
1718
1719public:
1720 const ConstantInt *getConstantIntValue() const { return Value; }
1721 const APInt &getAPIntValue() const { return Value->getValue(); }
1722 uint64_t getZExtValue() const { return Value->getZExtValue(); }
1723 int64_t getSExtValue() const { return Value->getSExtValue(); }
1725 return Value->getLimitedValue(Limit);
1726 }
1727 MaybeAlign getMaybeAlignValue() const { return Value->getMaybeAlignValue(); }
1728 Align getAlignValue() const { return Value->getAlignValue(); }
1729
1730 bool isOne() const { return Value->isOne(); }
1731 bool isZero() const { return Value->isZero(); }
1732 bool isAllOnes() const { return Value->isMinusOne(); }
1733 bool isMaxSignedValue() const { return Value->isMaxValue(true); }
1734 bool isMinSignedValue() const { return Value->isMinValue(true); }
1735
1736 bool isOpaque() const { return ConstantSDNodeBits.IsOpaque; }
1737
1738 static bool classof(const SDNode *N) {
1739 return N->getOpcode() == ISD::Constant ||
1740 N->getOpcode() == ISD::TargetConstant;
1741 }
1742};
1743
1745 return cast<ConstantSDNode>(getOperand(Num))->getZExtValue();
1746}
1747
1749 return cast<ConstantSDNode>(this)->getZExtValue();
1750}
1751
1752const APInt &SDNode::getConstantOperandAPInt(unsigned Num) const {
1753 return cast<ConstantSDNode>(getOperand(Num))->getAPIntValue();
1754}
1755
1757 return cast<ConstantSDNode>(this)->getAPIntValue();
1758}
1759
1760class ConstantFPSDNode : public SDNode {
1761 friend class SelectionDAG;
1762
1763 const ConstantFP *Value;
1764
1765 ConstantFPSDNode(bool isTarget, const ConstantFP *val, SDVTList VTs)
1766 : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0,
1767 DebugLoc(), VTs),
1768 Value(val) {
1769 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1770 }
1771
1772public:
1773 const APFloat& getValueAPF() const { return Value->getValueAPF(); }
1774 const ConstantFP *getConstantFPValue() const { return Value; }
1775
1776 /// Return true if the value is positive or negative zero.
1777 bool isZero() const { return Value->isZero(); }
1778
1779 /// Return true if the value is a NaN.
1780 bool isNaN() const { return Value->isNaN(); }
1781
1782 /// Return true if the value is an infinity
1783 bool isInfinity() const { return Value->isInfinity(); }
1784
1785 /// Return true if the value is negative.
1786 bool isNegative() const { return Value->isNegative(); }
1787
1788 /// We don't rely on operator== working on double values, as
1789 /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
1790 /// As such, this method can be used to do an exact bit-for-bit comparison of
1791 /// two floating point values.
1792
1793 /// We leave the version with the double argument here because it's just so
1794 /// convenient to write "2.0" and the like. Without this function we'd
1795 /// have to duplicate its logic everywhere it's called.
1796 bool isExactlyValue(double V) const {
1797 return Value->getValueAPF().isExactlyValue(V);
1798 }
1799 bool isExactlyValue(const APFloat& V) const;
1800
1801 static bool isValueValidForType(EVT VT, const APFloat& Val);
1802
1803 static bool classof(const SDNode *N) {
1804 return N->getOpcode() == ISD::ConstantFP ||
1805 N->getOpcode() == ISD::TargetConstantFP;
1806 }
1807};
1808
1809/// Returns true if \p V is a constant integer zero.
1810bool isNullConstant(SDValue V);
1811
1812/// Returns true if \p V is a constant integer zero or an UNDEF node.
1813bool isNullConstantOrUndef(SDValue V);
1814
1815/// Returns true if \p V is an FP constant with a value of positive zero.
1816bool isNullFPConstant(SDValue V);
1817
1818/// Returns true if \p V is an integer constant with all bits set.
1819bool isAllOnesConstant(SDValue V);
1820
1821/// Returns true if \p V is a constant integer one.
1822bool isOneConstant(SDValue V);
1823
1824/// Returns true if \p V is a constant min signed integer value.
1825bool isMinSignedConstant(SDValue V);
1826
1827/// Returns true if \p V is a neutral element of Opc with Flags.
1828/// When OperandNo is 0, it checks that V is a left identity. Otherwise, it
1829/// checks that V is a right identity.
1830bool isNeutralConstant(unsigned Opc, SDNodeFlags Flags, SDValue V,
1831 unsigned OperandNo);
1832
1833/// Return the non-bitcasted source operand of \p V if it exists.
1834/// If \p V is not a bitcasted value, it is returned as-is.
1835SDValue peekThroughBitcasts(SDValue V);
1836
1837/// Return the non-bitcasted and one-use source operand of \p V if it exists.
1838/// If \p V is not a bitcasted one-use value, it is returned as-is.
1839SDValue peekThroughOneUseBitcasts(SDValue V);
1840
1841/// Return the non-extracted vector source operand of \p V if it exists.
1842/// If \p V is not an extracted subvector, it is returned as-is.
1843SDValue peekThroughExtractSubvectors(SDValue V);
1844
1845/// Return the non-truncated source operand of \p V if it exists.
1846/// If \p V is not a truncation, it is returned as-is.
1847SDValue peekThroughTruncates(SDValue V);
1848
1849/// Returns true if \p V is a bitwise not operation. Assumes that an all ones
1850/// constant is canonicalized to be operand 1.
1851bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
1852
1853/// If \p V is a bitwise not, returns the inverted operand. Otherwise returns
1854/// an empty SDValue. Only bits set in \p Mask are required to be inverted,
1855/// other bits may be arbitrary.
1856SDValue getBitwiseNotOperand(SDValue V, SDValue Mask, bool AllowUndefs);
1857
1858/// Returns the SDNode if it is a constant splat BuildVector or constant int.
1859ConstantSDNode *isConstOrConstSplat(SDValue N, bool AllowUndefs = false,
1860 bool AllowTruncation = false);
1861
1862/// Returns the SDNode if it is a demanded constant splat BuildVector or
1863/// constant int.
1864ConstantSDNode *isConstOrConstSplat(SDValue N, const APInt &DemandedElts,
1865 bool AllowUndefs = false,
1866 bool AllowTruncation = false);
1867
1868/// Returns the SDNode if it is a constant splat BuildVector or constant float.
1869ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, bool AllowUndefs = false);
1870
1871/// Returns the SDNode if it is a demanded constant splat BuildVector or
1872/// constant float.
1873ConstantFPSDNode *isConstOrConstSplatFP(SDValue N, const APInt &DemandedElts,
1874 bool AllowUndefs = false);
1875
1876/// Return true if the value is a constant 0 integer or a splatted vector of
1877/// a constant 0 integer (with no undefs by default).
1878/// Build vector implicit truncation is not an issue for null values.
1879bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false);
1880
1881/// Return true if the value is a constant 1 integer or a splatted vector of a
1882/// constant 1 integer (with no undefs).
1883/// Build vector implicit truncation is allowed, but the truncated bits need to
1884/// be zero.
1885bool isOneOrOneSplat(SDValue V, bool AllowUndefs = false);
1886
1887/// Return true if the value is a constant -1 integer or a splatted vector of a
1888/// constant -1 integer (with no undefs).
1889/// Does not permit build vector implicit truncation.
1890bool isAllOnesOrAllOnesSplat(SDValue V, bool AllowUndefs = false);
1891
1892/// Return true if \p V is either a integer or FP constant.
1894 return isa<ConstantSDNode>(V) || isa<ConstantFPSDNode>(V);
1895}
1896
1898 friend class SelectionDAG;
1899
1900 const GlobalValue *TheGlobal;
1901 int64_t Offset;
1902 unsigned TargetFlags;
1903
1904 GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL,
1905 const GlobalValue *GA, SDVTList VTs, int64_t o,
1906 unsigned TF)
1907 : SDNode(Opc, Order, DL, VTs), TheGlobal(GA), Offset(o), TargetFlags(TF) {
1908 }
1909
1910public:
1911 const GlobalValue *getGlobal() const { return TheGlobal; }
1912 int64_t getOffset() const { return Offset; }
1913 unsigned getTargetFlags() const { return TargetFlags; }
1914 // Return the address space this GlobalAddress belongs to.
1915 unsigned getAddressSpace() const;
1916
1917 static bool classof(const SDNode *N) {
1918 return N->getOpcode() == ISD::GlobalAddress ||
1919 N->getOpcode() == ISD::TargetGlobalAddress ||
1920 N->getOpcode() == ISD::GlobalTLSAddress ||
1921 N->getOpcode() == ISD::TargetGlobalTLSAddress;
1922 }
1923};
1924
1925class FrameIndexSDNode : public SDNode {
1926 friend class SelectionDAG;
1927
1928 int FI;
1929
1930 FrameIndexSDNode(int fi, SDVTList VTs, bool isTarg)
1931 : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, 0, DebugLoc(),
1932 VTs),
1933 FI(fi) {}
1934
1935public:
1936 int getIndex() const { return FI; }
1937
1938 static bool classof(const SDNode *N) {
1939 return N->getOpcode() == ISD::FrameIndex ||
1940 N->getOpcode() == ISD::TargetFrameIndex;
1941 }
1942};
1943
1944/// This SDNode is used for LIFETIME_START/LIFETIME_END values, which indicate
1945/// the offet and size that are started/ended in the underlying FrameIndex.
1946class LifetimeSDNode : public SDNode {
1947 friend class SelectionDAG;
1948 int64_t Size;
1949 int64_t Offset; // -1 if offset is unknown.
1950
1951 LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl,
1952 SDVTList VTs, int64_t Size, int64_t Offset)
1953 : SDNode(Opcode, Order, dl, VTs), Size(Size), Offset(Offset) {}
1954public:
1955 int64_t getFrameIndex() const {
1956 return cast<FrameIndexSDNode>(getOperand(1))->getIndex();
1957 }
1958
1959 bool hasOffset() const { return Offset >= 0; }
1960 int64_t getOffset() const {
1961 assert(hasOffset() && "offset is unknown");
1962 return Offset;
1963 }
1964 int64_t getSize() const {
1965 assert(hasOffset() && "offset is unknown");
1966 return Size;
1967 }
1968
1969 // Methods to support isa and dyn_cast
1970 static bool classof(const SDNode *N) {
1971 return N->getOpcode() == ISD::LIFETIME_START ||
1972 N->getOpcode() == ISD::LIFETIME_END;
1973 }
1974};
1975
1976/// This SDNode is used for PSEUDO_PROBE values, which are the function guid and
1977/// the index of the basic block being probed. A pseudo probe serves as a place
1978/// holder and will be removed at the end of compilation. It does not have any
1979/// operand because we do not want the instruction selection to deal with any.
1981 friend class SelectionDAG;
1982 uint64_t Guid;
1984 uint32_t Attributes;
1985
1986 PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl,
1987 SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr)
1988 : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index),
1989 Attributes(Attr) {}
1990
1991public:
1992 uint64_t getGuid() const { return Guid; }
1993 uint64_t getIndex() const { return Index; }
1995
1996 // Methods to support isa and dyn_cast
1997 static bool classof(const SDNode *N) {
1998 return N->getOpcode() == ISD::PSEUDO_PROBE;
1999 }
2000};
2001
2002class JumpTableSDNode : public SDNode {
2003 friend class SelectionDAG;
2004
2005 int JTI;
2006 unsigned TargetFlags;
2007
2008 JumpTableSDNode(int jti, SDVTList VTs, bool isTarg, unsigned TF)
2009 : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, 0, DebugLoc(),
2010 VTs),
2011 JTI(jti), TargetFlags(TF) {}
2012
2013public:
2014 int getIndex() const { return JTI; }
2015 unsigned getTargetFlags() const { return TargetFlags; }
2016
2017 static bool classof(const SDNode *N) {
2018 return N->getOpcode() == ISD::JumpTable ||
2019 N->getOpcode() == ISD::TargetJumpTable;
2020 }
2021};
2022
2024 friend class SelectionDAG;
2025
2026 union {
2029 } Val;
2030 int Offset; // It's a MachineConstantPoolValue if top bit is set.
2031 Align Alignment; // Minimum alignment requirement of CP.
2032 unsigned TargetFlags;
2033
2034 ConstantPoolSDNode(bool isTarget, const Constant *c, SDVTList VTs, int o,
2035 Align Alignment, unsigned TF)
2036 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2037 DebugLoc(), VTs),
2038 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2039 assert(Offset >= 0 && "Offset is too large");
2040 Val.ConstVal = c;
2041 }
2042
2043 ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, SDVTList VTs,
2044 int o, Align Alignment, unsigned TF)
2045 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2046 DebugLoc(), VTs),
2047 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2048 assert(Offset >= 0 && "Offset is too large");
2049 Val.MachineCPVal = v;
2050 Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
2051 }
2052
2053public:
2055 return Offset < 0;
2056 }
2057
2058 const Constant *getConstVal() const {
2059 assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
2060 return Val.ConstVal;
2061 }
2062
2064 assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
2065 return Val.MachineCPVal;
2066 }
2067
2068 int getOffset() const {
2069 return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
2070 }
2071
2072 // Return the alignment of this constant pool object, which is either 0 (for
2073 // default alignment) or the desired value.
2074 Align getAlign() const { return Alignment; }
2075 unsigned getTargetFlags() const { return TargetFlags; }
2076
2077 Type *getType() const;
2078
2079 static bool classof(const SDNode *N) {
2080 return N->getOpcode() == ISD::ConstantPool ||
2081 N->getOpcode() == ISD::TargetConstantPool;
2082 }
2083};
2084
2085/// Completely target-dependent object reference.
2087 friend class SelectionDAG;
2088
2089 unsigned TargetFlags;
2090 int Index;
2091 int64_t Offset;
2092
2093public:
2094 TargetIndexSDNode(int Idx, SDVTList VTs, int64_t Ofs, unsigned TF)
2095 : SDNode(ISD::TargetIndex, 0, DebugLoc(), VTs), TargetFlags(TF),
2096 Index(Idx), Offset(Ofs) {}
2097
2098 unsigned getTargetFlags() const { return TargetFlags; }
2099 int getIndex() const { return Index; }
2100 int64_t getOffset() const { return Offset; }
2101
2102 static bool classof(const SDNode *N) {
2103 return N->getOpcode() == ISD::TargetIndex;
2104 }
2105};
2106
2107class BasicBlockSDNode : public SDNode {
2108 friend class SelectionDAG;
2109
2111
2112 /// Debug info is meaningful and potentially useful here, but we create
2113 /// blocks out of order when they're jumped to, which makes it a bit
2114 /// harder. Let's see if we need it first.
2115 explicit BasicBlockSDNode(MachineBasicBlock *mbb)
2116 : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb)
2117 {}
2118
2119public:
2121
2122 static bool classof(const SDNode *N) {
2123 return N->getOpcode() == ISD::BasicBlock;
2124 }
2125};
2126
2127/// A "pseudo-class" with methods for operating on BUILD_VECTORs.
2129public:
2130 // These are constructed as SDNodes and then cast to BuildVectorSDNodes.
2131 explicit BuildVectorSDNode() = delete;
2132
2133 /// Check if this is a constant splat, and if so, find the
2134 /// smallest element size that splats the vector. If MinSplatBits is
2135 /// nonzero, the element size must be at least that large. Note that the
2136 /// splat element may be the entire vector (i.e., a one element vector).
2137 /// Returns the splat element value in SplatValue. Any undefined bits in
2138 /// that value are zero, and the corresponding bits in the SplatUndef mask
2139 /// are set. The SplatBitSize value is set to the splat element size in
2140 /// bits. HasAnyUndefs is set to true if any bits in the vector are
2141 /// undefined. isBigEndian describes the endianness of the target.
2142 bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
2143 unsigned &SplatBitSize, bool &HasAnyUndefs,
2144 unsigned MinSplatBits = 0,
2145 bool isBigEndian = false) const;
2146
2147 /// Returns the demanded splatted value or a null value if this is not a
2148 /// splat.
2149 ///
2150 /// The DemandedElts mask indicates the elements that must be in the splat.
2151 /// If passed a non-null UndefElements bitvector, it will resize it to match
2152 /// the vector width and set the bits where elements are undef.
2153 SDValue getSplatValue(const APInt &DemandedElts,
2154 BitVector *UndefElements = nullptr) const;
2155
2156 /// Returns the splatted value or a null value if this is not a splat.
2157 ///
2158 /// If passed a non-null UndefElements bitvector, it will resize it to match
2159 /// the vector width and set the bits where elements are undef.
2160 SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
2161
2162 /// Find the shortest repeating sequence of values in the build vector.
2163 ///
2164 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
2165 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
2166 ///
2167 /// Currently this must be a power-of-2 build vector.
2168 /// The DemandedElts mask indicates the elements that must be present,
2169 /// undemanded elements in Sequence may be null (SDValue()). If passed a
2170 /// non-null UndefElements bitvector, it will resize it to match the original
2171 /// vector width and set the bits where elements are undef. If result is
2172 /// false, Sequence will be empty.
2173 bool getRepeatedSequence(const APInt &DemandedElts,
2174 SmallVectorImpl<SDValue> &Sequence,
2175 BitVector *UndefElements = nullptr) const;
2176
2177 /// Find the shortest repeating sequence of values in the build vector.
2178 ///
2179 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
2180 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
2181 ///
2182 /// Currently this must be a power-of-2 build vector.
2183 /// If passed a non-null UndefElements bitvector, it will resize it to match
2184 /// the original vector width and set the bits where elements are undef.
2185 /// If result is false, Sequence will be empty.
2187 BitVector *UndefElements = nullptr) const;
2188
2189 /// Returns the demanded splatted constant or null if this is not a constant
2190 /// splat.
2191 ///
2192 /// The DemandedElts mask indicates the elements that must be in the splat.
2193 /// If passed a non-null UndefElements bitvector, it will resize it to match
2194 /// the vector width and set the bits where elements are undef.
2196 getConstantSplatNode(const APInt &DemandedElts,
2197 BitVector *UndefElements = nullptr) const;
2198
2199 /// Returns the splatted constant or null if this is not a constant
2200 /// splat.
2201 ///
2202 /// If passed a non-null UndefElements bitvector, it will resize it to match
2203 /// the vector width and set the bits where elements are undef.
2205 getConstantSplatNode(BitVector *UndefElements = nullptr) const;
2206
2207 /// Returns the demanded splatted constant FP or null if this is not a
2208 /// constant FP splat.
2209 ///
2210 /// The DemandedElts mask indicates the elements that must be in the splat.
2211 /// If passed a non-null UndefElements bitvector, it will resize it to match
2212 /// the vector width and set the bits where elements are undef.
2214 getConstantFPSplatNode(const APInt &DemandedElts,
2215 BitVector *UndefElements = nullptr) const;
2216
2217 /// Returns the splatted constant FP or null if this is not a constant
2218 /// FP splat.
2219 ///
2220 /// If passed a non-null UndefElements bitvector, it will resize it to match
2221 /// the vector width and set the bits where elements are undef.
2223 getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
2224
2225 /// If this is a constant FP splat and the splatted constant FP is an
2226 /// exact power or 2, return the log base 2 integer value. Otherwise,
2227 /// return -1.
2228 ///
2229 /// The BitWidth specifies the necessary bit precision.
2230 int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements,
2231 uint32_t BitWidth) const;
2232
2233 /// Extract the raw bit data from a build vector of Undef, Constant or
2234 /// ConstantFP node elements. Each raw bit element will be \p
2235 /// DstEltSizeInBits wide, undef elements are treated as zero, and entirely
2236 /// undefined elements are flagged in \p UndefElements.
2237 bool getConstantRawBits(bool IsLittleEndian, unsigned DstEltSizeInBits,
2238 SmallVectorImpl<APInt> &RawBitElements,
2239 BitVector &UndefElements) const;
2240
2241 bool isConstant() const;
2242
2243 /// If this BuildVector is constant and represents the numerical series
2244 /// "<a, a+n, a+2n, a+3n, ...>" where a is integer and n is a non-zero integer,
2245 /// the value "<a,n>" is returned.
2246 std::optional<std::pair<APInt, APInt>> isConstantSequence() const;
2247
2248 /// Recast bit data \p SrcBitElements to \p DstEltSizeInBits wide elements.
2249 /// Undef elements are treated as zero, and entirely undefined elements are
2250 /// flagged in \p DstUndefElements.
2251 static void recastRawBits(bool IsLittleEndian, unsigned DstEltSizeInBits,
2252 SmallVectorImpl<APInt> &DstBitElements,
2253 ArrayRef<APInt> SrcBitElements,
2254 BitVector &DstUndefElements,
2255 const BitVector &SrcUndefElements);
2256
2257 static bool classof(const SDNode *N) {
2258 return N->getOpcode() == ISD::BUILD_VECTOR;
2259 }
2260};
2261
2262/// An SDNode that holds an arbitrary LLVM IR Value. This is
2263/// used when the SelectionDAG needs to make a simple reference to something
2264/// in the LLVM IR representation.
2265///
2266class SrcValueSDNode : public SDNode {
2267 friend class SelectionDAG;
2268
2269 const Value *V;
2270
2271 /// Create a SrcValue for a general value.
2272 explicit SrcValueSDNode(const Value *v)
2273 : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
2274
2275public:
2276 /// Return the contained Value.
2277 const Value *getValue() const { return V; }
2278
2279 static bool classof(const SDNode *N) {
2280 return N->getOpcode() == ISD::SRCVALUE;
2281 }
2282};
2283
2284class MDNodeSDNode : public SDNode {
2285 friend class SelectionDAG;
2286
2287 const MDNode *MD;
2288
2289 explicit MDNodeSDNode(const MDNode *md)
2290 : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md)
2291 {}
2292
2293public:
2294 const MDNode *getMD() const { return MD; }
2295
2296 static bool classof(const SDNode *N) {
2297 return N->getOpcode() == ISD::MDNODE_SDNODE;
2298 }
2299};
2300
2301class RegisterSDNode : public SDNode {
2302 friend class SelectionDAG;
2303
2304 Register Reg;
2305
2307 : SDNode(ISD::Register, 0, DebugLoc(), VTs), Reg(reg) {}
2308
2309public:
2310 Register getReg() const { return Reg; }
2311
2312 static bool classof(const SDNode *N) {
2313 return N->getOpcode() == ISD::Register;
2314 }
2315};
2316
2318 friend class SelectionDAG;
2319
2320 // The memory for RegMask is not owned by the node.
2321 const uint32_t *RegMask;
2322
2323 RegisterMaskSDNode(const uint32_t *mask)
2324 : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)),
2325 RegMask(mask) {}
2326
2327public:
2328 const uint32_t *getRegMask() const { return RegMask; }
2329
2330 static bool classof(const SDNode *N) {
2331 return N->getOpcode() == ISD::RegisterMask;
2332 }
2333};
2334
2336 friend class SelectionDAG;
2337
2338 const BlockAddress *BA;
2339 int64_t Offset;
2340 unsigned TargetFlags;
2341
2342 BlockAddressSDNode(unsigned NodeTy, SDVTList VTs, const BlockAddress *ba,
2343 int64_t o, unsigned Flags)
2344 : SDNode(NodeTy, 0, DebugLoc(), VTs), BA(ba), Offset(o),
2345 TargetFlags(Flags) {}
2346
2347public:
2348 const BlockAddress *getBlockAddress() const { return BA; }
2349 int64_t getOffset() const { return Offset; }
2350 unsigned getTargetFlags() const { return TargetFlags; }
2351
2352 static bool classof(const SDNode *N) {
2353 return N->getOpcode() == ISD::BlockAddress ||
2354 N->getOpcode() == ISD::TargetBlockAddress;
2355 }
2356};
2357
2358class LabelSDNode : public SDNode {
2359 friend class SelectionDAG;
2360
2361 MCSymbol *Label;
2362
2363 LabelSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, MCSymbol *L)
2364 : SDNode(Opcode, Order, dl, getSDVTList(MVT::Other)), Label(L) {
2365 assert(LabelSDNode::classof(this) && "not a label opcode");
2366 }
2367
2368public:
2369 MCSymbol *getLabel() const { return Label; }
2370
2371 static bool classof(const SDNode *N) {
2372 return N->getOpcode() == ISD::EH_LABEL ||
2373 N->getOpcode() == ISD::ANNOTATION_LABEL;
2374 }
2375};
2376
2378 friend class SelectionDAG;
2379
2380 const char *Symbol;
2381 unsigned TargetFlags;
2382
2383 ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF,
2384 SDVTList VTs)
2385 : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0,
2386 DebugLoc(), VTs),
2387 Symbol(Sym), TargetFlags(TF) {}
2388
2389public:
2390 const char *getSymbol() const { return Symbol; }
2391 unsigned getTargetFlags() const { return TargetFlags; }
2392
2393 static bool classof(const SDNode *N) {
2394 return N->getOpcode() == ISD::ExternalSymbol ||
2395 N->getOpcode() == ISD::TargetExternalSymbol;
2396 }
2397};
2398
2399class MCSymbolSDNode : public SDNode {
2400 friend class SelectionDAG;
2401
2402 MCSymbol *Symbol;
2403
2404 MCSymbolSDNode(MCSymbol *Symbol, SDVTList VTs)
2405 : SDNode(ISD::MCSymbol, 0, DebugLoc(), VTs), Symbol(Symbol) {}
2406
2407public:
2408 MCSymbol *getMCSymbol() const { return Symbol; }
2409
2410 static bool classof(const SDNode *N) {
2411 return N->getOpcode() == ISD::MCSymbol;
2412 }
2413};
2414
2415class CondCodeSDNode : public SDNode {
2416 friend class SelectionDAG;
2417
2418 ISD::CondCode Condition;
2419
2421 : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2422 Condition(Cond) {}
2423
2424public:
2425 ISD::CondCode get() const { return Condition; }
2426
2427 static bool classof(const SDNode *N) {
2428 return N->getOpcode() == ISD::CONDCODE;
2429 }
2430};
2431
2432/// This class is used to represent EVT's, which are used
2433/// to parameterize some operations.
2434class VTSDNode : public SDNode {
2435 friend class SelectionDAG;
2436
2437 EVT ValueType;
2438
2439 explicit VTSDNode(EVT VT)
2440 : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2441 ValueType(VT) {}
2442
2443public:
2444 EVT getVT() const { return ValueType; }
2445
2446 static bool classof(const SDNode *N) {
2447 return N->getOpcode() == ISD::VALUETYPE;
2448 }
2449};
2450
2451/// Base class for LoadSDNode and StoreSDNode
2452class LSBaseSDNode : public MemSDNode {
2453public:
2454 LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl,
2455 SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT,
2457 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2458 LSBaseSDNodeBits.AddressingMode = AM;
2459 assert(getAddressingMode() == AM && "Value truncated");
2460 }
2461
2462 const SDValue &getOffset() const {
2463 return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
2464 }
2465
2466 /// Return the addressing mode for this load or store:
2467 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2469 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2470 }
2471
2472 /// Return true if this is a pre/post inc/dec load/store.
2473 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2474
2475 /// Return true if this is NOT a pre/post inc/dec load/store.
2476 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2477
2478 static bool classof(const SDNode *N) {
2479 return N->getOpcode() == ISD::LOAD ||
2480 N->getOpcode() == ISD::STORE;
2481 }
2482};
2483
2484/// This class is used to represent ISD::LOAD nodes.
2485class LoadSDNode : public LSBaseSDNode {
2486 friend class SelectionDAG;
2487
2488 LoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2491 : LSBaseSDNode(ISD::LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2492 LoadSDNodeBits.ExtTy = ETy;
2493 assert(readMem() && "Load MachineMemOperand is not a load!");
2494 assert(!writeMem() && "Load MachineMemOperand is a store!");
2495 }
2496
2497public:
2498 /// Return whether this is a plain node,
2499 /// or one of the varieties of value-extending loads.
2501 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2502 }
2503
2504 const SDValue &getBasePtr() const { return getOperand(1); }
2505 const SDValue &getOffset() const { return getOperand(2); }
2506
2507 static bool classof(const SDNode *N) {
2508 return N->getOpcode() == ISD::LOAD;
2509 }
2510};
2511
2512/// This class is used to represent ISD::STORE nodes.
2514 friend class SelectionDAG;
2515
2516 StoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2517 ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT,
2519 : LSBaseSDNode(ISD::STORE, Order, dl, VTs, AM, MemVT, MMO) {
2520 StoreSDNodeBits.IsTruncating = isTrunc;
2521 assert(!readMem() && "Store MachineMemOperand is a load!");
2522 assert(writeMem() && "Store MachineMemOperand is not a store!");
2523 }
2524
2525public:
2526 /// Return true if the op does a truncation before store.
2527 /// For integers this is the same as doing a TRUNCATE and storing the result.
2528 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2529 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2530 void setTruncatingStore(bool Truncating) {
2531 StoreSDNodeBits.IsTruncating = Truncating;
2532 }
2533
2534 const SDValue &getValue() const { return getOperand(1); }
2535 const SDValue &getBasePtr() const { return getOperand(2); }
2536 const SDValue &getOffset() const { return getOperand(3); }
2537
2538 static bool classof(const SDNode *N) {
2539 return N->getOpcode() == ISD::STORE;
2540 }
2541};
2542
2543/// This base class is used to represent VP_LOAD, VP_STORE,
2544/// EXPERIMENTAL_VP_STRIDED_LOAD and EXPERIMENTAL_VP_STRIDED_STORE nodes
2546public:
2547 friend class SelectionDAG;
2548
2549 VPBaseLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2550 const DebugLoc &DL, SDVTList VTs,
2551 ISD::MemIndexedMode AM, EVT MemVT,
2553 : MemSDNode(NodeTy, Order, DL, VTs, MemVT, MMO) {
2554 LSBaseSDNodeBits.AddressingMode = AM;
2555 assert(getAddressingMode() == AM && "Value truncated");
2556 }
2557
2558 // VPStridedStoreSDNode (Chain, Data, Ptr, Offset, Stride, Mask, EVL)
2559 // VPStoreSDNode (Chain, Data, Ptr, Offset, Mask, EVL)
2560 // VPStridedLoadSDNode (Chain, Ptr, Offset, Stride, Mask, EVL)
2561 // VPLoadSDNode (Chain, Ptr, Offset, Mask, EVL)
2562 // Mask is a vector of i1 elements;
2563 // the type of EVL is TLI.getVPExplicitVectorLengthTy().
2564 const SDValue &getOffset() const {
2565 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2566 getOpcode() == ISD::VP_LOAD)
2567 ? 2
2568 : 3);
2569 }
2570 const SDValue &getBasePtr() const {
2571 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2572 getOpcode() == ISD::VP_LOAD)
2573 ? 1
2574 : 2);
2575 }
2576 const SDValue &getMask() const {
2577 switch (getOpcode()) {
2578 default:
2579 llvm_unreachable("Invalid opcode");
2580 case ISD::VP_LOAD:
2581 return getOperand(3);
2582 case ISD::VP_STORE:
2583 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2584 return getOperand(4);
2585 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2586 return getOperand(5);
2587 }
2588 }
2589 const SDValue &getVectorLength() const {
2590 switch (getOpcode()) {
2591 default:
2592 llvm_unreachable("Invalid opcode");
2593 case ISD::VP_LOAD:
2594 return getOperand(4);
2595 case ISD::VP_STORE:
2596 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2597 return getOperand(5);
2598 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2599 return getOperand(6);
2600 }
2601 }
2602
2603 /// Return the addressing mode for this load or store:
2604 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2606 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2607 }
2608
2609 /// Return true if this is a pre/post inc/dec load/store.
2610 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2611
2612 /// Return true if this is NOT a pre/post inc/dec load/store.
2613 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2614
2615 static bool classof(const SDNode *N) {
2616 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2617 N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE ||
2618 N->getOpcode() == ISD::VP_LOAD || N->getOpcode() == ISD::VP_STORE;
2619 }
2620};
2621
2622/// This class is used to represent a VP_LOAD node
2624public:
2625 friend class SelectionDAG;
2626
2627 VPLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2628 ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool isExpanding,
2629 EVT MemVT, MachineMemOperand *MMO)
2630 : VPBaseLoadStoreSDNode(ISD::VP_LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2631 LoadSDNodeBits.ExtTy = ETy;
2632 LoadSDNodeBits.IsExpanding = isExpanding;
2633 }
2634
2636 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2637 }
2638
2639 const SDValue &getBasePtr() const { return getOperand(1); }
2640 const SDValue &getOffset() const { return getOperand(2); }
2641 const SDValue &getMask() const { return getOperand(3); }
2642 const SDValue &getVectorLength() const { return getOperand(4); }
2643
2644 static bool classof(const SDNode *N) {
2645 return N->getOpcode() == ISD::VP_LOAD;
2646 }
2647 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2648};
2649
2650/// This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
2652public:
2653 friend class SelectionDAG;
2654
2655 VPStridedLoadSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2657 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2658 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_LOAD, Order, DL, VTs,
2659 AM, MemVT, MMO) {
2660 LoadSDNodeBits.ExtTy = ETy;
2661 LoadSDNodeBits.IsExpanding = IsExpanding;
2662 }
2663
2665 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2666 }
2667
2668 const SDValue &getBasePtr() const { return getOperand(1); }
2669 const SDValue &getOffset() const { return getOperand(2); }
2670 const SDValue &getStride() const { return getOperand(3); }
2671 const SDValue &getMask() const { return getOperand(4); }
2672 const SDValue &getVectorLength() const { return getOperand(5); }
2673
2674 static bool classof(const SDNode *N) {
2675 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD;
2676 }
2677 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2678};
2679
2680/// This class is used to represent a VP_STORE node
2682public:
2683 friend class SelectionDAG;
2684
2685 VPStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2686 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
2687 EVT MemVT, MachineMemOperand *MMO)
2688 : VPBaseLoadStoreSDNode(ISD::VP_STORE, Order, dl, VTs, AM, MemVT, MMO) {
2689 StoreSDNodeBits.IsTruncating = isTrunc;
2690 StoreSDNodeBits.IsCompressing = isCompressing;
2691 }
2692
2693 /// Return true if this is a truncating store.
2694 /// For integers this is the same as doing a TRUNCATE and storing the result.
2695 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2696 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2697
2698 /// Returns true if the op does a compression to the vector before storing.
2699 /// The node contiguously stores the active elements (integers or floats)
2700 /// in src (those with their respective bit set in writemask k) to unaligned
2701 /// memory at base_addr.
2702 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2703
2704 const SDValue &getValue() const { return getOperand(1); }
2705 const SDValue &getBasePtr() const { return getOperand(2); }
2706 const SDValue &getOffset() const { return getOperand(3); }
2707 const SDValue &getMask() const { return getOperand(4); }
2708 const SDValue &getVectorLength() const { return getOperand(5); }
2709
2710 static bool classof(const SDNode *N) {
2711 return N->getOpcode() == ISD::VP_STORE;
2712 }
2713};
2714
2715/// This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
2717public:
2718 friend class SelectionDAG;
2719
2720 VPStridedStoreSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2721 ISD::MemIndexedMode AM, bool IsTrunc, bool IsCompressing,
2722 EVT MemVT, MachineMemOperand *MMO)
2723 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_STORE, Order, DL,
2724 VTs, AM, MemVT, MMO) {
2725 StoreSDNodeBits.IsTruncating = IsTrunc;
2726 StoreSDNodeBits.IsCompressing = IsCompressing;
2727 }
2728
2729 /// Return true if this is a truncating store.
2730 /// For integers this is the same as doing a TRUNCATE and storing the result.
2731 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2732 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2733
2734 /// Returns true if the op does a compression to the vector before storing.
2735 /// The node contiguously stores the active elements (integers or floats)
2736 /// in src (those with their respective bit set in writemask k) to unaligned
2737 /// memory at base_addr.
2738 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2739
2740 const SDValue &getValue() const { return getOperand(1); }
2741 const SDValue &getBasePtr() const { return getOperand(2); }
2742 const SDValue &getOffset() const { return getOperand(3); }
2743 const SDValue &getStride() const { return getOperand(4); }
2744 const SDValue &getMask() const { return getOperand(5); }
2745 const SDValue &getVectorLength() const { return getOperand(6); }
2746
2747 static bool classof(const SDNode *N) {
2748 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE;
2749 }
2750};
2751
2752/// This base class is used to represent MLOAD and MSTORE nodes
2754public:
2755 friend class SelectionDAG;
2756
2757 MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2758 const DebugLoc &dl, SDVTList VTs,
2759 ISD::MemIndexedMode AM, EVT MemVT,
2761 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2762 LSBaseSDNodeBits.AddressingMode = AM;
2763 assert(getAddressingMode() == AM && "Value truncated");
2764 }
2765
2766 // MaskedLoadSDNode (Chain, ptr, offset, mask, passthru)
2767 // MaskedStoreSDNode (Chain, data, ptr, offset, mask)
2768 // Mask is a vector of i1 elements
2769 const SDValue &getOffset() const {
2770 return getOperand(getOpcode() == ISD::MLOAD ? 2 : 3);
2771 }
2772 const SDValue &getMask() const {
2773 return getOperand(getOpcode() == ISD::MLOAD ? 3 : 4);
2774 }
2775
2776 /// Return the addressing mode for this load or store:
2777 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2779 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2780 }
2781
2782 /// Return true if this is a pre/post inc/dec load/store.
2783 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2784
2785 /// Return true if this is NOT a pre/post inc/dec load/store.
2786 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2787
2788 static bool classof(const SDNode *N) {
2789 return N->getOpcode() == ISD::MLOAD ||
2790 N->getOpcode() == ISD::MSTORE;
2791 }
2792};
2793
2794/// This class is used to represent an MLOAD node
2796public:
2797 friend class SelectionDAG;
2798
2799 MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2801 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2802 : MaskedLoadStoreSDNode(ISD::MLOAD, Order, dl, VTs, AM, MemVT, MMO) {
2803 LoadSDNodeBits.ExtTy = ETy;
2804 LoadSDNodeBits.IsExpanding = IsExpanding;
2805 }
2806
2808 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2809 }
2810
2811 const SDValue &getBasePtr() const { return getOperand(1); }
2812 const SDValue &getOffset() const { return getOperand(2); }
2813 const SDValue &getMask() const { return getOperand(3); }
2814 const SDValue &getPassThru() const { return getOperand(4); }
2815
2816 static bool classof(const SDNode *N) {
2817 return N->getOpcode() == ISD::MLOAD;
2818 }
2819
2820 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2821};
2822
2823/// This class is used to represent an MSTORE node
2825public:
2826 friend class SelectionDAG;
2827
2828 MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2829 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
2830 EVT MemVT, MachineMemOperand *MMO)
2831 : MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, VTs, AM, MemVT, MMO) {
2832 StoreSDNodeBits.IsTruncating = isTrunc;
2833 StoreSDNodeBits.IsCompressing = isCompressing;
2834 }
2835
2836 /// Return true if the op does a truncation before store.
2837 /// For integers this is the same as doing a TRUNCATE and storing the result.
2838 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2839 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2840
2841 /// Returns true if the op does a compression to the vector before storing.
2842 /// The node contiguously stores the active elements (integers or floats)
2843 /// in src (those with their respective bit set in writemask k) to unaligned
2844 /// memory at base_addr.
2845 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2846
2847 const SDValue &getValue() const { return getOperand(1); }
2848 const SDValue &getBasePtr() const { return getOperand(2); }
2849 const SDValue &getOffset() const { return getOperand(3); }
2850 const SDValue &getMask() const { return getOperand(4); }
2851
2852 static bool classof(const SDNode *N) {
2853 return N->getOpcode() == ISD::MSTORE;
2854 }
2855};
2856
2857/// This is a base class used to represent
2858/// VP_GATHER and VP_SCATTER nodes
2859///
2861public:
2862 friend class SelectionDAG;
2863
2864 VPGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
2865 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2867 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2868 LSBaseSDNodeBits.AddressingMode = IndexType;
2869 assert(getIndexType() == IndexType && "Value truncated");
2870 }
2871
2872 /// How is Index applied to BasePtr when computing addresses.
2874 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
2875 }
2876 bool isIndexScaled() const {
2877 return !cast<ConstantSDNode>(getScale())->isOne();
2878 }
2879 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
2880
2881 // In the both nodes address is Op1, mask is Op2:
2882 // VPGatherSDNode (Chain, base, index, scale, mask, vlen)
2883 // VPScatterSDNode (Chain, value, base, index, scale, mask, vlen)
2884 // Mask is a vector of i1 elements
2885 const SDValue &getBasePtr() const {
2886 return getOperand((getOpcode() == ISD::VP_GATHER) ? 1 : 2);
2887 }
2888 const SDValue &getIndex() const {
2889 return getOperand((getOpcode() == ISD::VP_GATHER) ? 2 : 3);
2890 }
2891 const SDValue &getScale() const {
2892 return getOperand((getOpcode() == ISD::VP_GATHER) ? 3 : 4);
2893 }
2894 const SDValue &getMask() const {
2895 return getOperand((getOpcode() == ISD::VP_GATHER) ? 4 : 5);
2896 }
2897 const SDValue &getVectorLength() const {
2898 return getOperand((getOpcode() == ISD::VP_GATHER) ? 5 : 6);
2899 }
2900
2901 static bool classof(const SDNode *N) {
2902 return N->getOpcode() == ISD::VP_GATHER ||
2903 N->getOpcode() == ISD::VP_SCATTER;
2904 }
2905};
2906
2907/// This class is used to represent an VP_GATHER node
2908///
2910public:
2911 friend class SelectionDAG;
2912
2913 VPGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2915 : VPGatherScatterSDNode(ISD::VP_GATHER, Order, dl, VTs, MemVT, MMO,
2916 IndexType) {}
2917
2918 static bool classof(const SDNode *N) {
2919 return N->getOpcode() == ISD::VP_GATHER;
2920 }
2921};
2922
2923/// This class is used to represent an VP_SCATTER node
2924///
2926public:
2927 friend class SelectionDAG;
2928
2929 VPScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2931 : VPGatherScatterSDNode(ISD::VP_SCATTER, Order, dl, VTs, MemVT, MMO,
2932 IndexType) {}
2933
2934 const SDValue &getValue() const { return getOperand(1); }
2935
2936 static bool classof(const SDNode *N) {
2937 return N->getOpcode() == ISD::VP_SCATTER;
2938 }
2939};
2940
2941/// This is a base class used to represent
2942/// MGATHER and MSCATTER nodes
2943///
2945public:
2946 friend class SelectionDAG;
2947
2949 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
2951 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2952 LSBaseSDNodeBits.AddressingMode = IndexType;
2953 assert(getIndexType() == IndexType && "Value truncated");
2954 }
2955
2956 /// How is Index applied to BasePtr when computing addresses.
2958 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
2959 }
2960 bool isIndexScaled() const {
2961 return !cast<ConstantSDNode>(getScale())->isOne();
2962 }
2963 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
2964
2965 // In the both nodes address is Op1, mask is Op2:
2966 // MaskedGatherSDNode (Chain, passthru, mask, base, index, scale)
2967 // MaskedScatterSDNode (Chain, value, mask, base, index, scale)
2968 // Mask is a vector of i1 elements
2969 const SDValue &getBasePtr() const { return getOperand(3); }
2970 const SDValue &getIndex() const { return getOperand(4); }
2971 const SDValue &getMask() const { return getOperand(2); }
2972 const SDValue &getScale() const { return getOperand(5); }
2973
2974 static bool classof(const SDNode *N) {
2975 return N->getOpcode() == ISD::MGATHER || N->getOpcode() == ISD::MSCATTER ||
2976 N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
2977 }
2978};
2979
2980/// This class is used to represent an MGATHER node
2981///
2983public:
2984 friend class SelectionDAG;
2985
2986 MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2987 EVT MemVT, MachineMemOperand *MMO,
2988 ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
2989 : MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, VTs, MemVT, MMO,
2990 IndexType) {
2991 LoadSDNodeBits.ExtTy = ETy;
2992 }
2993
2994 const SDValue &getPassThru() const { return getOperand(1); }
2995
2997 return ISD::LoadExtType(LoadSDNodeBits.ExtTy);
2998 }
2999
3000 static bool classof(const SDNode *N) {
3001 return N->getOpcode() == ISD::MGATHER;
3002 }
3003};
3004
3005/// This class is used to represent an MSCATTER node
3006///
3008public:
3009 friend class SelectionDAG;
3010
3011 MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
3012 EVT MemVT, MachineMemOperand *MMO,
3013 ISD::MemIndexType IndexType, bool IsTrunc)
3014 : MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, VTs, MemVT, MMO,
3015 IndexType) {
3016 StoreSDNodeBits.IsTruncating = IsTrunc;
3017 }
3018
3019 /// Return true if the op does a truncation before store.
3020 /// For integers this is the same as doing a TRUNCATE and storing the result.
3021 /// For floats, it is the same as doing an FP_ROUND and storing the result.
3022 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
3023
3024 const SDValue &getValue() const { return getOperand(1); }
3025
3026 static bool classof(const SDNode *N) {
3027 return N->getOpcode() == ISD::MSCATTER;
3028 }
3029};
3030
3032public:
3033 friend class SelectionDAG;
3034
3035 MaskedHistogramSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
3036 EVT MemVT, MachineMemOperand *MMO,
3037 ISD::MemIndexType IndexType)
3038 : MaskedGatherScatterSDNode(ISD::EXPERIMENTAL_VECTOR_HISTOGRAM, Order, DL,
3039 VTs, MemVT, MMO, IndexType) {}
3040
3042 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3043 }
3044
3045 const SDValue &getBasePtr() const { return getOperand(3); }
3046 const SDValue &getIndex() const { return getOperand(4); }
3047 const SDValue &getMask() const { return getOperand(2); }
3048 const SDValue &getScale() const { return getOperand(5); }
3049 const SDValue &getInc() const { return getOperand(1); }
3050 const SDValue &getIntID() const { return getOperand(6); }
3051
3052 static bool classof(const SDNode *N) {
3053 return N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
3054 }
3055};
3056
3058public:
3059 friend class SelectionDAG;
3060
3061 FPStateAccessSDNode(unsigned NodeTy, unsigned Order, const DebugLoc &dl,
3062 SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
3063 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3064 assert((NodeTy == ISD::GET_FPENV_MEM || NodeTy == ISD::SET_FPENV_MEM) &&
3065 "Expected FP state access node");
3066 }
3067
3068 static bool classof(const SDNode *N) {
3069 return N->getOpcode() == ISD::GET_FPENV_MEM ||
3070 N->getOpcode() == ISD::SET_FPENV_MEM;
3071 }
3072};
3073
3074/// An SDNode that represents everything that will be needed
3075/// to construct a MachineInstr. These nodes are created during the
3076/// instruction selection proper phase.
3077///
3078/// Note that the only supported way to set the `memoperands` is by calling the
3079/// `SelectionDAG::setNodeMemRefs` function as the memory management happens
3080/// inside the DAG rather than in the node.
3081class MachineSDNode : public SDNode {
3082private:
3083 friend class SelectionDAG;
3084
3085 MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, SDVTList VTs)
3086 : SDNode(Opc, Order, DL, VTs) {}
3087
3088 // We use a pointer union between a single `MachineMemOperand` pointer and
3089 // a pointer to an array of `MachineMemOperand` pointers. This is null when
3090 // the number of these is zero, the single pointer variant used when the
3091 // number is one, and the array is used for larger numbers.
3092 //
3093 // The array is allocated via the `SelectionDAG`'s allocator and so will
3094 // always live until the DAG is cleaned up and doesn't require ownership here.
3095 //
3096 // We can't use something simpler like `TinyPtrVector` here because `SDNode`
3097 // subclasses aren't managed in a conforming C++ manner. See the comments on
3098 // `SelectionDAG::MorphNodeTo` which details what all goes on, but the
3099 // constraint here is that these don't manage memory with their constructor or
3100 // destructor and can be initialized to a good state even if they start off
3101 // uninitialized.
3103
3104 // Note that this could be folded into the above `MemRefs` member if doing so
3105 // is advantageous at some point. We don't need to store this in most cases.
3106 // However, at the moment this doesn't appear to make the allocation any
3107 // smaller and makes the code somewhat simpler to read.
3108 int NumMemRefs = 0;
3109
3110public:
3112
3114 // Special case the common cases.
3115 if (NumMemRefs == 0)
3116 return {};
3117 if (NumMemRefs == 1)
3118 return ArrayRef(MemRefs.getAddrOfPtr1(), 1);
3119
3120 // Otherwise we have an actual array.
3121 return ArrayRef(cast<MachineMemOperand **>(MemRefs), NumMemRefs);
3122 }
3123 mmo_iterator memoperands_begin() const { return memoperands().begin(); }
3124 mmo_iterator memoperands_end() const { return memoperands().end(); }
3125 bool memoperands_empty() const { return memoperands().empty(); }
3126
3127 /// Clear out the memory reference descriptor list.
3129 MemRefs = nullptr;
3130 NumMemRefs = 0;
3131 }
3132
3133 static bool classof(const SDNode *N) {
3134 return N->isMachineOpcode();
3135 }
3136};
3137
3138/// An SDNode that records if a register contains a value that is guaranteed to
3139/// be aligned accordingly.
3141 Align Alignment;
3142
3143public:
3144 AssertAlignSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, Align A)
3145 : SDNode(ISD::AssertAlign, Order, DL, VTs), Alignment(A) {}
3146
3147 Align getAlign() const { return Alignment; }
3148
3149 static bool classof(const SDNode *N) {
3150 return N->getOpcode() == ISD::AssertAlign;
3151 }
3152};
3153
3155 const SDNode *Node;
3156 unsigned Operand;
3157
3158 SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
3159
3160public:
3161 using iterator_category = std::forward_iterator_tag;
3163 using difference_type = std::ptrdiff_t;
3166
3167 bool operator==(const SDNodeIterator& x) const {
3168 return Operand == x.Operand;
3169 }
3170 bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
3171
3173 return Node->getOperand(Operand).getNode();
3174 }
3175 pointer operator->() const { return operator*(); }
3176
3177 SDNodeIterator& operator++() { // Preincrement
3178 ++Operand;
3179 return *this;
3180 }
3181 SDNodeIterator operator++(int) { // Postincrement
3182 SDNodeIterator tmp = *this; ++*this; return tmp;
3183 }
3185 assert(Node == Other.Node &&
3186 "Cannot compare iterators of two different nodes!");
3187 return Operand - Other.Operand;
3188 }
3189
3190 static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); }
3191 static SDNodeIterator end (const SDNode *N) {
3192 return SDNodeIterator(N, N->getNumOperands());
3193 }
3194
3195 unsigned getOperand() const { return Operand; }
3196 const SDNode *getNode() const { return Node; }
3197};
3198
3199template <> struct GraphTraits<SDNode*> {
3200 using NodeRef = SDNode *;
3202
3203 static NodeRef getEntryNode(SDNode *N) { return N; }
3204
3206 return SDNodeIterator::begin(N);
3207 }
3208
3210 return SDNodeIterator::end(N);
3211 }
3212};
3213
3214/// A representation of the largest SDNode, for use in sizeof().
3215///
3216/// This needs to be a union because the largest node differs on 32 bit systems
3217/// with 4 and 8 byte pointer alignment, respectively.
3222
3223/// The SDNode class with the greatest alignment requirement.
3225
3226namespace ISD {
3227
3228 /// Returns true if the specified node is a non-extending and unindexed load.
3229 inline bool isNormalLoad(const SDNode *N) {
3230 auto *Ld = dyn_cast<LoadSDNode>(N);
3231 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
3232 Ld->getAddressingMode() == ISD::UNINDEXED;
3233 }
3234
3235 /// Returns true if the specified node is a non-extending load.
3236 inline bool isNON_EXTLoad(const SDNode *N) {
3237 auto *Ld = dyn_cast<LoadSDNode>(N);
3238 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD;
3239 }
3240
3241 /// Returns true if the specified node is a EXTLOAD.
3242 inline bool isEXTLoad(const SDNode *N) {
3243 auto *Ld = dyn_cast<LoadSDNode>(N);
3244 return Ld && Ld->getExtensionType() == ISD::EXTLOAD;
3245 }
3246
3247 /// Returns true if the specified node is a SEXTLOAD.
3248 inline bool isSEXTLoad(const SDNode *N) {
3249 auto *Ld = dyn_cast<LoadSDNode>(N);
3250 return Ld && Ld->getExtensionType() == ISD::SEXTLOAD;
3251 }
3252
3253 /// Returns true if the specified node is a ZEXTLOAD.
3254 inline bool isZEXTLoad(const SDNode *N) {
3255 auto *Ld = dyn_cast<LoadSDNode>(N);
3256 return Ld && Ld->getExtensionType() == ISD::ZEXTLOAD;
3257 }
3258
3259 /// Returns true if the specified node is an unindexed load.
3260 inline bool isUNINDEXEDLoad(const SDNode *N) {
3261 auto *Ld = dyn_cast<LoadSDNode>(N);
3262 return Ld && Ld->getAddressingMode() == ISD::UNINDEXED;
3263 }
3264
3265 /// Returns true if the specified node is a non-truncating
3266 /// and unindexed store.
3267 inline bool isNormalStore(const SDNode *N) {
3268 auto *St = dyn_cast<StoreSDNode>(N);
3269 return St && !St->isTruncatingStore() &&
3270 St->getAddressingMode() == ISD::UNINDEXED;
3271 }
3272
3273 /// Returns true if the specified node is an unindexed store.
3274 inline bool isUNINDEXEDStore(const SDNode *N) {
3275 auto *St = dyn_cast<StoreSDNode>(N);
3276 return St && St->getAddressingMode() == ISD::UNINDEXED;
3277 }
3278
3279 /// Attempt to match a unary predicate against a scalar/splat constant or
3280 /// every element of a constant BUILD_VECTOR.
3281 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
3282 template <typename ConstNodeType>
3284 std::function<bool(ConstNodeType *)> Match,
3285 bool AllowUndefs = false);
3286
3287 /// Hook for matching ConstantSDNode predicate
3289 std::function<bool(ConstantSDNode *)> Match,
3290 bool AllowUndefs = false) {
3291 return matchUnaryPredicateImpl<ConstantSDNode>(Op, Match, AllowUndefs);
3292 }
3293
3294 /// Hook for matching ConstantFPSDNode predicate
3295 inline bool
3297 std::function<bool(ConstantFPSDNode *)> Match,
3298 bool AllowUndefs = false) {
3299 return matchUnaryPredicateImpl<ConstantFPSDNode>(Op, Match, AllowUndefs);
3300 }
3301
3302 /// Attempt to match a binary predicate against a pair of scalar/splat
3303 /// constants or every element of a pair of constant BUILD_VECTORs.
3304 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
3305 /// If AllowTypeMismatch is true then RetType + ArgTypes don't need to match.
3308 std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
3309 bool AllowUndefs = false, bool AllowTypeMismatch = false);
3310
3311 /// Returns true if the specified value is the overflow result from one
3312 /// of the overflow intrinsic nodes.
3314 unsigned Opc = Op.getOpcode();
3315 return (Op.getResNo() == 1 &&
3316 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
3317 Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO));
3318 }
3319
3320} // end namespace ISD
3321
3322} // end namespace llvm
3323
3324#endif // LLVM_CODEGEN_SELECTIONDAGNODES_H
aarch64 promote const
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
AMDGPU Kernel Attributes
This file declares a class to represent arbitrary precision floating point values and provide a varie...
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
This file implements the BitVector class.
#define LLVM_DECLARE_ENUM_AS_BITMASK(Enum, LargestValue)
LLVM_DECLARE_ENUM_AS_BITMASK can be used to declare an enum type as a bit set, so that bitwise operat...
Definition: BitmaskEnum.h:66
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
RelocType Type
Definition: COFFYAML.cpp:410
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint32_t Index
uint64_t Size
uint64_t Offset
Definition: ELF_riscv.cpp:478
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
This file defines a hash set that can be used to remove duplication of nodes in a graph.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
#define op(i)
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
Load MIR Sample Profile
unsigned Reg
This file contains the declarations for metadata subclasses.
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
#define END_TWO_BYTE_PACK()
#define BEGIN_TWO_BYTE_PACK()
static cl::opt< unsigned > MaxSteps("has-predecessor-max-steps", cl::Hidden, cl::init(8192), cl::desc("DAG combiner limit number of steps when searching DAG " "for predecessor nodes"))
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Value * RHS
Value * LHS
DEMANGLE_DUMP_METHOD void dump() const
Class for arbitrary precision integers.
Definition: APInt.h:78
unsigned getSrcAddressSpace() const
AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, unsigned SrcAS, unsigned DestAS)
unsigned getDestAddressSpace() const
static bool classof(const SDNode *N)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
An SDNode that records if a register contains a value that is guaranteed to be aligned accordingly.
static bool classof(const SDNode *N)
AssertAlignSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, Align A)
This is an SDNode representing atomic operations.
void setExtensionType(ISD::LoadExtType ETy)
static bool classof(const SDNode *N)
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
AtomicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTL, EVT MemVT, MachineMemOperand *MMO)
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
bool isCompareAndSwap() const
Returns true if this SDNode represents cmpxchg atomic operation, false otherwise.
const SDValue & getVal() const
MachineBasicBlock * getBasicBlock() const
static bool classof(const SDNode *N)
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
static bool classof(const SDNode *N)
unsigned getTargetFlags() const
const BlockAddress * getBlockAddress() const
The address of a basic block.
Definition: Constants.h:893
A "pseudo-class" with methods for operating on BUILD_VECTORs.
bool getConstantRawBits(bool IsLittleEndian, unsigned DstEltSizeInBits, SmallVectorImpl< APInt > &RawBitElements, BitVector &UndefElements) const
Extract the raw bit data from a build vector of Undef, Constant or ConstantFP node elements.
static void recastRawBits(bool IsLittleEndian, unsigned DstEltSizeInBits, SmallVectorImpl< APInt > &DstBitElements, ArrayRef< APInt > SrcBitElements, BitVector &DstUndefElements, const BitVector &SrcUndefElements)
Recast bit data SrcBitElements to DstEltSizeInBits wide elements.
bool getRepeatedSequence(const APInt &DemandedElts, SmallVectorImpl< SDValue > &Sequence, BitVector *UndefElements=nullptr) const
Find the shortest repeating sequence of values in the build vector.
ConstantFPSDNode * getConstantFPSplatNode(const APInt &DemandedElts, BitVector *UndefElements=nullptr) const
Returns the demanded splatted constant FP or null if this is not a constant FP splat.
std::optional< std::pair< APInt, APInt > > isConstantSequence() const
If this BuildVector is constant and represents the numerical series "<a, a+n, a+2n,...
SDValue getSplatValue(const APInt &DemandedElts, BitVector *UndefElements=nullptr) const
Returns the demanded splatted value or a null value if this is not a splat.
bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef, unsigned &SplatBitSize, bool &HasAnyUndefs, unsigned MinSplatBits=0, bool isBigEndian=false) const
Check if this is a constant splat, and if so, find the smallest element size that splats the vector.
ConstantSDNode * getConstantSplatNode(const APInt &DemandedElts, BitVector *UndefElements=nullptr) const
Returns the demanded splatted constant or null if this is not a constant splat.
int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements, uint32_t BitWidth) const
If this is a constant FP splat and the splatted constant FP is an exact power or 2,...
static bool classof(const SDNode *N)
ISD::CondCode get() const
static bool classof(const SDNode *N)
static bool isValueValidForType(EVT VT, const APFloat &Val)
const APFloat & getValueAPF() const
bool isNaN() const
Return true if the value is a NaN.
const ConstantFP * getConstantFPValue() const
bool isExactlyValue(double V) const
We don't rely on operator== working on double values, as it returns true for things that are clearly ...
bool isNegative() const
Return true if the value is negative.
bool isInfinity() const
Return true if the value is an infinity.
static bool classof(const SDNode *N)
bool isZero() const
Return true if the value is positive or negative zero.
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:271
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
static bool classof(const SDNode *N)
MachineConstantPoolValue * getMachineCPVal() const
bool isMachineConstantPoolEntry() const
MachineConstantPoolValue * MachineCPVal
const Constant * getConstVal() const
unsigned getTargetFlags() const
MaybeAlign getMaybeAlignValue() const
uint64_t getLimitedValue(uint64_t Limit=UINT64_MAX)
const ConstantInt * getConstantIntValue() const
uint64_t getZExtValue() const
const APInt & getAPIntValue() const
int64_t getSExtValue() const
static bool classof(const SDNode *N)
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:33
bool hasTrivialDestructor() const
Check whether this has a trivial destructor.
Definition: DebugLoc.h:69
const char * getSymbol() const
static bool classof(const SDNode *N)
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition: Operator.h:205
bool hasAllowReassoc() const
Test if this operation may be simplified with reassociative transforms.
Definition: Operator.h:302
bool hasNoNaNs() const
Test if this operation's arguments and results are assumed not-NaN.
Definition: Operator.h:307
bool hasAllowReciprocal() const
Test if this operation can use reciprocal multiply instead of division.
Definition: Operator.h:322
bool hasNoSignedZeros() const
Test if this operation can ignore the sign of zero.
Definition: Operator.h:317
bool hasAllowContract() const
Test if this operation can be floating-point contracted (FMA).
Definition: Operator.h:327
bool hasNoInfs() const
Test if this operation's arguments and results are assumed not-infinite.
Definition: Operator.h:312
bool hasApproxFunc() const
Test if this operation allows approximations of math library functions or intrinsics.
Definition: Operator.h:333
static bool classof(const SDNode *N)
FPStateAccessSDNode(unsigned NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
Node - This class is used to maintain the singly linked bucket list in a folding set.
Definition: FoldingSet.h:138
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:327
static bool classof(const SDNode *N)
unsigned getAddressSpace() const
static bool classof(const SDNode *N)
const GlobalValue * getGlobal() const
This class is used to form a handle around another node that is persistent and is updated across invo...
const SDValue & getValue() const
static bool classof(const SDNode *N)
unsigned getTargetFlags() const
Base class for LoadSDNode and StoreSDNode.
LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, MachineMemOperand *MMO)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
static bool classof(const SDNode *N)
MCSymbol * getLabel() const
static bool classof(const SDNode *N)
This SDNode is used for LIFETIME_START/LIFETIME_END values, which indicate the offet and size that ar...
int64_t getFrameIndex() const
static bool classof(const SDNode *N)
int64_t getOffset() const
This class is used to represent ISD::LOAD nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
static bool classof(const SDNode *N)
MCSymbol * getMCSymbol() const
static bool classof(const SDNode *N)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
static bool classof(const SDNode *N)
const MDNode * getMD() const
Metadata node.
Definition: Metadata.h:1069
Machine Value Type.
Abstract base class for all machine specific constantpool value subclasses.
A description of a memory reference used in the backend.
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
bool isUnordered() const
Returns true if this memory operation doesn't have any ordering constraints other than normal aliasin...
const MDNode * getRanges() const
Return the range tag for the memory reference.
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
void refineAlignment(const MachineMemOperand *MMO)
Update this MachineMemOperand to reflect the alignment of MMO, if it has a greater alignment.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
AtomicOrdering getMergedOrdering() const
Return a single atomic ordering that is at least as strong as both the success and failure orderings ...
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
const MachinePointerInfo & getPointerInfo() const
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
Align getBaseAlign() const
Return the minimum known alignment in bytes of the base address, without the offset.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
An SDNode that represents everything that will be needed to construct a MachineInstr.
ArrayRef< MachineMemOperand * > memoperands() const
bool memoperands_empty() const
void clearMemRefs()
Clear out the memory reference descriptor list.
mmo_iterator memoperands_begin() const
static bool classof(const SDNode *N)
mmo_iterator memoperands_end() const
This class is used to represent an MGATHER node.
static bool classof(const SDNode *N)
MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
const SDValue & getPassThru() const
ISD::LoadExtType getExtensionType() const
This is a base class used to represent MGATHER and MSCATTER nodes.
const SDValue & getIndex() const
const SDValue & getScale() const
static bool classof(const SDNode *N)
MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getBasePtr() const
const SDValue & getMask() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
MaskedHistogramSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getScale() const
static bool classof(const SDNode *N)
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
This class is used to represent an MLOAD node.
MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
static bool classof(const SDNode *N)
const SDValue & getOffset() const
This base class is used to represent MLOAD and MSTORE nodes.
const SDValue & getMask() const
MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, MachineMemOperand *MMO)
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
static bool classof(const SDNode *N)
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
This class is used to represent an MSCATTER node.
MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType, bool IsTrunc)
const SDValue & getValue() const
static bool classof(const SDNode *N)
bool isTruncatingStore() const
Return true if the op does a truncation before store.
This class is used to represent an MSTORE node.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
static bool classof(const SDNode *N)
This SDNode is used for target intrinsics that touch memory and need an associated MachineMemOperand.
MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemoryVT, MachineMemOperand *MMO)
static bool classof(const SDNode *N)
This is an abstract virtual class for memory operations.
MachineMemOperand * MMO
Memory reference information.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
Align getAlign() const
bool isVolatile() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
Align getOriginalAlign() const
Returns alignment and volatility of the memory access.
int64_t getSrcValueOffset() const
bool readMem() const
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
void refineAlignment(const MachineMemOperand *NewMMO)
Update this MemSDNode's MachineMemOperand information to reflect the alignment of NewMMO,...
const MachinePointerInfo & getPointerInfo() const
AtomicOrdering getMergedOrdering() const
Return a single atomic ordering that is at least as strong as both the success and failure orderings ...
const SDValue & getChain() const
bool isNonTemporal() const
bool isInvariant() const
bool writeMem() const
bool isDereferenceable() const
bool isUnordered() const
Returns true if the memory operation doesn't imply any ordering constraints on surrounding memory ope...
bool isAtomic() const
Return true if the memory operation ordering is Unordered or higher.
static bool classof(const SDNode *N)
unsigned getRawSubclassData() const
Return the SubclassData value, without HasDebugValue.
EVT getMemoryVT() const
Return the type of the in-memory value.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:310
First const * getAddrOfPtr1() const
If the union is set to the first pointer type get an address pointing to it.
Definition: PointerUnion.h:168
This SDNode is used for PSEUDO_PROBE values, which are the function guid and the index of the basic b...
static bool classof(const SDNode *N)
uint32_t getAttributes() const
const uint32_t * getRegMask() const
static bool classof(const SDNode *N)
static bool classof(const SDNode *N)
Register getReg() const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
const DebugLoc & getDebugLoc() const
unsigned getIROrder() const
SDLoc(const SDValue V)
SDLoc()=default
SDLoc(const SDNode *N)
SDLoc(const Instruction *I, int Order)
pointer operator->() const
static SDNodeIterator end(const SDNode *N)
size_t operator-(SDNodeIterator Other) const
SDNodeIterator operator++(int)
std::ptrdiff_t difference_type
std::forward_iterator_tag iterator_category
unsigned getOperand() const
pointer operator*() const
SDNodeIterator & operator++()
bool operator==(const SDNodeIterator &x) const
const SDNode * getNode() const
static SDNodeIterator begin(const SDNode *N)
bool operator!=(const SDNodeIterator &x) const
This class provides iterator support for SDUse operands that use a specific SDNode.
bool operator!=(const use_iterator &x) const
use_iterator & operator=(const use_iterator &)=default
std::forward_iterator_tag iterator_category
bool operator==(const use_iterator &x) const
SDUse & operator*() const
Retrieve a pointer to the current user node.
use_iterator(const use_iterator &I)=default
std::forward_iterator_tag iterator_category
bool operator!=(const user_iterator &x) const
bool operator==(const user_iterator &x) const
Represents one node in the SelectionDAG.
void setDebugLoc(DebugLoc dl)
Set source location info.
uint32_t getCFIType() const
void setIROrder(unsigned Order)
Set the node ordering.
bool isStrictFPOpcode()
Test if this node is a strict floating point pseudo-op.
ArrayRef< SDUse > ops() const
char RawSDNodeBits[sizeof(uint16_t)]
const APInt & getAsAPIntVal() const
Helper method returns the APInt value of a ConstantSDNode.
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode.
void dumprFull(const SelectionDAG *G=nullptr) const
printrFull to dbgs().
int getNodeId() const
Return the unique node id.
void dump() const
Dump this node, for debugging.
iterator_range< value_iterator > values() const
iterator_range< use_iterator > uses() const
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
SDNode * getGluedUser() const
If this node has a glue value with a user, return the user (there is at most one).
bool isDivergent() const
bool hasOneUse() const
Return true if there is exactly one use of this node.
bool isOnlyUserOf(const SDNode *N) const
Return true if this node is the only use of N.
static const char * getIndexedModeName(ISD::MemIndexedMode AM)
iterator_range< value_op_iterator > op_values() const
unsigned getIROrder() const
Return the node ordering.
LoadSDNodeBitfields LoadSDNodeBits
void dropFlags(unsigned Mask)
static constexpr size_t getMaxNumOperands()
Return the maximum number of operands that a SDNode can hold.
int getCombinerWorklistIndex() const
Get worklist index for DAGCombiner.
value_iterator value_end() const
void setHasDebugValue(bool b)
LSBaseSDNodeBitfields LSBaseSDNodeBits
iterator_range< use_iterator > uses()
MemSDNodeBitfields MemSDNodeBits
bool getHasDebugValue() const
void dumpr() const
Dump (recursively) this node and its use-def subgraph.
SDNodeFlags getFlags() const
void setNodeId(int Id)
Set unique node id.
std::string getOperationName(const SelectionDAG *G=nullptr) const
Return the opcode of this operation for printing.
void printrFull(raw_ostream &O, const SelectionDAG *G=nullptr) const
Print a SelectionDAG node and all children down to the leaves.
size_t use_size() const
Return the number of uses of this node.
void intersectFlagsWith(const SDNodeFlags Flags)
Clear any flags in this node that aren't also set in Flags.
void printr(raw_ostream &OS, const SelectionDAG *G=nullptr) const
StoreSDNodeBitfields StoreSDNodeBits
static SDVTList getSDVTList(MVT VT)
TypeSize getValueSizeInBits(unsigned ResNo) const
Returns MVT::getSizeInBits(getValueType(ResNo)).
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
static bool hasPredecessorHelper(const SDNode *N, SmallPtrSetImpl< const SDNode * > &Visited, SmallVectorImpl< const SDNode * > &Worklist, unsigned int MaxSteps=0, bool TopologicalPrune=false)
Returns true if N is a predecessor of any node in Worklist.
uint64_t getAsZExtVal() const
Helper method returns the zero-extended integer value of a ConstantSDNode.
bool use_empty() const
Return true if there are no uses of this node.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
unsigned getNumOperands() const
Return the number of values used by this operation.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
SDVTList getVTList() const
const SDValue & getOperand(unsigned Num) const
bool isMemIntrinsic() const
Test if this node is a memory intrinsic (with valid pointer information).
void setCombinerWorklistIndex(int Index)
Set worklist index for DAGCombiner.
uint64_t getConstantOperandVal(unsigned Num) const
Helper method returns the integer value of a ConstantSDNode operand.
static bool areOnlyUsersOf(ArrayRef< const SDNode * > Nodes, const SDNode *N)
Return true if all the users of N are contained in Nodes.
bool isTargetStrictFPOpcode() const
Test if this node has a target-specific opcode that may raise FP exceptions (in the <target>ISD names...
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
bool isOperandOf(const SDNode *N) const
Return true if this node is an operand of N.
void print(raw_ostream &OS, const SelectionDAG *G=nullptr) const
const DebugLoc & getDebugLoc() const
Return the source location info.
void printrWithDepth(raw_ostream &O, const SelectionDAG *G=nullptr, unsigned depth=100) const
Print a SelectionDAG node and children up to depth "depth." The given SelectionDAG allows target-spec...
const APInt & getConstantOperandAPInt(unsigned Num) const
Helper method returns the APInt of a ConstantSDNode operand.
uint16_t PersistentId
Unique and persistent id per SDNode in the DAG.
void dumprWithDepth(const SelectionDAG *G=nullptr, unsigned depth=100) const
printrWithDepth to dbgs().
static user_iterator user_end()
bool isPredecessorOf(const SDNode *N) const
Return true if this node is a predecessor of N.
bool hasPredecessor(const SDNode *N) const
Return true if N is a predecessor of this node.
void addUse(SDUse &U)
This method should only be used by the SDUse class.
bool hasAnyUseOfValue(unsigned Value) const
Return true if there are any use of the indicated value.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void print_details(raw_ostream &OS, const SelectionDAG *G) const
bool isTargetMemoryOpcode() const
Test if this node has a target-specific memory-referencing opcode (in the <target>ISD namespace and g...
void setCFIType(uint32_t Type)
bool isUndef() const
Return true if the type of the node type undefined.
void print_types(raw_ostream &OS, const SelectionDAG *G) const
iterator_range< user_iterator > users()
iterator_range< user_iterator > users() const
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const
Return true if there are exactly NUSES uses of the indicated value.
bool isVPOpcode() const
Test if this node is a vector predication operation.
bool hasPoisonGeneratingFlags() const
void setFlags(SDNodeFlags NewFlags)
user_iterator user_begin() const
Provide iteration support to walk over all users of an SDNode.
SDNode * getGluedNode() const
If this node has a glue operand, return the node to which the glue operand points.
bool isTargetOpcode() const
Test if this node has a target-specific opcode (in the <target>ISD namespace).
op_iterator op_end() const
ConstantSDNodeBitfields ConstantSDNodeBits
value_iterator value_begin() const
op_iterator op_begin() const
static use_iterator use_end()
void DropOperands()
Release the operands and set this node to have zero operands.
SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs)
Create an SDNode.
SDNodeBitfields SDNodeBits
Represents a use of a SDNode.
const SDNode * getUser() const
SDUse & operator=(const SDUse &)=delete
EVT getValueType() const
Convenience function for get().getValueType().
const SDValue & get() const
If implicit conversion to SDValue doesn't work, the get() method returns the SDValue.
SDUse * getNext() const
Get the next SDUse in the use list.
SDNode * getNode() const
Convenience function for get().getNode().
bool operator!=(const SDValue &V) const
Convenience function for get().operator!=.
SDUse()=default
SDUse(const SDUse &U)=delete
unsigned getResNo() const
Convenience function for get().getResNo().
bool operator==(const SDValue &V) const
Convenience function for get().operator==.
unsigned getOperandNo() const
Return the operand # of this use in its user.
bool operator<(const SDValue &V) const
Convenience function for get().operator<.
SDNode * getUser()
This returns the SDNode that contains this Use.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
bool isUndef() const
SDNode * getNode() const
get the SDNode which holds the desired result
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
bool isOperandOf(const SDNode *N) const
Return true if this node is an operand of N.
SDValue()=default
bool isTargetMemoryOpcode() const
bool reachesChainWithoutSideEffects(SDValue Dest, unsigned Depth=2) const
Return true if this operand (which must be a chain) reaches the specified operand without crossing an...
bool operator!=(const SDValue &O) const
SDValue getValue(unsigned R) const
void dump() const
EVT getValueType() const
Return the ValueType of the referenced return value.
bool isTargetOpcode() const
bool isMachineOpcode() const
TypeSize getValueSizeInBits() const
Returns the size of the value in bits.
const DebugLoc & getDebugLoc() const
SDNode * operator->() const
bool operator==(const SDValue &O) const
const SDValue & getOperand(unsigned i) const
bool use_empty() const
Return true if there are no nodes using value ResNo of Node.
bool operator<(const SDValue &O) const
const APInt & getConstantOperandAPInt(unsigned i) const
uint64_t getScalarValueSizeInBits() const
unsigned getResNo() const
get the index which selects a specific result in the SDNode
uint64_t getConstantOperandVal(unsigned i) const
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
void setNode(SDNode *N)
set the SDNode
unsigned getMachineOpcode() const
unsigned getOpcode() const
void dumpr() const
unsigned getNumOperands() const
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:228
This SDNode is used to implement the code generator support for the llvm IR shufflevector instruction...
static bool isSplatMask(const int *Mask, EVT VT)
int getMaskElt(unsigned Idx) const
ShuffleVectorSDNode(SDVTList VTs, unsigned Order, const DebugLoc &dl, const int *M)
ArrayRef< int > getMask() const
static void commuteMask(MutableArrayRef< int > Mask)
Change values in a shuffle permute mask assuming the two vector operands have swapped position.
static bool classof(const SDNode *N)
size_type size() const
Definition: SmallPtrSet.h:94
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:363
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:452
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
bool empty() const
Definition: SmallVector.h:81
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:683
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
An SDNode that holds an arbitrary LLVM IR Value.
const Value * getValue() const
Return the contained Value.
static bool classof(const SDNode *N)
This class is used to represent ISD::STORE nodes.
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
void setTruncatingStore(bool Truncating)
static bool classof(const SDNode *N)
Completely target-dependent object reference.
TargetIndexSDNode(int Idx, SDVTList VTs, int64_t Ofs, unsigned TF)
static bool classof(const SDNode *N)
unsigned getTargetFlags() const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
This base class is used to represent VP_LOAD, VP_STORE, EXPERIMENTAL_VP_STRIDED_LOAD and EXPERIMENTAL...
const SDValue & getMask() const
static bool classof(const SDNode *N)
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
VPBaseLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &DL, SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getOffset() const
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getVectorLength() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
const SDValue & getBasePtr() const
This class is used to represent an VP_GATHER node.
VPGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
static bool classof(const SDNode *N)
This is a base class used to represent VP_GATHER and VP_SCATTER nodes.
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
VPGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getBasePtr() const
static bool classof(const SDNode *N)
const SDValue & getMask() const
This class is used to represent a VP_LOAD node.
const SDValue & getOffset() const
const SDValue & getVectorLength() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
VPLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool isExpanding, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getBasePtr() const
static bool classof(const SDNode *N)
bool isExpandingLoad() const
This class is used to represent an VP_SCATTER node.
static bool classof(const SDNode *N)
VPScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getValue() const
This class is used to represent a VP_STORE node.
const SDValue & getMask() const
VPStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing, EVT MemVT, MachineMemOperand *MMO)
static bool classof(const SDNode *N)
const SDValue & getVectorLength() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getBasePtr() const
const SDValue & getValue() const
This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
static bool classof(const SDNode *N)
const SDValue & getBasePtr() const
VPStridedLoadSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
VPStridedStoreSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, ISD::MemIndexedMode AM, bool IsTrunc, bool IsCompressing, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getOffset() const
const SDValue & getVectorLength() const
static bool classof(const SDNode *N)
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
This class is used to represent EVT's, which are used to parameterize some operations.
static bool classof(const SDNode *N)
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
CRTP base class for adapting an iterator to a different type.
Definition: iterator.h:237
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This file defines the ilist_node class template, which is a convenient base class for creating classe...
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define UINT64_MAX
Definition: DataTypes.h:77
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition: ISDOpcodes.h:40
@ TargetConstantPool
Definition: ISDOpcodes.h:174
@ MDNODE_SDNODE
MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to reference metadata in the IR.
Definition: ISDOpcodes.h:1242
@ ATOMIC_LOAD_FMAX
Definition: ISDOpcodes.h:1347
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
Definition: ISDOpcodes.h:1360
@ ATOMIC_LOAD_NAND
Definition: ISDOpcodes.h:1340
@ TargetBlockAddress
Definition: ISDOpcodes.h:176
@ ConstantFP
Definition: ISDOpcodes.h:77
@ ATOMIC_LOAD_MAX
Definition: ISDOpcodes.h:1342
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
Definition: ISDOpcodes.h:1312
@ ATOMIC_LOAD_UMIN
Definition: ISDOpcodes.h:1343
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1102
@ ATOMIC_LOAD_USUB_COND
Definition: ISDOpcodes.h:1351
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
Definition: ISDOpcodes.h:1325
@ ATOMIC_LOAD_OR
Definition: ISDOpcodes.h:1338
@ ATOMIC_LOAD_XOR
Definition: ISDOpcodes.h:1339
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
Definition: ISDOpcodes.h:1490
@ ATOMIC_LOAD_FADD
Definition: ISDOpcodes.h:1345
@ GlobalTLSAddress
Definition: ISDOpcodes.h:79
@ SRCVALUE
SRCVALUE - This is a node type that holds a Value* that is used to make reference to a value in the L...
Definition: ISDOpcodes.h:1238
@ FrameIndex
Definition: ISDOpcodes.h:80
@ EH_LABEL
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
Definition: ISDOpcodes.h:1173
@ ATOMIC_LOAD_USUB_SAT
Definition: ISDOpcodes.h:1352
@ ANNOTATION_LABEL
ANNOTATION_LABEL - Represents a mid basic block label used by annotations.
Definition: ISDOpcodes.h:1179
@ TargetExternalSymbol
Definition: ISDOpcodes.h:175
@ TargetJumpTable
Definition: ISDOpcodes.h:173
@ TargetIndex
TargetIndex - Like a constant pool entry, but with completely target-dependent semantics.
Definition: ISDOpcodes.h:183
@ ATOMIC_LOAD_FSUB
Definition: ISDOpcodes.h:1346
@ SSUBO
Same for subtraction.
Definition: ISDOpcodes.h:334
@ ATOMIC_LOAD_MIN
Definition: ISDOpcodes.h:1341
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
Definition: ISDOpcodes.h:1308
@ UNDEF
UNDEF - An undefined node.
Definition: ISDOpcodes.h:218
@ RegisterMask
Definition: ISDOpcodes.h:75
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
Definition: ISDOpcodes.h:68
@ ATOMIC_LOAD_FMIN
Definition: ISDOpcodes.h:1348
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition: ISDOpcodes.h:330
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition: ISDOpcodes.h:170
@ STRICT_FP_TO_FP16
Definition: ISDOpcodes.h:967
@ STRICT_FP16_TO_FP
Definition: ISDOpcodes.h:966
@ ATOMIC_LOAD_CLR
Definition: ISDOpcodes.h:1337
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition: ISDOpcodes.h:615
@ ATOMIC_LOAD_AND
Definition: ISDOpcodes.h:1336
@ TargetConstantFP
Definition: ISDOpcodes.h:165
@ ATOMIC_CMP_SWAP
Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap) For double-word atomic operations: ValLo,...
Definition: ISDOpcodes.h:1319
@ ATOMIC_LOAD_UMAX
Definition: ISDOpcodes.h:1344
@ SMULO
Same for multiplication.
Definition: ISDOpcodes.h:338
@ TargetFrameIndex
Definition: ISDOpcodes.h:172
@ ConstantPool
Definition: ISDOpcodes.h:82
@ LIFETIME_START
This corresponds to the llvm.lifetime.
Definition: ISDOpcodes.h:1377
@ MGATHER
Masked gather and scatter - load and store operations for a vector of random addresses with additiona...
Definition: ISDOpcodes.h:1372
@ STRICT_BF16_TO_FP
Definition: ISDOpcodes.h:975
@ ATOMIC_LOAD_UDEC_WRAP
Definition: ISDOpcodes.h:1350
@ ATOMIC_LOAD_ADD
Definition: ISDOpcodes.h:1334
@ ATOMIC_LOAD_SUB
Definition: ISDOpcodes.h:1335
@ TargetConstant
TargetConstant* - Like Constant*, but the DAG does not do any folding, simplification,...
Definition: ISDOpcodes.h:164
@ GET_FPENV_MEM
Gets the current floating-point environment.
Definition: ISDOpcodes.h:1078
@ PSEUDO_PROBE
Pseudo probe for AutoFDO, as a place holder in a basic block to improve the sample counts quality.
Definition: ISDOpcodes.h:1402
@ STRICT_FP_TO_BF16
Definition: ISDOpcodes.h:976
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ ATOMIC_SWAP
Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt) Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN,...
Definition: ISDOpcodes.h:1333
@ ExternalSymbol
Definition: ISDOpcodes.h:83
@ ADDRSPACECAST
ADDRSPACECAST - This operator converts between pointers of different address spaces.
Definition: ISDOpcodes.h:958
@ EXPERIMENTAL_VECTOR_HISTOGRAM
Definition: ISDOpcodes.h:1481
@ BlockAddress
Definition: ISDOpcodes.h:84
@ ATOMIC_LOAD_UINC_WRAP
Definition: ISDOpcodes.h:1349
@ SET_FPENV_MEM
Sets the current floating point environment.
Definition: ISDOpcodes.h:1083
@ TargetGlobalTLSAddress
Definition: ISDOpcodes.h:171
@ BUILD_VECTOR
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector with the specified,...
Definition: ISDOpcodes.h:530
bool isOverflowIntrOpRes(SDValue Op)
Returns true if the specified value is the overflow result from one of the overflow intrinsic nodes.
bool isBuildVectorOfConstantSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantSDNode or undef.
bool isNormalStore(const SDNode *N)
Returns true if the specified node is a non-truncating and unindexed store.
bool matchUnaryPredicate(SDValue Op, std::function< bool(ConstantSDNode *)> Match, bool AllowUndefs=false)
Hook for matching ConstantSDNode predicate.
bool isZEXTLoad(const SDNode *N)
Returns true if the specified node is a ZEXTLOAD.
bool matchUnaryFpPredicate(SDValue Op, std::function< bool(ConstantFPSDNode *)> Match, bool AllowUndefs=false)
Hook for matching ConstantFPSDNode predicate.
static const int FIRST_TARGET_MEMORY_OPCODE
FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations which do not reference a specific me...
Definition: ISDOpcodes.h:1502
bool isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are 0 o...
bool isVectorShrinkable(const SDNode *N, unsigned NewEltSize, bool Signed)
Returns true if the specified node is a vector where all elements can be truncated to the specified e...
bool matchUnaryPredicateImpl(SDValue Op, std::function< bool(ConstNodeType *)> Match, bool AllowUndefs=false)
Attempt to match a unary predicate against a scalar/splat constant or every element of a constant BUI...
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
bool allOperandsUndef(const SDNode *N)
Return true if the node has at least one operand and all operands of the specified node are ISD::UNDE...
bool isFreezeUndef(const SDNode *N)
Return true if the specified node is FREEZE(UNDEF).
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
Definition: ISDOpcodes.h:1575
bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
bool matchBinaryPredicate(SDValue LHS, SDValue RHS, std::function< bool(ConstantSDNode *, ConstantSDNode *)> Match, bool AllowUndefs=false, bool AllowTypeMismatch=false)
Attempt to match a binary predicate against a pair of scalar/splat constants or every element of a pa...
bool isUNINDEXEDStore(const SDNode *N)
Returns true if the specified node is an unindexed store.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
Definition: ISDOpcodes.h:1562
bool isBuildVectorOfConstantFPSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantFPSDNode or undef.
static const int FIRST_TARGET_STRICTFP_OPCODE
FIRST_TARGET_STRICTFP_OPCODE - Target-specific pre-isel operations which cannot raise FP exceptions s...
Definition: ISDOpcodes.h:1496
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1613
bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
Definition: ISDOpcodes.h:1593
bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
SDValue peekThroughExtractSubvectors(SDValue V)
Return the non-extracted vector source operand of V if it exists.
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
bool isAllOnesOrAllOnesSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant -1 integer or a splatted vector of a constant -1 integer (with...
Definition: Utils.cpp:1538
APInt operator&(APInt a, const APInt &b)
Definition: APInt.h:2092
SDValue getBitwiseNotOperand(SDValue V, SDValue Mask, bool AllowUndefs)
If V is a bitwise not, returns the inverted operand.
SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
bool isIntOrFPConstant(SDValue V)
Return true if V is either a integer or FP constant.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool isNullOrNullSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant 0 integer or a splatted vector of a constant 0 integer (with n...
Definition: Utils.cpp:1520
bool isMinSignedConstant(SDValue V)
Returns true if V is a constant min signed integer value.
ConstantFPSDNode * isConstOrConstSplatFP(SDValue N, bool AllowUndefs=false)
Returns the SDNode if it is a constant splat BuildVector or constant float.
bool isBitwiseNot(SDValue V, bool AllowUndefs=false)
Returns true if V is a bitwise not operation.
void checkForCycles(const SelectionDAG *DAG, bool force=false)
SDValue peekThroughTruncates(SDValue V)
Return the non-truncated source operand of V if it exists.
bool hasSingleElement(ContainerTy &&C)
Returns true if the given container only contains a single element.
Definition: STLExtras.h:322
SDValue peekThroughOneUseBitcasts(SDValue V)
Return the non-bitcasted and one-use source operand of V if it exists.
bool isOneOrOneSplat(SDValue V, bool AllowUndefs=false)
Return true if the value is a constant 1 integer or a splatted vector of a constant 1 integer (with n...
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ Other
Any other memory.
bool isNullConstantOrUndef(SDValue V)
Returns true if V is a constant integer zero or an UNDEF node.
ConstantSDNode * isConstOrConstSplat(SDValue N, bool AllowUndefs=false, bool AllowTruncation=false)
Returns the SDNode if it is a constant splat BuildVector or constant int.
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:217
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
bool isOneConstant(SDValue V)
Returns true if V is a constant integer one.
bool isNullFPConstant(SDValue V)
Returns true if V is an FP constant with a value of positive zero.
APInt operator|(APInt a, const APInt &b)
Definition: APInt.h:2112
bool isNeutralConstant(unsigned Opc, SDNodeFlags Flags, SDValue V, unsigned OperandNo)
Returns true if V is a neutral element of Opc with Flags.
bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define N
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition: Metadata.h:760
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
A suitably aligned and sized character array member which can hold elements of any type.
Definition: AlignOf.h:27
static unsigned getHashValue(const SDValue &Val)
static bool isEqual(const SDValue &LHS, const SDValue &RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:52
Extended Value Type.
Definition: ValueTypes.h:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition: ValueTypes.h:368
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition: ValueTypes.h:376
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition: ValueTypes.h:318
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition: ValueTypes.h:331
static ChildIteratorType child_begin(NodeRef N)
static ChildIteratorType child_end(NodeRef N)
static NodeRef getEntryNode(SDNode *N)
This class contains a discriminated union of information about pointers in memory operands,...
unsigned getAddrSpace() const
Return the LLVM IR address space number that this pointer points into.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
These are IR-level optimization flags that may be propagated to SDNodes.
void setSameSign(bool b)
void copyFMF(const FPMathOperator &FPMO)
Propagate the fast-math-flags from an IR FPMathOperator.
bool hasNoInfs() const
void setNoFPExcept(bool b)
void setDisjoint(bool b)
void setAllowContract(bool b)
void setNoSignedZeros(bool b)
bool hasNoFPExcept() const
bool operator==(const SDNodeFlags &Other) const
void setNoNaNs(bool b)
void operator&=(const SDNodeFlags &OtherFlags)
void operator|=(const SDNodeFlags &OtherFlags)
bool hasNoUnsignedWrap() const
void setAllowReassociation(bool b)
bool hasNoNaNs() const
void setUnpredictable(bool b)
void setNoInfs(bool b)
void setAllowReciprocal(bool b)
bool hasAllowContract() const
bool hasNoSignedZeros() const
bool hasDisjoint() const
bool hasApproximateFuncs() const
bool hasUnpredictable() const
void setApproximateFuncs(bool b)
bool hasNoSignedWrap() const
bool hasSameSign() const
void setNonNeg(bool b)
SDNodeFlags(unsigned Flags=SDNodeFlags::None)
Default constructor turns off all optimization flags.
bool hasAllowReciprocal() const
bool hasNonNeg() const
bool hasAllowReassociation() const
void setNoUnsignedWrap(bool b)
void setNoSignedWrap(bool b)
Iterator for directly iterating over the operand SDValue's.
const SDValue & operator*() const
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
unsigned int NumVTs
static SimpleType getSimplifiedValue(SDUse &Val)
static SimpleType getSimplifiedValue(SDValue &Val)
static SimpleType getSimplifiedValue(const SDValue &Val)
Define a template that can be specialized by smart pointers to reflect the fact that they are automat...
Definition: Casting.h:34