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