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 // Call does not require convergence guarantees.
432 NoConvergent = 1 << 16,
433
434 // NOTE: Please update LargestValue in LLVM_DECLARE_ENUM_AS_BITMASK below
435 // the class definition when adding new flags.
436
441 };
442
443 /// Default constructor turns off all optimization flags.
444 SDNodeFlags(unsigned Flags = SDNodeFlags::None) : Flags(Flags) {}
445
446 /// Propagate the fast-math-flags from an IR FPMathOperator.
456
457 // These are mutators for each flag.
458 void setNoUnsignedWrap(bool b) { setFlag<NoUnsignedWrap>(b); }
459 void setNoSignedWrap(bool b) { setFlag<NoSignedWrap>(b); }
460 void setExact(bool b) { setFlag<Exact>(b); }
461 void setDisjoint(bool b) { setFlag<Disjoint>(b); }
462 void setSameSign(bool b) { setFlag<SameSign>(b); }
463 void setNonNeg(bool b) { setFlag<NonNeg>(b); }
464 void setNoNaNs(bool b) { setFlag<NoNaNs>(b); }
465 void setNoInfs(bool b) { setFlag<NoInfs>(b); }
466 void setNoSignedZeros(bool b) { setFlag<NoSignedZeros>(b); }
467 void setAllowReciprocal(bool b) { setFlag<AllowReciprocal>(b); }
468 void setAllowContract(bool b) { setFlag<AllowContract>(b); }
469 void setApproximateFuncs(bool b) { setFlag<ApproximateFuncs>(b); }
470 void setAllowReassociation(bool b) { setFlag<AllowReassociation>(b); }
471 void setNoFPExcept(bool b) { setFlag<NoFPExcept>(b); }
472 void setUnpredictable(bool b) { setFlag<Unpredictable>(b); }
473 void setInBounds(bool b) { setFlag<InBounds>(b); }
474 void setNoConvergent(bool b) { setFlag<NoConvergent>(b); }
475
476 // These are accessors for each flag.
477 bool hasNoUnsignedWrap() const { return Flags & NoUnsignedWrap; }
478 bool hasNoSignedWrap() const { return Flags & NoSignedWrap; }
479 bool hasExact() const { return Flags & Exact; }
480 bool hasDisjoint() const { return Flags & Disjoint; }
481 bool hasSameSign() const { return Flags & SameSign; }
482 bool hasNonNeg() const { return Flags & NonNeg; }
483 bool hasNoNaNs() const { return Flags & NoNaNs; }
484 bool hasNoInfs() const { return Flags & NoInfs; }
485 bool hasNoSignedZeros() const { return Flags & NoSignedZeros; }
486 bool hasAllowReciprocal() const { return Flags & AllowReciprocal; }
487 bool hasAllowContract() const { return Flags & AllowContract; }
488 bool hasApproximateFuncs() const { return Flags & ApproximateFuncs; }
489 bool hasAllowReassociation() const { return Flags & AllowReassociation; }
490 bool hasNoFPExcept() const { return Flags & NoFPExcept; }
491 bool hasUnpredictable() const { return Flags & Unpredictable; }
492 bool hasInBounds() const { return Flags & InBounds; }
493 bool hasNoConvergent() const { return Flags & NoConvergent; }
494
495 bool operator==(const SDNodeFlags &Other) const {
496 return Flags == Other.Flags;
497 }
498 void operator&=(const SDNodeFlags &OtherFlags) { Flags &= OtherFlags.Flags; }
499 void operator|=(const SDNodeFlags &OtherFlags) { Flags |= OtherFlags.Flags; }
500};
501
504
506 LHS |= RHS;
507 return LHS;
508}
509
511 LHS &= RHS;
512 return LHS;
513}
514
515/// Represents one node in the SelectionDAG.
516///
517class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
518private:
519 /// The operation that this node performs.
520 int32_t NodeType;
521
522 SDNodeFlags Flags;
523
524protected:
525 // We define a set of mini-helper classes to help us interpret the bits in our
526 // SubclassData. These are designed to fit within a uint16_t so they pack
527 // with SDNodeFlags.
528
529#if defined(_AIX) && (!defined(__GNUC__) || defined(__clang__))
530// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words
531// and give the `pack` pragma push semantics.
532#define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")
533#define END_TWO_BYTE_PACK() _Pragma("pack(pop)")
534#else
535#define BEGIN_TWO_BYTE_PACK()
536#define END_TWO_BYTE_PACK()
537#endif
538
541 friend class SDNode;
542 friend class MemIntrinsicSDNode;
543 friend class MemSDNode;
544 friend class SelectionDAG;
545
546 uint16_t HasDebugValue : 1;
547 uint16_t IsMemIntrinsic : 1;
548 uint16_t IsDivergent : 1;
549 };
550 enum { NumSDNodeBits = 3 };
551
553 friend class ConstantSDNode;
554
556
557 uint16_t IsOpaque : 1;
558 };
559
561 friend class MemSDNode;
562 friend class MemIntrinsicSDNode;
563 friend class AtomicSDNode;
564
566
567 uint16_t IsVolatile : 1;
568 uint16_t IsNonTemporal : 1;
569 uint16_t IsDereferenceable : 1;
570 uint16_t IsInvariant : 1;
571 };
573
575 friend class LSBaseSDNode;
581
583
584 // This storage is shared between disparate class hierarchies to hold an
585 // enumeration specific to the class hierarchy in use.
586 // LSBaseSDNode => enum ISD::MemIndexedMode
587 // VPLoadStoreBaseSDNode => enum ISD::MemIndexedMode
588 // MaskedLoadStoreBaseSDNode => enum ISD::MemIndexedMode
589 // VPGatherScatterSDNode => enum ISD::MemIndexType
590 // MaskedGatherScatterSDNode => enum ISD::MemIndexType
591 // MaskedHistogramSDNode => enum ISD::MemIndexType
592 uint16_t AddressingMode : 3;
593 };
595
597 friend class LoadSDNode;
598 friend class AtomicSDNode;
599 friend class VPLoadSDNode;
601 friend class MaskedLoadSDNode;
602 friend class MaskedGatherSDNode;
603 friend class VPGatherSDNode;
605
607
608 uint16_t ExtTy : 2; // enum ISD::LoadExtType
609 uint16_t IsExpanding : 1;
610 };
611
613 friend class StoreSDNode;
614 friend class VPStoreSDNode;
616 friend class MaskedStoreSDNode;
618 friend class VPScatterSDNode;
619
621
622 uint16_t IsTruncating : 1;
623 uint16_t IsCompressing : 1;
624 };
625
626 union {
627 char RawSDNodeBits[sizeof(uint16_t)];
634 };
636#undef BEGIN_TWO_BYTE_PACK
637#undef END_TWO_BYTE_PACK
638
639 // RawSDNodeBits must cover the entirety of the union. This means that all of
640 // the union's members must have size <= RawSDNodeBits. We write the RHS as
641 // "2" instead of sizeof(RawSDNodeBits) because MSVC can't handle the latter.
642 static_assert(sizeof(SDNodeBitfields) <= 2, "field too wide");
643 static_assert(sizeof(ConstantSDNodeBitfields) <= 2, "field too wide");
644 static_assert(sizeof(MemSDNodeBitfields) <= 2, "field too wide");
645 static_assert(sizeof(LSBaseSDNodeBitfields) <= 2, "field too wide");
646 static_assert(sizeof(LoadSDNodeBitfields) <= 2, "field too wide");
647 static_assert(sizeof(StoreSDNodeBitfields) <= 2, "field too wide");
648
649public:
650 /// Unique and persistent id per SDNode in the DAG. Used for debug printing.
651 /// We do not place that under `#if LLVM_ENABLE_ABI_BREAKING_CHECKS`
652 /// intentionally because it adds unneeded complexity without noticeable
653 /// benefits (see discussion with @thakis in D120714). Currently, there are
654 /// two padding bytes after this field.
656
657private:
658 friend class SelectionDAG;
659 // TODO: unfriend HandleSDNode once we fix its operand handling.
660 friend class HandleSDNode;
661
662 /// Unique id per SDNode in the DAG.
663 int NodeId = -1;
664
665 /// The values that are used by this operation.
666 SDUse *OperandList = nullptr;
667
668 /// The types of the values this node defines. SDNode's may
669 /// define multiple values simultaneously.
670 const EVT *ValueList;
671
672 /// List of uses for this SDNode.
673 SDUse *UseList = nullptr;
674
675 /// The number of entries in the Operand/Value list.
676 unsigned short NumOperands = 0;
677 unsigned short NumValues;
678
679 // The ordering of the SDNodes. It roughly corresponds to the ordering of the
680 // original LLVM instructions.
681 // This is used for turning off scheduling, because we'll forgo
682 // the normal scheduling algorithms and output the instructions according to
683 // this ordering.
684 unsigned IROrder;
685
686 /// Source line information.
687 DebugLoc debugLoc;
688
689 /// Return a pointer to the specified value type.
690 LLVM_ABI static const EVT *getValueTypeList(MVT VT);
691
692 union {
693 /// Index in worklist of DAGCombiner, or negative if the node is not in the
694 /// worklist. -1 = not in worklist; -2 = not in worklist, but has already
695 /// been combined at least once.
697 /// Visited state in ScheduleDAGSDNodes::BuildSchedUnits.
699 };
700
701 uint32_t CFIType = 0;
702
703public:
704 //===--------------------------------------------------------------------===//
705 // Accessors
706 //
707
708 /// Return the SelectionDAG opcode value for this node. For
709 /// pre-isel nodes (those for which isMachineOpcode returns false), these
710 /// are the opcode values in the ISD and <target>ISD namespaces. For
711 /// post-isel opcodes, see getMachineOpcode.
712 unsigned getOpcode() const { return (unsigned)NodeType; }
713
714 /// Test if this node has a target-specific opcode (in the
715 /// <target>ISD namespace).
716 bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
717
718 /// Returns true if the node type is UNDEF or POISON.
719 bool isUndef() const {
720 return NodeType == ISD::UNDEF || NodeType == ISD::POISON;
721 }
722
723 /// Returns true if the node type is ADD or PTRADD.
724 bool isAnyAdd() const {
725 return NodeType == ISD::ADD || NodeType == ISD::PTRADD;
726 }
727
728 /// Test if this node is a memory intrinsic (with valid pointer information).
729 bool isMemIntrinsic() const { return SDNodeBits.IsMemIntrinsic; }
730
731 /// Test if this node is a strict floating point pseudo-op.
733 switch (NodeType) {
734 default:
735 return false;
740#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
741 case ISD::STRICT_##DAGN:
742#include "llvm/IR/ConstrainedOps.def"
743 return true;
744 }
745 }
746
747 /// Test if this node is an assert operation.
748 bool isAssert() const {
749 switch (NodeType) {
750 default:
751 return false;
752 case ISD::AssertAlign:
754 case ISD::AssertSext:
755 case ISD::AssertZext:
756 return true;
757 }
758 }
759
760 /// Test if this node is a vector predication operation.
761 bool isVPOpcode() const { return ISD::isVPOpcode(getOpcode()); }
762
763 /// Test if this node has a post-isel opcode, directly
764 /// corresponding to a MachineInstr opcode.
765 bool isMachineOpcode() const { return NodeType < 0; }
766
767 /// This may only be called if isMachineOpcode returns
768 /// true. It returns the MachineInstr opcode value that the node's opcode
769 /// corresponds to.
770 unsigned getMachineOpcode() const {
771 assert(isMachineOpcode() && "Not a MachineInstr opcode!");
772 return ~NodeType;
773 }
774
775 bool getHasDebugValue() const { return SDNodeBits.HasDebugValue; }
776 void setHasDebugValue(bool b) { SDNodeBits.HasDebugValue = b; }
777
778 bool isDivergent() const { return SDNodeBits.IsDivergent; }
779
780 /// Return true if there are no uses of this node.
781 bool use_empty() const { return UseList == nullptr; }
782
783 /// Return true if there is exactly one use of this node.
784 bool hasOneUse() const { return hasSingleElement(uses()); }
785
786 /// Return the number of uses of this node. This method takes
787 /// time proportional to the number of uses.
788 size_t use_size() const { return std::distance(use_begin(), use_end()); }
789
790 /// Return the unique node id.
791 int getNodeId() const { return NodeId; }
792
793 /// Set unique node id.
794 void setNodeId(int Id) { NodeId = Id; }
795
796 /// Get worklist index for DAGCombiner
798
799 /// Set worklist index for DAGCombiner
801
802 /// Get visited state for ScheduleDAGSDNodes::BuildSchedUnits.
804
805 /// Set visited state for ScheduleDAGSDNodes::BuildSchedUnits.
806 void setSchedulerWorklistVisited(bool Visited) {
807 SchedulerWorklistVisited = Visited;
808 }
809
810 /// Return the node ordering.
811 unsigned getIROrder() const { return IROrder; }
812
813 /// Set the node ordering.
814 void setIROrder(unsigned Order) { IROrder = Order; }
815
816 /// Return the source location info.
817 const DebugLoc &getDebugLoc() const { return debugLoc; }
818
819 /// Set source location info. Try to avoid this, putting
820 /// it in the constructor is preferable.
821 void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); }
822
823 /// This class provides iterator support for SDUse
824 /// operands that use a specific SDNode.
825 class use_iterator {
826 friend class SDNode;
827
828 SDUse *Op = nullptr;
829
830 explicit use_iterator(SDUse *op) : Op(op) {}
831
832 public:
833 using iterator_category = std::forward_iterator_tag;
835 using difference_type = std::ptrdiff_t;
838
839 use_iterator() = default;
840 use_iterator(const use_iterator &I) = default;
841 use_iterator &operator=(const use_iterator &) = default;
842
843 bool operator==(const use_iterator &x) const { return Op == x.Op; }
844 bool operator!=(const use_iterator &x) const {
845 return !operator==(x);
846 }
847
848 // Iterator traversal: forward iteration only.
849 use_iterator &operator++() { // Preincrement
850 assert(Op && "Cannot increment end iterator!");
851 Op = Op->getNext();
852 return *this;
853 }
854
855 use_iterator operator++(int) { // Postincrement
856 use_iterator tmp = *this; ++*this; return tmp;
857 }
858
859 /// Retrieve a pointer to the current user node.
860 SDUse &operator*() const {
861 assert(Op && "Cannot dereference end iterator!");
862 return *Op;
863 }
864
865 SDUse *operator->() const { return &operator*(); }
866 };
867
868 class user_iterator {
869 friend class SDNode;
870 use_iterator UI;
871
872 explicit user_iterator(SDUse *op) : UI(op) {};
873
874 public:
875 using iterator_category = std::forward_iterator_tag;
877 using difference_type = std::ptrdiff_t;
880
881 user_iterator() = default;
882
883 bool operator==(const user_iterator &x) const { return UI == x.UI; }
884 bool operator!=(const user_iterator &x) const { return !operator==(x); }
885
886 user_iterator &operator++() { // Preincrement
887 ++UI;
888 return *this;
889 }
890
891 user_iterator operator++(int) { // Postincrement
892 auto tmp = *this;
893 ++*this;
894 return tmp;
895 }
896
897 // Retrieve a pointer to the current User.
898 SDNode *operator*() const { return UI->getUser(); }
899
900 SDNode *operator->() const { return operator*(); }
901
902 SDUse &getUse() const { return *UI; }
903 };
904
905 /// Provide iteration support to walk over all uses of an SDNode.
907 return use_iterator(UseList);
908 }
909
910 static use_iterator use_end() { return use_iterator(nullptr); }
911
916 return make_range(use_begin(), use_end());
917 }
918
919 /// Provide iteration support to walk over all users of an SDNode.
920 user_iterator user_begin() const { return user_iterator(UseList); }
921
922 static user_iterator user_end() { return user_iterator(nullptr); }
923
928 return make_range(user_begin(), user_end());
929 }
930
931 /// Return true if there are exactly NUSES uses of the indicated value.
932 /// This method ignores uses of other values defined by this operation.
933 bool hasNUsesOfValue(unsigned NUses, unsigned Value) const {
934 assert(Value < getNumValues() && "Bad value!");
935
936 // TODO: Only iterate over uses of a given value of the node
937 for (SDUse &U : uses()) {
938 if (U.getResNo() == Value) {
939 if (NUses == 0)
940 return false;
941 --NUses;
942 }
943 }
944
945 // Found exactly the right number of uses?
946 return NUses == 0;
947 }
948
949 /// Return true if there are any use of the indicated value.
950 /// This method ignores uses of other values defined by this operation.
951 LLVM_ABI bool hasAnyUseOfValue(unsigned Value) const;
952
953 /// Return true if this node is the only use of N.
954 LLVM_ABI bool isOnlyUserOf(const SDNode *N) const;
955
956 /// Return true if this node is an operand of N.
957 LLVM_ABI bool isOperandOf(const SDNode *N) const;
958
959 /// Return true if this node is a predecessor of N.
960 /// NOTE: Implemented on top of hasPredecessor and every bit as
961 /// expensive. Use carefully.
962 bool isPredecessorOf(const SDNode *N) const {
963 return N->hasPredecessor(this);
964 }
965
966 /// Return true if N is a predecessor of this node.
967 /// N is either an operand of this node, or can be reached by recursively
968 /// traversing up the operands.
969 /// NOTE: This is an expensive method. Use it carefully.
970 LLVM_ABI bool hasPredecessor(const SDNode *N) const;
971
972 /// Returns true if N is a predecessor of any node in Worklist. This
973 /// helper keeps Visited and Worklist sets externally to allow unions
974 /// searches to be performed in parallel, caching of results across
975 /// queries and incremental addition to Worklist. Stops early if N is
976 /// found but will resume. Remember to clear Visited and Worklists
977 /// if DAG changes. MaxSteps gives a maximum number of nodes to visit before
978 /// giving up. The TopologicalPrune flag signals that positive NodeIds are
979 /// topologically ordered (Operands have strictly smaller node id) and search
980 /// can be pruned leveraging this.
981 static bool hasPredecessorHelper(const SDNode *N,
984 unsigned int MaxSteps = 0,
985 bool TopologicalPrune = false) {
986 if (Visited.count(N))
987 return true;
988
989 SmallVector<const SDNode *, 8> DeferredNodes;
990 // Node Id's are assigned in three places: As a topological
991 // ordering (> 0), during legalization (results in values set to
992 // 0), new nodes (set to -1). If N has a topolgical id then we
993 // know that all nodes with ids smaller than it cannot be
994 // successors and we need not check them. Filter out all node
995 // that can't be matches. We add them to the worklist before exit
996 // in case of multiple calls. Note that during selection the topological id
997 // may be violated if a node's predecessor is selected before it. We mark
998 // this at selection negating the id of unselected successors and
999 // restricting topological pruning to positive ids.
1000
1001 int NId = N->getNodeId();
1002 // If we Invalidated the Id, reconstruct original NId.
1003 if (NId < -1)
1004 NId = -(NId + 1);
1005
1006 bool Found = false;
1007 while (!Worklist.empty()) {
1008 const SDNode *M = Worklist.pop_back_val();
1009 int MId = M->getNodeId();
1010 if (TopologicalPrune && M->getOpcode() != ISD::TokenFactor && (NId > 0) &&
1011 (MId > 0) && (MId < NId)) {
1012 DeferredNodes.push_back(M);
1013 continue;
1014 }
1015 for (const SDValue &OpV : M->op_values()) {
1016 SDNode *Op = OpV.getNode();
1017 if (Visited.insert(Op).second)
1018 Worklist.push_back(Op);
1019 if (Op == N)
1020 Found = true;
1021 }
1022 if (Found)
1023 break;
1024 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
1025 break;
1026 }
1027 // Push deferred nodes back on worklist.
1028 Worklist.append(DeferredNodes.begin(), DeferredNodes.end());
1029 // If we bailed early, conservatively return found.
1030 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
1031 return true;
1032 return Found;
1033 }
1034
1035 /// Return true if all the users of N are contained in Nodes.
1036 /// NOTE: Requires at least one match, but doesn't require them all.
1038 const SDNode *N);
1039
1040 /// Return the number of values used by this operation.
1041 unsigned getNumOperands() const { return NumOperands; }
1042
1043 /// Return the maximum number of operands that a SDNode can hold.
1044 static constexpr size_t getMaxNumOperands() {
1045 return std::numeric_limits<decltype(SDNode::NumOperands)>::max();
1046 }
1047
1048 /// Helper method returns the integer value of a ConstantSDNode operand.
1049 inline uint64_t getConstantOperandVal(unsigned Num) const;
1050
1051 /// Helper method returns the zero-extended integer value of a ConstantSDNode.
1052 inline uint64_t getAsZExtVal() const;
1053
1054 /// Helper method returns the APInt of a ConstantSDNode operand.
1055 inline const APInt &getConstantOperandAPInt(unsigned Num) const;
1056
1057 /// Helper method returns the APInt value of a ConstantSDNode.
1058 inline const APInt &getAsAPIntVal() const;
1059
1060 inline std::optional<APInt> bitcastToAPInt() const;
1061
1062 const SDValue &getOperand(unsigned Num) const {
1063 assert(Num < NumOperands && "Invalid child # of SDNode!");
1064 return OperandList[Num];
1065 }
1066
1068
1069 op_iterator op_begin() const { return OperandList; }
1070 op_iterator op_end() const { return OperandList+NumOperands; }
1071 ArrayRef<SDUse> ops() const { return ArrayRef(op_begin(), op_end()); }
1072
1073 /// Iterator for directly iterating over the operand SDValue's.
1075 : iterator_adaptor_base<value_op_iterator, op_iterator,
1076 std::random_access_iterator_tag, SDValue,
1077 ptrdiff_t, value_op_iterator *,
1078 value_op_iterator *> {
1079 explicit value_op_iterator(SDUse *U = nullptr)
1080 : iterator_adaptor_base(U) {}
1081
1082 const SDValue &operator*() const { return I->get(); }
1083 };
1084
1089
1091 SDVTList X = { ValueList, NumValues };
1092 return X;
1093 }
1094
1095 /// If this node has a glue operand, return the node
1096 /// to which the glue operand points. Otherwise return NULL.
1098 if (getNumOperands() != 0 &&
1099 getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
1100 return getOperand(getNumOperands()-1).getNode();
1101 return nullptr;
1102 }
1103
1104 /// If this node has a glue value with a user, return
1105 /// the user (there is at most one). Otherwise return NULL.
1107 for (SDUse &U : uses())
1108 if (U.getValueType() == MVT::Glue)
1109 return U.getUser();
1110 return nullptr;
1111 }
1112
1113 SDNodeFlags getFlags() const { return Flags; }
1114 void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
1115 void dropFlags(unsigned Mask) { Flags &= ~Mask; }
1116
1117 /// Clear any flags in this node that aren't also set in Flags.
1118 /// If Flags is not in a defined state then this has no effect.
1119 LLVM_ABI void intersectFlagsWith(const SDNodeFlags Flags);
1120
1122 return Flags.Flags & SDNodeFlags::PoisonGeneratingFlags;
1123 }
1124
1125 void setCFIType(uint32_t Type) { CFIType = Type; }
1126 uint32_t getCFIType() const { return CFIType; }
1127
1128 /// Return the number of values defined/returned by this operator.
1129 unsigned getNumValues() const { return NumValues; }
1130
1131 /// Return the type of a specified result.
1132 EVT getValueType(unsigned ResNo) const {
1133 assert(ResNo < NumValues && "Illegal result number!");
1134 return ValueList[ResNo];
1135 }
1136
1137 /// Return the type of a specified result as a simple type.
1138 MVT getSimpleValueType(unsigned ResNo) const {
1139 return getValueType(ResNo).getSimpleVT();
1140 }
1141
1142 /// Returns MVT::getSizeInBits(getValueType(ResNo)).
1143 ///
1144 /// If the value type is a scalable vector type, the scalable property will
1145 /// be set and the runtime size will be a positive integer multiple of the
1146 /// base size.
1147 TypeSize getValueSizeInBits(unsigned ResNo) const {
1148 return getValueType(ResNo).getSizeInBits();
1149 }
1150
1151 using value_iterator = const EVT *;
1152
1153 value_iterator value_begin() const { return ValueList; }
1154 value_iterator value_end() const { return ValueList+NumValues; }
1158
1159 /// Return the opcode of this operation for printing.
1160 LLVM_ABI std::string getOperationName(const SelectionDAG *G = nullptr) const;
1161 LLVM_ABI static const char *getIndexedModeName(ISD::MemIndexedMode AM);
1162 LLVM_ABI void print_types(raw_ostream &OS, const SelectionDAG *G) const;
1163 LLVM_ABI void print_details(raw_ostream &OS, const SelectionDAG *G) const;
1164 LLVM_ABI void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1165 LLVM_ABI void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1166
1167 /// Print a SelectionDAG node and all children down to
1168 /// the leaves. The given SelectionDAG allows target-specific nodes
1169 /// to be printed in human-readable form. Unlike printr, this will
1170 /// print the whole DAG, including children that appear multiple
1171 /// times.
1172 ///
1174 const SelectionDAG *G = nullptr) const;
1175
1176 /// Print a SelectionDAG node and children up to
1177 /// depth "depth." The given SelectionDAG allows target-specific
1178 /// nodes to be printed in human-readable form. Unlike printr, this
1179 /// will print children that appear multiple times wherever they are
1180 /// used.
1181 ///
1182 LLVM_ABI void printrWithDepth(raw_ostream &O, const SelectionDAG *G = nullptr,
1183 unsigned depth = 100) const;
1184
1185 /// Dump this node, for debugging.
1186 LLVM_ABI void dump() const;
1187
1188 /// Dump (recursively) this node and its use-def subgraph.
1189 LLVM_ABI void dumpr() const;
1190
1191 /// Dump this node, for debugging.
1192 /// The given SelectionDAG allows target-specific nodes to be printed
1193 /// in human-readable form.
1194 LLVM_ABI void dump(const SelectionDAG *G) const;
1195
1196 /// Dump (recursively) this node and its use-def subgraph.
1197 /// The given SelectionDAG allows target-specific nodes to be printed
1198 /// in human-readable form.
1199 LLVM_ABI void dumpr(const SelectionDAG *G) const;
1200
1201 /// printrFull to dbgs(). The given SelectionDAG allows
1202 /// target-specific nodes to be printed in human-readable form.
1203 /// Unlike dumpr, this will print the whole DAG, including children
1204 /// that appear multiple times.
1205 LLVM_ABI void dumprFull(const SelectionDAG *G = nullptr) const;
1206
1207 /// printrWithDepth to dbgs(). The given
1208 /// SelectionDAG allows target-specific nodes to be printed in
1209 /// human-readable form. Unlike dumpr, this will print children
1210 /// that appear multiple times wherever they are used.
1211 ///
1212 LLVM_ABI void dumprWithDepth(const SelectionDAG *G = nullptr,
1213 unsigned depth = 100) const;
1214
1215 /// Gather unique data for the node.
1216 LLVM_ABI void Profile(FoldingSetNodeID &ID) const;
1217
1218 /// This method should only be used by the SDUse class.
1219 void addUse(SDUse &U) { U.addToList(&UseList); }
1220
1221protected:
1223 SDVTList Ret = { getValueTypeList(VT), 1 };
1224 return Ret;
1225 }
1226
1227 /// Create an SDNode.
1228 ///
1229 /// SDNodes are created without any operands, and never own the operand
1230 /// storage. To add operands, see SelectionDAG::createOperands.
1231 SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs)
1232 : NodeType(Opc), ValueList(VTs.VTs), NumValues(VTs.NumVTs),
1233 IROrder(Order), debugLoc(std::move(dl)) {
1234 memset(&RawSDNodeBits, 0, sizeof(RawSDNodeBits));
1235 assert(debugLoc.hasTrivialDestructor() && "Expected trivial destructor");
1236 assert(NumValues == VTs.NumVTs &&
1237 "NumValues wasn't wide enough for its operands!");
1238 }
1239
1240 /// Release the operands and set this node to have zero operands.
1241 LLVM_ABI void DropOperands();
1242};
1243
1244/// Wrapper class for IR location info (IR ordering and DebugLoc) to be passed
1245/// into SDNode creation functions.
1246/// When an SDNode is created from the DAGBuilder, the DebugLoc is extracted
1247/// from the original Instruction, and IROrder is the ordinal position of
1248/// the instruction.
1249/// When an SDNode is created after the DAG is being built, both DebugLoc and
1250/// the IROrder are propagated from the original SDNode.
1251/// So SDLoc class provides two constructors besides the default one, one to
1252/// be used by the DAGBuilder, the other to be used by others.
1253class SDLoc {
1254private:
1255 DebugLoc DL;
1256 int IROrder = 0;
1257
1258public:
1259 SDLoc() = default;
1260 SDLoc(const SDNode *N) : DL(N->getDebugLoc()), IROrder(N->getIROrder()) {}
1261 SDLoc(const SDValue V) : SDLoc(V.getNode()) {}
1262 SDLoc(const Instruction *I, int Order) : IROrder(Order) {
1263 assert(Order >= 0 && "bad IROrder");
1264 if (I)
1265 DL = I->getDebugLoc();
1266 }
1267
1268 unsigned getIROrder() const { return IROrder; }
1269 const DebugLoc &getDebugLoc() const { return DL; }
1270};
1271
1272// Define inline functions from the SDValue class.
1273
1274inline SDValue::SDValue(SDNode *node, unsigned resno)
1275 : Node(node), ResNo(resno) {
1276 // Explicitly check for !ResNo to avoid use-after-free, because there are
1277 // callers that use SDValue(N, 0) with a deleted N to indicate successful
1278 // combines.
1279 assert((!Node || !ResNo || ResNo < Node->getNumValues()) &&
1280 "Invalid result number for the given node!");
1281 assert(ResNo < -2U && "Cannot use result numbers reserved for DenseMaps.");
1282}
1283
1284inline unsigned SDValue::getOpcode() const {
1285 return Node->getOpcode();
1286}
1287
1289 return Node->getValueType(ResNo);
1290}
1291
1292inline unsigned SDValue::getNumOperands() const {
1293 return Node->getNumOperands();
1294}
1295
1296inline const SDValue &SDValue::getOperand(unsigned i) const {
1297 return Node->getOperand(i);
1298}
1299
1301 return Node->getConstantOperandVal(i);
1302}
1303
1304inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const {
1305 return Node->getConstantOperandAPInt(i);
1306}
1307
1308inline bool SDValue::isTargetOpcode() const {
1309 return Node->isTargetOpcode();
1310}
1311
1312inline bool SDValue::isMachineOpcode() const {
1313 return Node->isMachineOpcode();
1314}
1315
1316inline unsigned SDValue::getMachineOpcode() const {
1317 return Node->getMachineOpcode();
1318}
1319
1320inline bool SDValue::isUndef() const {
1321 return Node->isUndef();
1322}
1323
1324inline bool SDValue::isAnyAdd() const { return Node->isAnyAdd(); }
1325
1326inline bool SDValue::use_empty() const {
1327 return !Node->hasAnyUseOfValue(ResNo);
1328}
1329
1330inline bool SDValue::hasOneUse() const {
1331 return Node->hasNUsesOfValue(1, ResNo);
1332}
1333
1334inline const DebugLoc &SDValue::getDebugLoc() const {
1335 return Node->getDebugLoc();
1336}
1337
1338inline void SDValue::dump() const {
1339 return Node->dump();
1340}
1341
1342inline void SDValue::dump(const SelectionDAG *G) const {
1343 return Node->dump(G);
1344}
1345
1346inline void SDValue::dumpr() const {
1347 return Node->dumpr();
1348}
1349
1350inline void SDValue::dumpr(const SelectionDAG *G) const {
1351 return Node->dumpr(G);
1352}
1353
1354// Define inline functions from the SDUse class.
1355inline unsigned SDUse::getOperandNo() const {
1356 return this - getUser()->op_begin();
1357}
1358
1359inline void SDUse::set(const SDValue &V) {
1360 if (Val.getNode()) removeFromList();
1361 Val = V;
1362 if (V.getNode())
1363 V->addUse(*this);
1364}
1365
1366inline void SDUse::setInitial(const SDValue &V) {
1367 Val = V;
1368 V->addUse(*this);
1369}
1370
1371inline void SDUse::setNode(SDNode *N) {
1372 if (Val.getNode()) removeFromList();
1373 Val.setNode(N);
1374 if (N) N->addUse(*this);
1375}
1376
1377/// This class is used to form a handle around another node that
1378/// is persistent and is updated across invocations of replaceAllUsesWith on its
1379/// operand. This node should be directly created by end-users and not added to
1380/// the AllNodes list.
1381class HandleSDNode : public SDNode {
1382 SDUse Op;
1383
1384public:
1386 : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) {
1387 // HandleSDNodes are never inserted into the DAG, so they won't be
1388 // auto-numbered. Use ID 65535 as a sentinel.
1389 PersistentId = 0xffff;
1390
1391 // Manually set up the operand list. This node type is special in that it's
1392 // always stack allocated and SelectionDAG does not manage its operands.
1393 // TODO: This should either (a) not be in the SDNode hierarchy, or (b) not
1394 // be so special.
1395 Op.setUser(this);
1396 Op.setInitial(X);
1397 NumOperands = 1;
1398 OperandList = &Op;
1399 }
1401
1402 const SDValue &getValue() const { return Op; }
1403};
1404
1406private:
1407 unsigned SrcAddrSpace;
1408 unsigned DestAddrSpace;
1409
1410public:
1411 AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
1412 unsigned SrcAS, unsigned DestAS)
1413 : SDNode(ISD::ADDRSPACECAST, Order, dl, VTs), SrcAddrSpace(SrcAS),
1414 DestAddrSpace(DestAS) {}
1415
1416 unsigned getSrcAddressSpace() const { return SrcAddrSpace; }
1417 unsigned getDestAddressSpace() const { return DestAddrSpace; }
1418
1419 static bool classof(const SDNode *N) {
1420 return N->getOpcode() == ISD::ADDRSPACECAST;
1421 }
1422};
1423
1424/// This is an abstract virtual class for memory operations.
1425class MemSDNode : public SDNode {
1426private:
1427 // VT of in-memory value.
1428 EVT MemoryVT;
1429
1430protected:
1431 /// Memory reference information. Must always have at least one MMO.
1432 /// - MachineMemOperand*: exactly 1 MMO (common case)
1433 /// - MachineMemOperand**: pointer to array, size at offset -1
1435
1436public:
1437 /// Constructor that supports single or multiple MMOs. For single MMO, pass
1438 /// the MMO pointer directly. For multiple MMOs, pre-allocate storage with
1439 /// count at offset -1 and pass pointer to array.
1440 LLVM_ABI
1441 MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs,
1442 EVT memvt,
1444
1445 bool readMem() const { return getMemOperand()->isLoad(); }
1446 bool writeMem() const { return getMemOperand()->isStore(); }
1447
1448 /// Returns alignment and volatility of the memory access
1450 Align getAlign() const { return getMemOperand()->getAlign(); }
1451
1452 /// Return the SubclassData value, without HasDebugValue. This contains an
1453 /// encoding of the volatile flag, as well as bits used by subclasses. This
1454 /// function should only be used to compute a FoldingSetNodeID value.
1455 /// The HasDebugValue bit is masked out because CSE map needs to match
1456 /// nodes with debug info with nodes without debug info. Same is about
1457 /// isDivergent bit.
1458 unsigned getRawSubclassData() const {
1459 uint16_t Data;
1460 union {
1461 char RawSDNodeBits[sizeof(uint16_t)];
1463 };
1464 memcpy(&RawSDNodeBits, &this->RawSDNodeBits, sizeof(this->RawSDNodeBits));
1465 SDNodeBits.HasDebugValue = 0;
1466 SDNodeBits.IsDivergent = false;
1467 memcpy(&Data, &RawSDNodeBits, sizeof(RawSDNodeBits));
1468 return Data;
1469 }
1470
1471 bool isVolatile() const { return MemSDNodeBits.IsVolatile; }
1472 bool isNonTemporal() const { return MemSDNodeBits.IsNonTemporal; }
1473 bool isDereferenceable() const { return MemSDNodeBits.IsDereferenceable; }
1474 bool isInvariant() const { return MemSDNodeBits.IsInvariant; }
1475
1476 // Returns the offset from the location of the access.
1477 int64_t getSrcValueOffset() const { return getMemOperand()->getOffset(); }
1478
1479 /// Returns the AA info that describes the dereference.
1481
1482 /// Returns the Ranges that describes the dereference.
1483 const MDNode *getRanges() const { return getMemOperand()->getRanges(); }
1484
1485 /// Returns the synchronization scope ID for this memory operation.
1487 return getMemOperand()->getSyncScopeID();
1488 }
1489
1490 /// Return the atomic ordering requirements for this memory operation. For
1491 /// cmpxchg atomic operations, return the atomic ordering requirements when
1492 /// store occurs.
1496
1497 /// Return a single atomic ordering that is at least as strong as both the
1498 /// success and failure orderings for an atomic operation. (For operations
1499 /// other than cmpxchg, this is equivalent to getSuccessOrdering().)
1503
1504 /// Return true if the memory operation ordering is Unordered or higher.
1505 bool isAtomic() const { return getMemOperand()->isAtomic(); }
1506
1507 /// Returns true if the memory operation doesn't imply any ordering
1508 /// constraints on surrounding memory operations beyond the normal memory
1509 /// aliasing rules.
1510 bool isUnordered() const { return getMemOperand()->isUnordered(); }
1511
1512 /// Returns true if the memory operation is neither atomic or volatile.
1513 bool isSimple() const { return !isAtomic() && !isVolatile(); }
1514
1515 /// Return the type of the in-memory value.
1516 EVT getMemoryVT() const { return MemoryVT; }
1517
1518 /// Return the unique MachineMemOperand object describing the memory
1519 /// reference performed by operation.
1520 /// Asserts if multiple MMOs are present - use memoperands() instead.
1523 "Use memoperands() for nodes with multiple memory operands");
1525 }
1526
1527 /// Return the number of memory operands.
1528 size_t getNumMemOperands() const {
1530 return 1;
1532 return reinterpret_cast<size_t *>(Array)[-1];
1533 }
1534
1535 /// Return true if this node has exactly one memory operand.
1537
1538 /// Return the memory operands for this node.
1541 return ArrayRef(MemRefs.getAddrOfPtr1(), 1);
1543 size_t Count = reinterpret_cast<size_t *>(Array)[-1];
1544 return ArrayRef(Array, Count);
1545 }
1546
1548 return getMemOperand()->getPointerInfo();
1549 }
1550
1551 /// Return the address space for the associated pointer
1552 unsigned getAddressSpace() const {
1553 return getPointerInfo().getAddrSpace();
1554 }
1555
1556 /// Update this MemSDNode's MachineMemOperand information
1557 /// to reflect the alignment of NewMMOs, if they have greater alignment.
1558 /// This must only be used when the new alignment applies to all users of
1559 /// these MachineMemOperands. The NewMMOs array must parallel memoperands().
1562 assert(NewMMOs.size() == MMOs.size() && "MMO count mismatch");
1563 for (auto [MMO, NewMMO] : zip(MMOs, NewMMOs))
1564 MMO->refineAlignment(NewMMO);
1565 }
1566
1568 refineAlignment(ArrayRef(NewMMO));
1569 }
1570
1571 /// Refine range metadata for all MMOs. The NewMMOs array must parallel
1572 /// memoperands(). For each pair, if ranges differ, the stored range is
1573 /// cleared.
1576 assert(NewMMOs.size() == MMOs.size() && "MMO count mismatch");
1577 // FIXME: Union the ranges instead?
1578 for (auto [MMO, NewMMO] : zip(MMOs, NewMMOs)) {
1579 if (MMO->getRanges() && MMO->getRanges() != NewMMO->getRanges())
1580 MMO->clearRanges();
1581 }
1582 }
1583
1585 refineRanges(ArrayRef(NewMMO));
1586 }
1587
1588 const SDValue &getChain() const { return getOperand(0); }
1589
1590 const SDValue &getBasePtr() const {
1591 switch (getOpcode()) {
1592 case ISD::STORE:
1593 case ISD::ATOMIC_STORE:
1594 case ISD::VP_STORE:
1595 case ISD::MSTORE:
1596 case ISD::VP_SCATTER:
1597 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1598 return getOperand(2);
1599 case ISD::MGATHER:
1600 case ISD::MSCATTER:
1602 return getOperand(3);
1603 default:
1604 return getOperand(1);
1605 }
1606 }
1607
1608 // Methods to support isa and dyn_cast
1609 static bool classof(const SDNode *N) {
1610 // For some targets, we lower some target intrinsics to a MemIntrinsicNode
1611 // with either an intrinsic or a target opcode.
1612 switch (N->getOpcode()) {
1613 case ISD::LOAD:
1614 case ISD::STORE:
1617 case ISD::ATOMIC_SWAP:
1639 case ISD::ATOMIC_LOAD:
1640 case ISD::ATOMIC_STORE:
1641 case ISD::MLOAD:
1642 case ISD::MSTORE:
1643 case ISD::MGATHER:
1644 case ISD::MSCATTER:
1645 case ISD::VP_LOAD:
1646 case ISD::VP_STORE:
1647 case ISD::VP_GATHER:
1648 case ISD::VP_SCATTER:
1649 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1650 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1651 case ISD::GET_FPENV_MEM:
1652 case ISD::SET_FPENV_MEM:
1654 return true;
1655 default:
1656 return N->isMemIntrinsic();
1657 }
1658 }
1659};
1660
1661/// This is an SDNode representing atomic operations.
1662class AtomicSDNode : public MemSDNode {
1663public:
1664 AtomicSDNode(unsigned Order, const DebugLoc &dl, unsigned Opc, SDVTList VTL,
1665 EVT MemVT, MachineMemOperand *MMO, ISD::LoadExtType ETy)
1666 : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
1668 MMO->isAtomic()) && "then why are we using an AtomicSDNode?");
1670 "Only atomic load uses ExtTy");
1671 LoadSDNodeBits.ExtTy = ETy;
1672 }
1673
1675 assert(getOpcode() == ISD::ATOMIC_LOAD && "Only used for atomic loads.");
1676 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
1677 }
1678
1679 const SDValue &getBasePtr() const {
1680 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(2) : getOperand(1);
1681 }
1682 const SDValue &getVal() const {
1683 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(1) : getOperand(2);
1684 }
1685
1686 /// Returns true if this SDNode represents cmpxchg atomic operation, false
1687 /// otherwise.
1688 bool isCompareAndSwap() const {
1689 unsigned Op = getOpcode();
1690 return Op == ISD::ATOMIC_CMP_SWAP ||
1692 }
1693
1694 /// For cmpxchg atomic operations, return the atomic ordering requirements
1695 /// when store does not occur.
1697 assert(isCompareAndSwap() && "Must be cmpxchg operation");
1699 }
1700
1701 // Methods to support isa and dyn_cast
1702 static bool classof(const SDNode *N) {
1703 return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
1704 N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
1705 N->getOpcode() == ISD::ATOMIC_SWAP ||
1706 N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1707 N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1708 N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1709 N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1710 N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1711 N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1712 N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1713 N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1714 N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1715 N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1716 N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1717 N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1718 N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1719 N->getOpcode() == ISD::ATOMIC_LOAD_FMAX ||
1720 N->getOpcode() == ISD::ATOMIC_LOAD_FMIN ||
1721 N->getOpcode() == ISD::ATOMIC_LOAD_FMAXIMUM ||
1722 N->getOpcode() == ISD::ATOMIC_LOAD_FMINIMUM ||
1723 N->getOpcode() == ISD::ATOMIC_LOAD_UINC_WRAP ||
1724 N->getOpcode() == ISD::ATOMIC_LOAD_UDEC_WRAP ||
1725 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_COND ||
1726 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_SAT ||
1727 N->getOpcode() == ISD::ATOMIC_LOAD ||
1728 N->getOpcode() == ISD::ATOMIC_STORE;
1729 }
1730};
1731
1732/// This SDNode is used for target intrinsics that touch memory and need
1733/// an associated MachineMemOperand. Its opcode may be INTRINSIC_VOID,
1734/// INTRINSIC_W_CHAIN, PREFETCH, or a target-specific memory-referencing
1735/// opcode (see `SelectionDAGTargetInfo::isTargetMemoryOpcode`).
1737public:
1739 unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs,
1740 EVT MemoryVT,
1742 : MemSDNode(Opc, Order, dl, VTs, MemoryVT, MemRefs) {
1743 SDNodeBits.IsMemIntrinsic = true;
1744 }
1745
1746 // Methods to support isa and dyn_cast
1747 static bool classof(const SDNode *N) {
1748 // We lower some target intrinsics to their target opcode
1749 // early a node with a target opcode can be of this class
1750 return N->isMemIntrinsic();
1751 }
1752};
1753
1754/// This SDNode is used to implement the code generator
1755/// support for the llvm IR shufflevector instruction. It combines elements
1756/// from two input vectors into a new input vector, with the selection and
1757/// ordering of elements determined by an array of integers, referred to as
1758/// the shuffle mask. For input vectors of width N, mask indices of 0..N-1
1759/// refer to elements from the LHS input, and indices from N to 2N-1 the RHS.
1760/// An index of -1 is treated as undef, such that the code generator may put
1761/// any value in the corresponding element of the result.
1763 // The memory for Mask is owned by the SelectionDAG's OperandAllocator, and
1764 // is freed when the SelectionDAG object is destroyed.
1765 const int *Mask;
1766
1767protected:
1768 friend class SelectionDAG;
1769
1770 ShuffleVectorSDNode(SDVTList VTs, unsigned Order, const DebugLoc &dl,
1771 const int *M)
1772 : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, VTs), Mask(M) {}
1773
1774public:
1776 EVT VT = getValueType(0);
1777 return ArrayRef(Mask, VT.getVectorNumElements());
1778 }
1779
1780 int getMaskElt(unsigned Idx) const {
1781 assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!");
1782 return Mask[Idx];
1783 }
1784
1785 bool isSplat() const { return isSplatMask(getMask()); }
1786
1787 int getSplatIndex() const { return getSplatMaskIndex(getMask()); }
1788
1789 LLVM_ABI static bool isSplatMask(ArrayRef<int> Mask);
1790
1792 assert(isSplatMask(Mask) && "Cannot get splat index for non-splat!");
1793 for (int Elem : Mask)
1794 if (Elem >= 0)
1795 return Elem;
1796
1797 // We can choose any index value here and be correct because all elements
1798 // are undefined. Return 0 for better potential for callers to simplify.
1799 return 0;
1800 }
1801
1802 /// Change values in a shuffle permute mask assuming
1803 /// the two vector operands have swapped position.
1805 unsigned NumElems = Mask.size();
1806 for (unsigned i = 0; i != NumElems; ++i) {
1807 int idx = Mask[i];
1808 if (idx < 0)
1809 continue;
1810 else if (idx < (int)NumElems)
1811 Mask[i] = idx + NumElems;
1812 else
1813 Mask[i] = idx - NumElems;
1814 }
1815 }
1816
1817 static bool classof(const SDNode *N) {
1818 return N->getOpcode() == ISD::VECTOR_SHUFFLE;
1819 }
1820};
1821
1822class ConstantSDNode : public SDNode {
1823 friend class SelectionDAG;
1824
1825 const ConstantInt *Value;
1826
1827 ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val,
1828 SDVTList VTs)
1829 : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(),
1830 VTs),
1831 Value(val) {
1832 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1833 ConstantSDNodeBits.IsOpaque = isOpaque;
1834 }
1835
1836public:
1837 const ConstantInt *getConstantIntValue() const { return Value; }
1838 const APInt &getAPIntValue() const { return Value->getValue(); }
1839 uint64_t getZExtValue() const { return Value->getZExtValue(); }
1840 int64_t getSExtValue() const { return Value->getSExtValue(); }
1842 return Value->getLimitedValue(Limit);
1843 }
1844 MaybeAlign getMaybeAlignValue() const { return Value->getMaybeAlignValue(); }
1845 Align getAlignValue() const { return Value->getAlignValue(); }
1846
1847 bool isOne() const { return Value->isOne(); }
1848 bool isZero() const { return Value->isZero(); }
1849 bool isAllOnes() const { return Value->isMinusOne(); }
1850 bool isMaxSignedValue() const { return Value->isMaxValue(true); }
1851 bool isMinSignedValue() const { return Value->isMinValue(true); }
1852
1853 bool isOpaque() const { return ConstantSDNodeBits.IsOpaque; }
1854
1855 static bool classof(const SDNode *N) {
1856 return N->getOpcode() == ISD::Constant ||
1857 N->getOpcode() == ISD::TargetConstant;
1858 }
1859};
1860
1862 return cast<ConstantSDNode>(getOperand(Num))->getZExtValue();
1863}
1864
1866 return cast<ConstantSDNode>(this)->getZExtValue();
1867}
1868
1869const APInt &SDNode::getConstantOperandAPInt(unsigned Num) const {
1870 return cast<ConstantSDNode>(getOperand(Num))->getAPIntValue();
1871}
1872
1874 return cast<ConstantSDNode>(this)->getAPIntValue();
1875}
1876
1877class ConstantFPSDNode : public SDNode {
1878 friend class SelectionDAG;
1879
1880 const ConstantFP *Value;
1881
1882 ConstantFPSDNode(bool isTarget, const ConstantFP *val, SDVTList VTs)
1883 : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0,
1884 DebugLoc(), VTs),
1885 Value(val) {
1886 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1887 }
1888
1889public:
1890 const APFloat& getValueAPF() const { return Value->getValueAPF(); }
1891 const ConstantFP *getConstantFPValue() const { return Value; }
1892
1893 /// Return true if the value is positive or negative zero.
1894 bool isZero() const { return Value->isZero(); }
1895
1896 /// Return true if the value is a NaN.
1897 bool isNaN() const { return Value->isNaN(); }
1898
1899 /// Return true if the value is an infinity
1900 bool isInfinity() const { return Value->isInfinity(); }
1901
1902 /// Return true if the value is negative.
1903 bool isNegative() const { return Value->isNegative(); }
1904
1905 /// We don't rely on operator== working on double values, as
1906 /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
1907 /// As such, this method can be used to do an exact bit-for-bit comparison of
1908 /// two floating point values.
1909
1910 /// We leave the version with the double argument here because it's just so
1911 /// convenient to write "2.0" and the like. Without this function we'd
1912 /// have to duplicate its logic everywhere it's called.
1913 bool isExactlyValue(double V) const {
1914 return Value->getValueAPF().isExactlyValue(V);
1915 }
1916 LLVM_ABI bool isExactlyValue(const APFloat &V) const;
1917
1918 LLVM_ABI static bool isValueValidForType(EVT VT, const APFloat &Val);
1919
1920 static bool classof(const SDNode *N) {
1921 return N->getOpcode() == ISD::ConstantFP ||
1922 N->getOpcode() == ISD::TargetConstantFP;
1923 }
1924};
1925
1926std::optional<APInt> SDNode::bitcastToAPInt() const {
1927 if (auto *CN = dyn_cast<ConstantSDNode>(this))
1928 return CN->getAPIntValue();
1929 if (auto *CFPN = dyn_cast<ConstantFPSDNode>(this))
1930 return CFPN->getValueAPF().bitcastToAPInt();
1931 return std::nullopt;
1932}
1933
1934/// Returns true if \p V is a constant integer zero.
1936
1937/// Returns true if \p V is a constant integer zero or an UNDEF node.
1939
1940/// Returns true if \p V is an FP constant with a value of positive zero.
1942
1943/// Returns true if \p V is an integer constant with all bits set.
1945
1946/// Returns true if \p V is a constant integer one.
1948
1949/// Returns true if \p V is a constant min signed integer value.
1951
1952/// Returns true if \p V is a neutral element of Opc with Flags.
1953/// When OperandNo is 0, it checks that V is a left identity. Otherwise, it
1954/// checks that V is a right identity.
1955LLVM_ABI bool isNeutralConstant(unsigned Opc, SDNodeFlags Flags, SDValue V,
1956 unsigned OperandNo);
1957
1958/// Return the non-bitcasted source operand of \p V if it exists.
1959/// If \p V is not a bitcasted value, it is returned as-is.
1961
1962/// Return the non-bitcasted and one-use source operand of \p V if it exists.
1963/// If \p V is not a bitcasted one-use value, it is returned as-is.
1965
1966/// Return the non-extracted vector source operand of \p V if it exists.
1967/// If \p V is not an extracted subvector, it is returned as-is.
1969
1970/// Recursively peek through INSERT_VECTOR_ELT nodes, returning the source
1971/// vector operand of \p V, as long as \p V is an INSERT_VECTOR_ELT operation
1972/// that do not insert into any of the demanded vector elts.
1974 const APInt &DemandedElts);
1975
1976/// Return the non-truncated source operand of \p V if it exists.
1977/// If \p V is not a truncation, it is returned as-is.
1979
1980/// Return the non-frozen source operand of \p V if it exists.
1981/// If \p V is not a freeze, it is returned as-is.
1983 if (V.getOpcode() == ISD::FREEZE)
1984 return V.getOperand(0);
1985 return V;
1986}
1987
1988/// Return the non-frozen source operand of \p V if it exists and \p V has
1989/// a single use. If \p V is not a single-use freeze, it is returned as-is.
1991 if (V.getOpcode() == ISD::FREEZE && V.hasOneUse())
1992 return V.getOperand(0);
1993 return V;
1994}
1995
1996/// Returns true if \p V is a bitwise not operation. Assumes that an all ones
1997/// constant is canonicalized to be operand 1.
1998LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
1999
2000/// If \p V is a bitwise not, returns the inverted operand. Otherwise returns
2001/// an empty SDValue. Only bits set in \p Mask are required to be inverted,
2002/// other bits may be arbitrary.
2004 bool AllowUndefs);
2005
2006/// Returns the SDNode if it is a constant splat BuildVector or constant int.
2007LLVM_ABI ConstantSDNode *isConstOrConstSplat(SDValue N,
2008 bool AllowUndefs = false,
2009 bool AllowTruncation = false);
2010
2011/// Returns the SDNode if it is a demanded constant splat BuildVector or
2012/// constant int.
2013LLVM_ABI ConstantSDNode *isConstOrConstSplat(SDValue N,
2014 const APInt &DemandedElts,
2015 bool AllowUndefs = false,
2016 bool AllowTruncation = false);
2017
2018/// Returns the SDNode if it is a constant splat BuildVector or constant float.
2019LLVM_ABI ConstantFPSDNode *isConstOrConstSplatFP(SDValue N,
2020 bool AllowUndefs = false);
2021
2022/// Returns the SDNode if it is a demanded constant splat BuildVector or
2023/// constant float.
2024LLVM_ABI ConstantFPSDNode *isConstOrConstSplatFP(SDValue N,
2025 const APInt &DemandedElts,
2026 bool AllowUndefs = false);
2027
2028/// Return true if the value is a constant 0 integer or a splatted vector of
2029/// a constant 0 integer (with no undefs by default).
2030/// Build vector implicit truncation is not an issue for null values.
2031LLVM_ABI bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false);
2032
2033/// Return true if the value is a constant 1 integer or a splatted vector of a
2034/// constant 1 integer (with no undefs).
2035/// Build vector implicit truncation is allowed, but the truncated bits need to
2036/// be zero.
2037LLVM_ABI bool isOneOrOneSplat(SDValue V, bool AllowUndefs = false);
2038
2039/// Return true if the value is a constant floating-point value, or a splatted
2040/// vector of a constant floating-point value, of 1.0 (with no undefs).
2041LLVM_ABI bool isOneOrOneSplatFP(SDValue V, bool AllowUndefs = false);
2042
2043/// Return true if the value is a constant -1 integer or a splatted vector of a
2044/// constant -1 integer (with no undefs).
2045/// Does not permit build vector implicit truncation.
2046LLVM_ABI bool isAllOnesOrAllOnesSplat(SDValue V, bool AllowUndefs = false);
2047
2048/// Return true if the value is a constant 1 integer or a splatted vector of a
2049/// constant 1 integer (with no undefs).
2050/// Does not permit build vector implicit truncation.
2051LLVM_ABI bool isOnesOrOnesSplat(SDValue N, bool AllowUndefs = false);
2052
2053/// Return true if the value is a constant 0 integer or a splatted vector of a
2054/// constant 0 integer (with no undefs).
2055/// Build vector implicit truncation is allowed.
2056LLVM_ABI bool isZeroOrZeroSplat(SDValue N, bool AllowUndefs = false);
2057
2058/// Return true if the value is a constant (+/-)0.0 floating-point value or a
2059/// splatted vector thereof (with no undefs).
2060LLVM_ABI bool isZeroOrZeroSplatFP(SDValue N, bool AllowUndefs = false);
2061
2062/// Return true if \p V is either a integer or FP constant.
2065}
2066
2067class GlobalAddressSDNode : public SDNode {
2068 friend class SelectionDAG;
2069
2070 const GlobalValue *TheGlobal;
2071 int64_t Offset;
2072 unsigned TargetFlags;
2073
2074 GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL,
2075 const GlobalValue *GA, SDVTList VTs, int64_t o,
2076 unsigned TF)
2077 : SDNode(Opc, Order, DL, VTs), TheGlobal(GA), Offset(o), TargetFlags(TF) {
2078 }
2079
2080public:
2081 const GlobalValue *getGlobal() const { return TheGlobal; }
2082 int64_t getOffset() const { return Offset; }
2083 unsigned getTargetFlags() const { return TargetFlags; }
2084 // Return the address space this GlobalAddress belongs to.
2085 LLVM_ABI unsigned getAddressSpace() const;
2086
2087 static bool classof(const SDNode *N) {
2088 return N->getOpcode() == ISD::GlobalAddress ||
2089 N->getOpcode() == ISD::TargetGlobalAddress ||
2090 N->getOpcode() == ISD::GlobalTLSAddress ||
2091 N->getOpcode() == ISD::TargetGlobalTLSAddress;
2092 }
2093};
2094
2095class DeactivationSymbolSDNode : public SDNode {
2096 friend class SelectionDAG;
2097
2098 const GlobalValue *TheGlobal;
2099
2100 DeactivationSymbolSDNode(const GlobalValue *GV, SDVTList VTs)
2101 : SDNode(ISD::DEACTIVATION_SYMBOL, 0, DebugLoc(), VTs), TheGlobal(GV) {}
2102
2103public:
2104 const GlobalValue *getGlobal() const { return TheGlobal; }
2105
2106 static bool classof(const SDNode *N) {
2107 return N->getOpcode() == ISD::DEACTIVATION_SYMBOL;
2108 }
2109};
2110
2111class FrameIndexSDNode : public SDNode {
2112 friend class SelectionDAG;
2113
2114 int FI;
2115
2116 FrameIndexSDNode(int fi, SDVTList VTs, bool isTarg)
2117 : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, 0, DebugLoc(),
2118 VTs),
2119 FI(fi) {}
2120
2121public:
2122 int getIndex() const { return FI; }
2123
2124 static bool classof(const SDNode *N) {
2125 return N->getOpcode() == ISD::FrameIndex ||
2126 N->getOpcode() == ISD::TargetFrameIndex;
2127 }
2128};
2129
2130/// This SDNode is used for LIFETIME_START/LIFETIME_END values.
2131class LifetimeSDNode : public SDNode {
2132 friend class SelectionDAG;
2133
2134 LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl,
2135 SDVTList VTs)
2136 : SDNode(Opcode, Order, dl, VTs) {}
2137
2138public:
2139 int64_t getFrameIndex() const {
2140 return cast<FrameIndexSDNode>(getOperand(1))->getIndex();
2141 }
2142
2143 // Methods to support isa and dyn_cast
2144 static bool classof(const SDNode *N) {
2145 return N->getOpcode() == ISD::LIFETIME_START ||
2146 N->getOpcode() == ISD::LIFETIME_END;
2147 }
2148};
2149
2150/// This SDNode is used for PSEUDO_PROBE values, which are the function guid and
2151/// the index of the basic block being probed. A pseudo probe serves as a place
2152/// holder and will be removed at the end of compilation. It does not have any
2153/// operand because we do not want the instruction selection to deal with any.
2154class PseudoProbeSDNode : public SDNode {
2155 friend class SelectionDAG;
2156 uint64_t Guid;
2157 uint64_t Index;
2158 uint32_t Attributes;
2159
2160 PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl,
2161 SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr)
2162 : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index),
2163 Attributes(Attr) {}
2164
2165public:
2166 uint64_t getGuid() const { return Guid; }
2167 uint64_t getIndex() const { return Index; }
2168 uint32_t getAttributes() const { return Attributes; }
2169
2170 // Methods to support isa and dyn_cast
2171 static bool classof(const SDNode *N) {
2172 return N->getOpcode() == ISD::PSEUDO_PROBE;
2173 }
2174};
2175
2176class JumpTableSDNode : public SDNode {
2177 friend class SelectionDAG;
2178
2179 int JTI;
2180 unsigned TargetFlags;
2181
2182 JumpTableSDNode(int jti, SDVTList VTs, bool isTarg, unsigned TF)
2183 : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, 0, DebugLoc(),
2184 VTs),
2185 JTI(jti), TargetFlags(TF) {}
2186
2187public:
2188 int getIndex() const { return JTI; }
2189 unsigned getTargetFlags() const { return TargetFlags; }
2190
2191 static bool classof(const SDNode *N) {
2192 return N->getOpcode() == ISD::JumpTable ||
2193 N->getOpcode() == ISD::TargetJumpTable;
2194 }
2195};
2196
2197class ConstantPoolSDNode : public SDNode {
2198 friend class SelectionDAG;
2199
2200 union {
2203 } Val;
2204 int Offset; // It's a MachineConstantPoolValue if top bit is set.
2205 Align Alignment; // Minimum alignment requirement of CP.
2206 unsigned TargetFlags;
2207
2208 ConstantPoolSDNode(bool isTarget, const Constant *c, SDVTList VTs, int o,
2209 Align Alignment, unsigned TF)
2210 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2211 DebugLoc(), VTs),
2212 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2213 assert(Offset >= 0 && "Offset is too large");
2214 Val.ConstVal = c;
2215 }
2216
2217 ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, SDVTList VTs,
2218 int o, Align Alignment, unsigned TF)
2219 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2220 DebugLoc(), VTs),
2221 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2222 assert(Offset >= 0 && "Offset is too large");
2223 Val.MachineCPVal = v;
2224 Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
2225 }
2226
2227public:
2229 return Offset < 0;
2230 }
2231
2232 const Constant *getConstVal() const {
2233 assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
2234 return Val.ConstVal;
2235 }
2236
2238 assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
2239 return Val.MachineCPVal;
2240 }
2241
2242 int getOffset() const {
2243 return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
2244 }
2245
2246 // Return the alignment of this constant pool object, which is either 0 (for
2247 // default alignment) or the desired value.
2248 Align getAlign() const { return Alignment; }
2249 unsigned getTargetFlags() const { return TargetFlags; }
2250
2251 LLVM_ABI Type *getType() const;
2252
2253 static bool classof(const SDNode *N) {
2254 return N->getOpcode() == ISD::ConstantPool ||
2255 N->getOpcode() == ISD::TargetConstantPool;
2256 }
2257};
2258
2259/// Completely target-dependent object reference.
2261 friend class SelectionDAG;
2262
2263 unsigned TargetFlags;
2264 int Index;
2265 int64_t Offset;
2266
2267public:
2268 TargetIndexSDNode(int Idx, SDVTList VTs, int64_t Ofs, unsigned TF)
2269 : SDNode(ISD::TargetIndex, 0, DebugLoc(), VTs), TargetFlags(TF),
2270 Index(Idx), Offset(Ofs) {}
2271
2272 unsigned getTargetFlags() const { return TargetFlags; }
2273 int getIndex() const { return Index; }
2274 int64_t getOffset() const { return Offset; }
2275
2276 static bool classof(const SDNode *N) {
2277 return N->getOpcode() == ISD::TargetIndex;
2278 }
2279};
2280
2281class BasicBlockSDNode : public SDNode {
2282 friend class SelectionDAG;
2283
2284 MachineBasicBlock *MBB;
2285
2286 /// Debug info is meaningful and potentially useful here, but we create
2287 /// blocks out of order when they're jumped to, which makes it a bit
2288 /// harder. Let's see if we need it first.
2289 explicit BasicBlockSDNode(MachineBasicBlock *mbb)
2290 : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb)
2291 {}
2292
2293public:
2294 MachineBasicBlock *getBasicBlock() const { return MBB; }
2295
2296 static bool classof(const SDNode *N) {
2297 return N->getOpcode() == ISD::BasicBlock;
2298 }
2299};
2300
2301/// A "pseudo-class" with methods for operating on BUILD_VECTORs.
2303public:
2304 // These are constructed as SDNodes and then cast to BuildVectorSDNodes.
2305 explicit BuildVectorSDNode() = delete;
2306
2307 /// Check if this is a constant splat, and if so, find the
2308 /// smallest element size that splats the vector. If MinSplatBits is
2309 /// nonzero, the element size must be at least that large. Note that the
2310 /// splat element may be the entire vector (i.e., a one element vector).
2311 /// Returns the splat element value in SplatValue. Any undefined bits in
2312 /// that value are zero, and the corresponding bits in the SplatUndef mask
2313 /// are set. The SplatBitSize value is set to the splat element size in
2314 /// bits. HasAnyUndefs is set to true if any bits in the vector are
2315 /// undefined. isBigEndian describes the endianness of the target.
2316 LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
2317 unsigned &SplatBitSize, bool &HasAnyUndefs,
2318 unsigned MinSplatBits = 0,
2319 bool isBigEndian = false) const;
2320
2321 /// Returns the demanded splatted value or a null value if this is not a
2322 /// splat.
2323 ///
2324 /// The DemandedElts mask indicates the elements that must be in the splat.
2325 /// If passed a non-null UndefElements bitvector, it will resize it to match
2326 /// the vector width and set the bits where elements are undef.
2327 LLVM_ABI SDValue getSplatValue(const APInt &DemandedElts,
2328 BitVector *UndefElements = nullptr) const;
2329
2330 /// Returns the splatted value or a null value if this is not a splat.
2331 ///
2332 /// If passed a non-null UndefElements bitvector, it will resize it to match
2333 /// the vector width and set the bits where elements are undef.
2334 LLVM_ABI SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
2335
2336 /// Find the shortest repeating sequence of values in the build vector.
2337 ///
2338 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
2339 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
2340 ///
2341 /// Currently this must be a power-of-2 build vector.
2342 /// The DemandedElts mask indicates the elements that must be present,
2343 /// undemanded elements in Sequence may be null (SDValue()). If passed a
2344 /// non-null UndefElements bitvector, it will resize it to match the original
2345 /// vector width and set the bits where elements are undef. If result is
2346 /// false, Sequence will be empty.
2347 LLVM_ABI bool getRepeatedSequence(const APInt &DemandedElts,
2348 SmallVectorImpl<SDValue> &Sequence,
2349 BitVector *UndefElements = nullptr) const;
2350
2351 /// Find the shortest repeating sequence of values in the build vector.
2352 ///
2353 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
2354 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
2355 ///
2356 /// Currently this must be a power-of-2 build vector.
2357 /// If passed a non-null UndefElements bitvector, it will resize it to match
2358 /// the original vector width and set the bits where elements are undef.
2359 /// If result is false, Sequence will be empty.
2361 BitVector *UndefElements = nullptr) const;
2362
2363 /// Returns the demanded splatted constant or null if this is not a constant
2364 /// splat.
2365 ///
2366 /// The DemandedElts mask indicates the elements that must be in the splat.
2367 /// If passed a non-null UndefElements bitvector, it will resize it to match
2368 /// the vector width and set the bits where elements are undef.
2370 getConstantSplatNode(const APInt &DemandedElts,
2371 BitVector *UndefElements = nullptr) const;
2372
2373 /// Returns the splatted constant or null if this is not a constant
2374 /// splat.
2375 ///
2376 /// If passed a non-null UndefElements bitvector, it will resize it to match
2377 /// the vector width and set the bits where elements are undef.
2379 getConstantSplatNode(BitVector *UndefElements = nullptr) const;
2380
2381 /// Returns the demanded splatted constant FP or null if this is not a
2382 /// constant FP splat.
2383 ///
2384 /// The DemandedElts mask indicates the elements that must be in the splat.
2385 /// If passed a non-null UndefElements bitvector, it will resize it to match
2386 /// the vector width and set the bits where elements are undef.
2388 getConstantFPSplatNode(const APInt &DemandedElts,
2389 BitVector *UndefElements = nullptr) const;
2390
2391 /// Returns the splatted constant FP or null if this is not a constant
2392 /// FP splat.
2393 ///
2394 /// If passed a non-null UndefElements bitvector, it will resize it to match
2395 /// the vector width and set the bits where elements are undef.
2397 getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
2398
2399 /// If this is a constant FP splat and the splatted constant FP is an
2400 /// exact power or 2, return the log base 2 integer value. Otherwise,
2401 /// return -1.
2402 ///
2403 /// The BitWidth specifies the necessary bit precision.
2404 LLVM_ABI int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements,
2405 uint32_t BitWidth) const;
2406
2407 /// Extract the raw bit data from a build vector of Undef, Constant or
2408 /// ConstantFP node elements. Each raw bit element will be \p
2409 /// DstEltSizeInBits wide, undef elements are treated as zero, and entirely
2410 /// undefined elements are flagged in \p UndefElements.
2411 LLVM_ABI bool getConstantRawBits(bool IsLittleEndian,
2412 unsigned DstEltSizeInBits,
2413 SmallVectorImpl<APInt> &RawBitElements,
2414 BitVector &UndefElements) const;
2415
2416 LLVM_ABI bool isConstant() const;
2417
2418 /// If this BuildVector is constant and represents an arithmetic sequence
2419 /// "<a, a+n, a+2n, a+3n, ...>" where a is integer and n is a non-zero
2420 /// integer, the value "<a, n>" is returned. Arithmetic is performed modulo
2421 /// 2^BitWidth, so this also matches sequences that wrap around. Poison
2422 /// elements are ignored and can take any value.
2423 LLVM_ABI std::optional<std::pair<APInt, APInt>> isArithmeticSequence() const;
2424
2425 /// Recast bit data \p SrcBitElements to \p DstEltSizeInBits wide elements.
2426 /// Undef elements are treated as zero, and entirely undefined elements are
2427 /// flagged in \p DstUndefElements.
2428 LLVM_ABI static void recastRawBits(bool IsLittleEndian,
2429 unsigned DstEltSizeInBits,
2430 SmallVectorImpl<APInt> &DstBitElements,
2431 ArrayRef<APInt> SrcBitElements,
2432 BitVector &DstUndefElements,
2433 const BitVector &SrcUndefElements);
2434
2435 static bool classof(const SDNode *N) {
2436 return N->getOpcode() == ISD::BUILD_VECTOR;
2437 }
2438};
2439
2440/// An SDNode that holds an arbitrary LLVM IR Value. This is
2441/// used when the SelectionDAG needs to make a simple reference to something
2442/// in the LLVM IR representation.
2443///
2444class SrcValueSDNode : public SDNode {
2445 friend class SelectionDAG;
2446
2447 const Value *V;
2448
2449 /// Create a SrcValue for a general value.
2450 explicit SrcValueSDNode(const Value *v)
2451 : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
2452
2453public:
2454 /// Return the contained Value.
2455 const Value *getValue() const { return V; }
2456
2457 static bool classof(const SDNode *N) {
2458 return N->getOpcode() == ISD::SRCVALUE;
2459 }
2460};
2461
2462class MDNodeSDNode : public SDNode {
2463 friend class SelectionDAG;
2464
2465 const MDNode *MD;
2466
2467 explicit MDNodeSDNode(const MDNode *md)
2468 : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md)
2469 {}
2470
2471public:
2472 const MDNode *getMD() const { return MD; }
2473
2474 static bool classof(const SDNode *N) {
2475 return N->getOpcode() == ISD::MDNODE_SDNODE;
2476 }
2477};
2478
2479class RegisterSDNode : public SDNode {
2480 friend class SelectionDAG;
2481
2482 Register Reg;
2483
2484 RegisterSDNode(Register reg, SDVTList VTs)
2485 : SDNode(ISD::Register, 0, DebugLoc(), VTs), Reg(reg) {}
2486
2487public:
2488 Register getReg() const { return Reg; }
2489
2490 static bool classof(const SDNode *N) {
2491 return N->getOpcode() == ISD::Register;
2492 }
2493};
2494
2495class RegisterMaskSDNode : public SDNode {
2496 friend class SelectionDAG;
2497
2498 // The memory for RegMask is not owned by the node.
2499 const uint32_t *RegMask;
2500
2501 RegisterMaskSDNode(const uint32_t *mask)
2502 : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)),
2503 RegMask(mask) {}
2504
2505public:
2506 const uint32_t *getRegMask() const { return RegMask; }
2507
2508 static bool classof(const SDNode *N) {
2509 return N->getOpcode() == ISD::RegisterMask;
2510 }
2511};
2512
2513class BlockAddressSDNode : public SDNode {
2514 friend class SelectionDAG;
2515
2516 const BlockAddress *BA;
2517 int64_t Offset;
2518 unsigned TargetFlags;
2519
2520 BlockAddressSDNode(unsigned NodeTy, SDVTList VTs, const BlockAddress *ba,
2521 int64_t o, unsigned Flags)
2522 : SDNode(NodeTy, 0, DebugLoc(), VTs), BA(ba), Offset(o),
2523 TargetFlags(Flags) {}
2524
2525public:
2526 const BlockAddress *getBlockAddress() const { return BA; }
2527 int64_t getOffset() const { return Offset; }
2528 unsigned getTargetFlags() const { return TargetFlags; }
2529
2530 static bool classof(const SDNode *N) {
2531 return N->getOpcode() == ISD::BlockAddress ||
2532 N->getOpcode() == ISD::TargetBlockAddress;
2533 }
2534};
2535
2536class LabelSDNode : public SDNode {
2537 friend class SelectionDAG;
2538
2539 MCSymbol *Label;
2540
2541 LabelSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, MCSymbol *L)
2542 : SDNode(Opcode, Order, dl, getSDVTList(MVT::Other)), Label(L) {
2543 assert(LabelSDNode::classof(this) && "not a label opcode");
2544 }
2545
2546public:
2547 MCSymbol *getLabel() const { return Label; }
2548
2549 static bool classof(const SDNode *N) {
2550 return N->getOpcode() == ISD::EH_LABEL ||
2551 N->getOpcode() == ISD::ANNOTATION_LABEL;
2552 }
2553};
2554
2555class ExternalSymbolSDNode : public SDNode {
2556 friend class SelectionDAG;
2557
2558 const char *Symbol;
2559 unsigned TargetFlags;
2560
2561 ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF,
2562 SDVTList VTs)
2563 : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0,
2564 DebugLoc(), VTs),
2565 Symbol(Sym), TargetFlags(TF) {}
2566
2567public:
2568 const char *getSymbol() const { return Symbol; }
2569 unsigned getTargetFlags() const { return TargetFlags; }
2570
2571 static bool classof(const SDNode *N) {
2572 return N->getOpcode() == ISD::ExternalSymbol ||
2573 N->getOpcode() == ISD::TargetExternalSymbol;
2574 }
2575};
2576
2577class MCSymbolSDNode : public SDNode {
2578 friend class SelectionDAG;
2579
2580 MCSymbol *Symbol;
2581
2582 MCSymbolSDNode(MCSymbol *Symbol, SDVTList VTs)
2583 : SDNode(ISD::MCSymbol, 0, DebugLoc(), VTs), Symbol(Symbol) {}
2584
2585public:
2586 MCSymbol *getMCSymbol() const { return Symbol; }
2587
2588 static bool classof(const SDNode *N) {
2589 return N->getOpcode() == ISD::MCSymbol;
2590 }
2591};
2592
2593class CondCodeSDNode : public SDNode {
2594 friend class SelectionDAG;
2595
2596 ISD::CondCode Condition;
2597
2598 explicit CondCodeSDNode(ISD::CondCode Cond)
2599 : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2600 Condition(Cond) {}
2601
2602public:
2603 ISD::CondCode get() const { return Condition; }
2604
2605 static bool classof(const SDNode *N) {
2606 return N->getOpcode() == ISD::CONDCODE;
2607 }
2608};
2609
2610/// This class is used to represent EVT's, which are used
2611/// to parameterize some operations.
2612class VTSDNode : public SDNode {
2613 friend class SelectionDAG;
2614
2615 EVT ValueType;
2616
2617 explicit VTSDNode(EVT VT)
2618 : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2619 ValueType(VT) {}
2620
2621public:
2622 EVT getVT() const { return ValueType; }
2623
2624 static bool classof(const SDNode *N) {
2625 return N->getOpcode() == ISD::VALUETYPE;
2626 }
2627};
2628
2629/// Base class for LoadSDNode and StoreSDNode
2630class LSBaseSDNode : public MemSDNode {
2631public:
2632 LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl,
2633 SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT,
2634 MachineMemOperand *MMO)
2635 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2636 LSBaseSDNodeBits.AddressingMode = AM;
2637 assert(getAddressingMode() == AM && "Value truncated");
2638 }
2639
2640 const SDValue &getOffset() const {
2641 return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
2642 }
2643
2644 /// Return the addressing mode for this load or store:
2645 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2647 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2648 }
2649
2650 /// Return true if this is a pre/post inc/dec load/store.
2651 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2652
2653 /// Return true if this is NOT a pre/post inc/dec load/store.
2654 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2655
2656 static bool classof(const SDNode *N) {
2657 return N->getOpcode() == ISD::LOAD ||
2658 N->getOpcode() == ISD::STORE;
2659 }
2660};
2661
2662/// This class is used to represent ISD::LOAD nodes.
2663class LoadSDNode : public LSBaseSDNode {
2664 friend class SelectionDAG;
2665
2666 LoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2668 MachineMemOperand *MMO)
2669 : LSBaseSDNode(ISD::LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2670 LoadSDNodeBits.ExtTy = ETy;
2671 assert(readMem() && "Load MachineMemOperand is not a load!");
2672 assert(!writeMem() && "Load MachineMemOperand is a store!");
2673 }
2674
2675public:
2676 /// Return whether this is a plain node,
2677 /// or one of the varieties of value-extending loads.
2679 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2680 }
2681
2682 const SDValue &getBasePtr() const { return getOperand(1); }
2683 const SDValue &getOffset() const { return getOperand(2); }
2684
2685 static bool classof(const SDNode *N) {
2686 return N->getOpcode() == ISD::LOAD;
2687 }
2688};
2689
2690/// This class is used to represent ISD::STORE nodes.
2691class StoreSDNode : public LSBaseSDNode {
2692 friend class SelectionDAG;
2693
2694 StoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2695 ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT,
2696 MachineMemOperand *MMO)
2697 : LSBaseSDNode(ISD::STORE, Order, dl, VTs, AM, MemVT, MMO) {
2698 StoreSDNodeBits.IsTruncating = isTrunc;
2699 assert(!readMem() && "Store MachineMemOperand is a load!");
2700 assert(writeMem() && "Store MachineMemOperand is not a store!");
2701 }
2702
2703public:
2704 /// Return true if the op does a truncation before store.
2705 /// For integers this is the same as doing a TRUNCATE and storing the result.
2706 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2707 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2708
2709 const SDValue &getValue() const { return getOperand(1); }
2710 const SDValue &getBasePtr() const { return getOperand(2); }
2711 const SDValue &getOffset() const { return getOperand(3); }
2712
2713 static bool classof(const SDNode *N) {
2714 return N->getOpcode() == ISD::STORE;
2715 }
2716};
2717
2718/// This base class is used to represent VP_LOAD, VP_STORE,
2719/// EXPERIMENTAL_VP_STRIDED_LOAD and EXPERIMENTAL_VP_STRIDED_STORE nodes
2721public:
2722 friend class SelectionDAG;
2723
2724 VPBaseLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2725 const DebugLoc &DL, SDVTList VTs,
2726 ISD::MemIndexedMode AM, EVT MemVT,
2727 MachineMemOperand *MMO)
2728 : MemSDNode(NodeTy, Order, DL, VTs, MemVT, MMO) {
2729 LSBaseSDNodeBits.AddressingMode = AM;
2730 assert(getAddressingMode() == AM && "Value truncated");
2731 }
2732
2733 // VPStridedStoreSDNode (Chain, Data, Ptr, Offset, Stride, Mask, EVL)
2734 // VPStoreSDNode (Chain, Data, Ptr, Offset, Mask, EVL)
2735 // VPStridedLoadSDNode (Chain, Ptr, Offset, Stride, Mask, EVL)
2736 // VPLoadSDNode (Chain, Ptr, Offset, Mask, EVL)
2737 // Mask is a vector of i1 elements;
2738 // the type of EVL is TLI.getVPExplicitVectorLengthTy().
2739 const SDValue &getOffset() const {
2740 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2741 getOpcode() == ISD::VP_LOAD)
2742 ? 2
2743 : 3);
2744 }
2745 const SDValue &getBasePtr() const {
2746 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2747 getOpcode() == ISD::VP_LOAD)
2748 ? 1
2749 : 2);
2750 }
2751 const SDValue &getMask() const {
2752 switch (getOpcode()) {
2753 default:
2754 llvm_unreachable("Invalid opcode");
2755 case ISD::VP_LOAD:
2756 return getOperand(3);
2757 case ISD::VP_STORE:
2758 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2759 return getOperand(4);
2760 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2761 return getOperand(5);
2762 }
2763 }
2764 const SDValue &getVectorLength() const {
2765 switch (getOpcode()) {
2766 default:
2767 llvm_unreachable("Invalid opcode");
2768 case ISD::VP_LOAD:
2769 return getOperand(4);
2770 case ISD::VP_STORE:
2771 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2772 return getOperand(5);
2773 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2774 return getOperand(6);
2775 }
2776 }
2777
2778 /// Return the addressing mode for this load or store:
2779 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2781 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2782 }
2783
2784 /// Return true if this is a pre/post inc/dec load/store.
2785 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2786
2787 /// Return true if this is NOT a pre/post inc/dec load/store.
2788 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2789
2790 static bool classof(const SDNode *N) {
2791 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2792 N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE ||
2793 N->getOpcode() == ISD::VP_LOAD || N->getOpcode() == ISD::VP_STORE;
2794 }
2795};
2796
2797/// This class is used to represent a VP_LOAD node
2799public:
2800 friend class SelectionDAG;
2801
2802 VPLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2803 ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool isExpanding,
2804 EVT MemVT, MachineMemOperand *MMO)
2805 : VPBaseLoadStoreSDNode(ISD::VP_LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2806 LoadSDNodeBits.ExtTy = ETy;
2807 LoadSDNodeBits.IsExpanding = isExpanding;
2808 }
2809
2811 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2812 }
2813
2814 const SDValue &getBasePtr() const { return getOperand(1); }
2815 const SDValue &getOffset() const { return getOperand(2); }
2816 const SDValue &getMask() const { return getOperand(3); }
2817 const SDValue &getVectorLength() const { return getOperand(4); }
2818
2819 static bool classof(const SDNode *N) {
2820 return N->getOpcode() == ISD::VP_LOAD;
2821 }
2822 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2823};
2824
2825/// This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
2827public:
2828 friend class SelectionDAG;
2829
2830 VPStridedLoadSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2832 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2833 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_LOAD, Order, DL, VTs,
2834 AM, MemVT, MMO) {
2835 LoadSDNodeBits.ExtTy = ETy;
2836 LoadSDNodeBits.IsExpanding = IsExpanding;
2837 }
2838
2840 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2841 }
2842
2843 const SDValue &getBasePtr() const { return getOperand(1); }
2844 const SDValue &getOffset() const { return getOperand(2); }
2845 const SDValue &getStride() const { return getOperand(3); }
2846 const SDValue &getMask() const { return getOperand(4); }
2847 const SDValue &getVectorLength() const { return getOperand(5); }
2848
2849 static bool classof(const SDNode *N) {
2850 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD;
2851 }
2852 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2853};
2854
2855/// This class is used to represent a VP_STORE node
2857public:
2858 friend class SelectionDAG;
2859
2860 VPStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2861 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
2862 EVT MemVT, MachineMemOperand *MMO)
2863 : VPBaseLoadStoreSDNode(ISD::VP_STORE, Order, dl, VTs, AM, MemVT, MMO) {
2864 StoreSDNodeBits.IsTruncating = isTrunc;
2865 StoreSDNodeBits.IsCompressing = isCompressing;
2866 }
2867
2868 /// Return true if this is a truncating store.
2869 /// For integers this is the same as doing a TRUNCATE and storing the result.
2870 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2871 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2872
2873 /// Returns true if the op does a compression to the vector before storing.
2874 /// The node contiguously stores the active elements (integers or floats)
2875 /// in src (those with their respective bit set in writemask k) to unaligned
2876 /// memory at base_addr.
2877 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2878
2879 const SDValue &getValue() const { return getOperand(1); }
2880 const SDValue &getBasePtr() const { return getOperand(2); }
2881 const SDValue &getOffset() const { return getOperand(3); }
2882 const SDValue &getMask() const { return getOperand(4); }
2883 const SDValue &getVectorLength() const { return getOperand(5); }
2884
2885 static bool classof(const SDNode *N) {
2886 return N->getOpcode() == ISD::VP_STORE;
2887 }
2888};
2889
2890/// This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
2892public:
2893 friend class SelectionDAG;
2894
2895 VPStridedStoreSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2896 ISD::MemIndexedMode AM, bool IsTrunc, bool IsCompressing,
2897 EVT MemVT, MachineMemOperand *MMO)
2898 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_STORE, Order, DL,
2899 VTs, AM, MemVT, MMO) {
2900 StoreSDNodeBits.IsTruncating = IsTrunc;
2901 StoreSDNodeBits.IsCompressing = IsCompressing;
2902 }
2903
2904 /// Return true if this is a truncating store.
2905 /// For integers this is the same as doing a TRUNCATE and storing the result.
2906 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2907 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2908
2909 /// Returns true if the op does a compression to the vector before storing.
2910 /// The node contiguously stores the active elements (integers or floats)
2911 /// in src (those with their respective bit set in writemask k) to unaligned
2912 /// memory at base_addr.
2913 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2914
2915 const SDValue &getValue() const { return getOperand(1); }
2916 const SDValue &getBasePtr() const { return getOperand(2); }
2917 const SDValue &getOffset() const { return getOperand(3); }
2918 const SDValue &getStride() const { return getOperand(4); }
2919 const SDValue &getMask() const { return getOperand(5); }
2920 const SDValue &getVectorLength() const { return getOperand(6); }
2921
2922 static bool classof(const SDNode *N) {
2923 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE;
2924 }
2925};
2926
2927/// This base class is used to represent MLOAD and MSTORE nodes
2929public:
2930 friend class SelectionDAG;
2931
2932 MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2933 const DebugLoc &dl, SDVTList VTs,
2934 ISD::MemIndexedMode AM, EVT MemVT,
2935 MachineMemOperand *MMO)
2936 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2937 LSBaseSDNodeBits.AddressingMode = AM;
2938 assert(getAddressingMode() == AM && "Value truncated");
2939 }
2940
2941 // MaskedLoadSDNode (Chain, ptr, offset, mask, passthru)
2942 // MaskedStoreSDNode (Chain, data, ptr, offset, mask)
2943 // Mask is a vector of i1 elements
2944 const SDValue &getOffset() const {
2945 return getOperand(getOpcode() == ISD::MLOAD ? 2 : 3);
2946 }
2947 const SDValue &getMask() const {
2948 return getOperand(getOpcode() == ISD::MLOAD ? 3 : 4);
2949 }
2950
2951 /// Return the addressing mode for this load or store:
2952 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2954 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2955 }
2956
2957 /// Return true if this is a pre/post inc/dec load/store.
2958 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2959
2960 /// Return true if this is NOT a pre/post inc/dec load/store.
2961 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2962
2963 static bool classof(const SDNode *N) {
2964 return N->getOpcode() == ISD::MLOAD ||
2965 N->getOpcode() == ISD::MSTORE;
2966 }
2967};
2968
2969/// This class is used to represent an MLOAD node
2971public:
2972 friend class SelectionDAG;
2973
2974 MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2976 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2977 : MaskedLoadStoreSDNode(ISD::MLOAD, Order, dl, VTs, AM, MemVT, MMO) {
2978 LoadSDNodeBits.ExtTy = ETy;
2979 LoadSDNodeBits.IsExpanding = IsExpanding;
2980 }
2981
2983 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2984 }
2985
2986 const SDValue &getBasePtr() const { return getOperand(1); }
2987 const SDValue &getOffset() const { return getOperand(2); }
2988 const SDValue &getMask() const { return getOperand(3); }
2989 const SDValue &getPassThru() const { return getOperand(4); }
2990
2991 static bool classof(const SDNode *N) {
2992 return N->getOpcode() == ISD::MLOAD;
2993 }
2994
2995 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2996};
2997
2998/// This class is used to represent an MSTORE node
3000public:
3001 friend class SelectionDAG;
3002
3003 MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
3004 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
3005 EVT MemVT, MachineMemOperand *MMO)
3006 : MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, VTs, AM, MemVT, MMO) {
3007 StoreSDNodeBits.IsTruncating = isTrunc;
3008 StoreSDNodeBits.IsCompressing = isCompressing;
3009 }
3010
3011 /// Return true if the op does a truncation before store.
3012 /// For integers this is the same as doing a TRUNCATE and storing the result.
3013 /// For floats, it is the same as doing an FP_ROUND and storing the result.
3014 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
3015
3016 /// Returns true if the op does a compression to the vector before storing.
3017 /// The node contiguously stores the active elements (integers or floats)
3018 /// in src (those with their respective bit set in writemask k) to unaligned
3019 /// memory at base_addr.
3020 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
3021
3022 const SDValue &getValue() const { return getOperand(1); }
3023 const SDValue &getBasePtr() const { return getOperand(2); }
3024 const SDValue &getOffset() const { return getOperand(3); }
3025 const SDValue &getMask() const { return getOperand(4); }
3026
3027 static bool classof(const SDNode *N) {
3028 return N->getOpcode() == ISD::MSTORE;
3029 }
3030};
3031
3032/// This is a base class used to represent
3033/// VP_GATHER and VP_SCATTER nodes
3034///
3036public:
3037 friend class SelectionDAG;
3038
3039 VPGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
3040 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3041 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3042 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3043 LSBaseSDNodeBits.AddressingMode = IndexType;
3044 assert(getIndexType() == IndexType && "Value truncated");
3045 }
3046
3047 /// How is Index applied to BasePtr when computing addresses.
3049 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3050 }
3051 bool isIndexScaled() const {
3052 return !cast<ConstantSDNode>(getScale())->isOne();
3053 }
3054 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
3055
3056 // In the both nodes address is Op1, mask is Op2:
3057 // VPGatherSDNode (Chain, base, index, scale, mask, vlen)
3058 // VPScatterSDNode (Chain, value, base, index, scale, mask, vlen)
3059 // Mask is a vector of i1 elements
3060 const SDValue &getBasePtr() const {
3061 return getOperand((getOpcode() == ISD::VP_GATHER) ? 1 : 2);
3062 }
3063 const SDValue &getIndex() const {
3064 return getOperand((getOpcode() == ISD::VP_GATHER) ? 2 : 3);
3065 }
3066 const SDValue &getScale() const {
3067 return getOperand((getOpcode() == ISD::VP_GATHER) ? 3 : 4);
3068 }
3069 const SDValue &getMask() const {
3070 return getOperand((getOpcode() == ISD::VP_GATHER) ? 4 : 5);
3071 }
3072 const SDValue &getVectorLength() const {
3073 return getOperand((getOpcode() == ISD::VP_GATHER) ? 5 : 6);
3074 }
3075
3076 static bool classof(const SDNode *N) {
3077 return N->getOpcode() == ISD::VP_GATHER ||
3078 N->getOpcode() == ISD::VP_SCATTER;
3079 }
3080};
3081
3082/// This class is used to represent an VP_GATHER node
3083///
3085public:
3086 friend class SelectionDAG;
3087
3088 VPGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3089 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3090 : VPGatherScatterSDNode(ISD::VP_GATHER, Order, dl, VTs, MemVT, MMO,
3091 IndexType) {}
3092
3093 static bool classof(const SDNode *N) {
3094 return N->getOpcode() == ISD::VP_GATHER;
3095 }
3096};
3097
3098/// This class is used to represent an VP_SCATTER node
3099///
3101public:
3102 friend class SelectionDAG;
3103
3104 VPScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3105 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3106 : VPGatherScatterSDNode(ISD::VP_SCATTER, Order, dl, VTs, MemVT, MMO,
3107 IndexType) {}
3108
3109 const SDValue &getValue() const { return getOperand(1); }
3110
3111 static bool classof(const SDNode *N) {
3112 return N->getOpcode() == ISD::VP_SCATTER;
3113 }
3114};
3115
3116/// This is a base class used to represent
3117/// MGATHER and MSCATTER nodes
3118///
3120public:
3121 friend class SelectionDAG;
3122
3124 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3125 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3126 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3127 LSBaseSDNodeBits.AddressingMode = IndexType;
3128 assert(getIndexType() == IndexType && "Value truncated");
3129 }
3130
3131 /// How is Index applied to BasePtr when computing addresses.
3133 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3134 }
3135 bool isIndexScaled() const {
3136 return !cast<ConstantSDNode>(getScale())->isOne();
3137 }
3138 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
3139
3140 // In the both nodes address is Op1, mask is Op2:
3141 // MaskedGatherSDNode (Chain, passthru, mask, base, index, scale)
3142 // MaskedScatterSDNode (Chain, value, mask, base, index, scale)
3143 // Mask is a vector of i1 elements
3144 const SDValue &getBasePtr() const { return getOperand(3); }
3145 const SDValue &getIndex() const { return getOperand(4); }
3146 const SDValue &getMask() const { return getOperand(2); }
3147 const SDValue &getScale() const { return getOperand(5); }
3148
3149 static bool classof(const SDNode *N) {
3150 return N->getOpcode() == ISD::MGATHER || N->getOpcode() == ISD::MSCATTER ||
3151 N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
3152 }
3153};
3154
3155/// This class is used to represent an MGATHER node
3156///
3158public:
3159 friend class SelectionDAG;
3160
3161 MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
3162 EVT MemVT, MachineMemOperand *MMO,
3163 ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
3164 : MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, VTs, MemVT, MMO,
3165 IndexType) {
3166 LoadSDNodeBits.ExtTy = ETy;
3167 }
3168
3169 const SDValue &getPassThru() const { return getOperand(1); }
3170
3174
3175 static bool classof(const SDNode *N) {
3176 return N->getOpcode() == ISD::MGATHER;
3177 }
3178};
3179
3180/// This class is used to represent an MSCATTER node
3181///
3183public:
3184 friend class SelectionDAG;
3185
3186 MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
3187 EVT MemVT, MachineMemOperand *MMO,
3188 ISD::MemIndexType IndexType, bool IsTrunc)
3189 : MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, VTs, MemVT, MMO,
3190 IndexType) {
3191 StoreSDNodeBits.IsTruncating = IsTrunc;
3192 }
3193
3194 /// Return true if the op does a truncation before store.
3195 /// For integers this is the same as doing a TRUNCATE and storing the result.
3196 /// For floats, it is the same as doing an FP_ROUND and storing the result.
3197 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
3198
3199 const SDValue &getValue() const { return getOperand(1); }
3200
3201 static bool classof(const SDNode *N) {
3202 return N->getOpcode() == ISD::MSCATTER;
3203 }
3204};
3205
3207public:
3208 friend class SelectionDAG;
3209
3210 MaskedHistogramSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
3211 EVT MemVT, MachineMemOperand *MMO,
3212 ISD::MemIndexType IndexType)
3213 : MaskedGatherScatterSDNode(ISD::EXPERIMENTAL_VECTOR_HISTOGRAM, Order, DL,
3214 VTs, MemVT, MMO, IndexType) {}
3215
3217 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3218 }
3219
3220 const SDValue &getBasePtr() const { return getOperand(3); }
3221 const SDValue &getIndex() const { return getOperand(4); }
3222 const SDValue &getMask() const { return getOperand(2); }
3223 const SDValue &getScale() const { return getOperand(5); }
3224 const SDValue &getInc() const { return getOperand(1); }
3225 const SDValue &getIntID() const { return getOperand(6); }
3226
3227 static bool classof(const SDNode *N) {
3228 return N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
3229 }
3230};
3231
3233public:
3234 friend class SelectionDAG;
3235
3236 VPLoadFFSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, EVT MemVT,
3237 MachineMemOperand *MMO)
3238 : MemSDNode(ISD::VP_LOAD_FF, Order, DL, VTs, MemVT, MMO) {}
3239
3240 const SDValue &getBasePtr() const { return getOperand(1); }
3241 const SDValue &getMask() const { return getOperand(2); }
3242 const SDValue &getVectorLength() const { return getOperand(3); }
3243
3244 static bool classof(const SDNode *N) {
3245 return N->getOpcode() == ISD::VP_LOAD_FF;
3246 }
3247};
3248
3250public:
3251 friend class SelectionDAG;
3252
3253 FPStateAccessSDNode(unsigned NodeTy, unsigned Order, const DebugLoc &dl,
3254 SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
3255 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3256 assert((NodeTy == ISD::GET_FPENV_MEM || NodeTy == ISD::SET_FPENV_MEM) &&
3257 "Expected FP state access node");
3258 }
3259
3260 static bool classof(const SDNode *N) {
3261 return N->getOpcode() == ISD::GET_FPENV_MEM ||
3262 N->getOpcode() == ISD::SET_FPENV_MEM;
3263 }
3264};
3265
3266/// An SDNode that represents everything that will be needed
3267/// to construct a MachineInstr. These nodes are created during the
3268/// instruction selection proper phase.
3269///
3270/// Note that the only supported way to set the `memoperands` is by calling the
3271/// `SelectionDAG::setNodeMemRefs` function as the memory management happens
3272/// inside the DAG rather than in the node.
3273class MachineSDNode : public SDNode {
3274private:
3275 friend class SelectionDAG;
3276
3277 MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, SDVTList VTs)
3278 : SDNode(Opc, Order, DL, VTs) {}
3279
3280 // We use a pointer union between a single `MachineMemOperand` pointer and
3281 // a pointer to an array of `MachineMemOperand` pointers. This is null when
3282 // the number of these is zero, the single pointer variant used when the
3283 // number is one, and the array is used for larger numbers.
3284 //
3285 // The array is allocated via the `SelectionDAG`'s allocator and so will
3286 // always live until the DAG is cleaned up and doesn't require ownership here.
3287 //
3288 // We can't use something simpler like `TinyPtrVector` here because `SDNode`
3289 // subclasses aren't managed in a conforming C++ manner. See the comments on
3290 // `SelectionDAG::MorphNodeTo` which details what all goes on, but the
3291 // constraint here is that these don't manage memory with their constructor or
3292 // destructor and can be initialized to a good state even if they start off
3293 // uninitialized.
3295
3296 // Note that this could be folded into the above `MemRefs` member if doing so
3297 // is advantageous at some point. We don't need to store this in most cases.
3298 // However, at the moment this doesn't appear to make the allocation any
3299 // smaller and makes the code somewhat simpler to read.
3300 int NumMemRefs = 0;
3301
3302public:
3304
3306 // Special case the common cases.
3307 if (NumMemRefs == 0)
3308 return {};
3309 if (NumMemRefs == 1)
3310 return ArrayRef(MemRefs.getAddrOfPtr1(), 1);
3311
3312 // Otherwise we have an actual array.
3313 return ArrayRef(cast<MachineMemOperand **>(MemRefs), NumMemRefs);
3314 }
3315 mmo_iterator memoperands_begin() const { return memoperands().begin(); }
3316 mmo_iterator memoperands_end() const { return memoperands().end(); }
3317 bool memoperands_empty() const { return memoperands().empty(); }
3318
3319 /// Clear out the memory reference descriptor list.
3321 MemRefs = nullptr;
3322 NumMemRefs = 0;
3323 }
3324
3325 static bool classof(const SDNode *N) {
3326 return N->isMachineOpcode();
3327 }
3328};
3329
3330/// An SDNode that records if a register contains a value that is guaranteed to
3331/// be aligned accordingly.
3333 Align Alignment;
3334
3335public:
3336 AssertAlignSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, Align A)
3337 : SDNode(ISD::AssertAlign, Order, DL, VTs), Alignment(A) {}
3338
3339 Align getAlign() const { return Alignment; }
3340
3341 static bool classof(const SDNode *N) {
3342 return N->getOpcode() == ISD::AssertAlign;
3343 }
3344};
3345
3346class SDNodeIterator {
3347 const SDNode *Node;
3348 unsigned Operand;
3349
3350 SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
3351
3352public:
3353 using iterator_category = std::forward_iterator_tag;
3355 using difference_type = std::ptrdiff_t;
3358
3359 bool operator==(const SDNodeIterator& x) const {
3360 return Operand == x.Operand;
3361 }
3362 bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
3363
3365 return Node->getOperand(Operand).getNode();
3366 }
3367 pointer operator->() const { return operator*(); }
3368
3369 SDNodeIterator& operator++() { // Preincrement
3370 ++Operand;
3371 return *this;
3372 }
3373 SDNodeIterator operator++(int) { // Postincrement
3374 SDNodeIterator tmp = *this; ++*this; return tmp;
3375 }
3376 size_t operator-(SDNodeIterator Other) const {
3377 assert(Node == Other.Node &&
3378 "Cannot compare iterators of two different nodes!");
3379 return Operand - Other.Operand;
3380 }
3381
3382 static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); }
3383 static SDNodeIterator end (const SDNode *N) {
3384 return SDNodeIterator(N, N->getNumOperands());
3385 }
3386
3387 unsigned getOperand() const { return Operand; }
3388 const SDNode *getNode() const { return Node; }
3389};
3390
3391template <> struct GraphTraits<SDNode*> {
3392 using NodeRef = SDNode *;
3394
3395 static NodeRef getEntryNode(SDNode *N) { return N; }
3396
3400
3404};
3405
3406/// A representation of the largest SDNode, for use in sizeof().
3407///
3408/// This needs to be a union because the largest node differs on 32 bit systems
3409/// with 4 and 8 byte pointer alignment, respectively.
3414
3415/// The SDNode class with the greatest alignment requirement.
3417
3418namespace ISD {
3419
3420 /// Returns true if the specified node is a non-extending and unindexed load.
3421 inline bool isNormalLoad(const SDNode *N) {
3422 auto *Ld = dyn_cast<LoadSDNode>(N);
3423 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
3424 Ld->getAddressingMode() == ISD::UNINDEXED;
3425 }
3426
3427 /// Returns true if the specified node is a non-extending load.
3428 inline bool isNON_EXTLoad(const SDNode *N) {
3429 auto *Ld = dyn_cast<LoadSDNode>(N);
3430 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD;
3431 }
3432
3433 /// Returns true if the specified node is a EXTLOAD.
3434 inline bool isEXTLoad(const SDNode *N) {
3435 auto *Ld = dyn_cast<LoadSDNode>(N);
3436 return Ld && Ld->getExtensionType() == ISD::EXTLOAD;
3437 }
3438
3439 /// Returns true if the specified node is a SEXTLOAD.
3440 inline bool isSEXTLoad(const SDNode *N) {
3441 auto *Ld = dyn_cast<LoadSDNode>(N);
3442 return Ld && Ld->getExtensionType() == ISD::SEXTLOAD;
3443 }
3444
3445 /// Returns true if the specified node is a ZEXTLOAD.
3446 inline bool isZEXTLoad(const SDNode *N) {
3447 auto *Ld = dyn_cast<LoadSDNode>(N);
3448 return Ld && Ld->getExtensionType() == ISD::ZEXTLOAD;
3449 }
3450
3451 /// Returns true if the specified node is an unindexed load.
3452 inline bool isUNINDEXEDLoad(const SDNode *N) {
3453 auto *Ld = dyn_cast<LoadSDNode>(N);
3454 return Ld && Ld->getAddressingMode() == ISD::UNINDEXED;
3455 }
3456
3457 /// Returns true if the specified node is a non-truncating
3458 /// and unindexed store.
3459 inline bool isNormalStore(const SDNode *N) {
3460 auto *St = dyn_cast<StoreSDNode>(N);
3461 return St && !St->isTruncatingStore() &&
3462 St->getAddressingMode() == ISD::UNINDEXED;
3463 }
3464
3465 /// Returns true if the specified node is an unindexed store.
3466 inline bool isUNINDEXEDStore(const SDNode *N) {
3467 auto *St = dyn_cast<StoreSDNode>(N);
3468 return St && St->getAddressingMode() == ISD::UNINDEXED;
3469 }
3470
3471 /// Returns true if the specified node is a non-extending and unindexed
3472 /// masked load.
3473 inline bool isNormalMaskedLoad(const SDNode *N) {
3474 auto *Ld = dyn_cast<MaskedLoadSDNode>(N);
3475 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
3476 Ld->getAddressingMode() == ISD::UNINDEXED;
3477 }
3478
3479 /// Returns true if the specified node is a non-extending and unindexed
3480 /// masked store.
3481 inline bool isNormalMaskedStore(const SDNode *N) {
3482 auto *St = dyn_cast<MaskedStoreSDNode>(N);
3483 return St && !St->isTruncatingStore() &&
3484 St->getAddressingMode() == ISD::UNINDEXED;
3485 }
3486
3487 /// Attempt to match a unary predicate against a scalar/splat constant or
3488 /// every element of a constant BUILD_VECTOR.
3489 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
3490 template <typename ConstNodeType>
3492 std::function<bool(ConstNodeType *)> Match,
3493 bool AllowUndefs = false,
3494 bool AllowTruncation = false);
3495
3496 /// Hook for matching ConstantSDNode predicate
3498 std::function<bool(ConstantSDNode *)> Match,
3499 bool AllowUndefs = false,
3500 bool AllowTruncation = false) {
3501 return matchUnaryPredicateImpl<ConstantSDNode>(Op, Match, AllowUndefs,
3502 AllowTruncation);
3503 }
3504
3505 /// Hook for matching ConstantFPSDNode predicate
3506 inline bool
3508 std::function<bool(ConstantFPSDNode *)> Match,
3509 bool AllowUndefs = false) {
3510 return matchUnaryPredicateImpl<ConstantFPSDNode>(Op, Match, AllowUndefs);
3511 }
3512
3513 /// Attempt to match a binary predicate against a pair of scalar/splat
3514 /// constants or every element of a pair of constant BUILD_VECTORs.
3515 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
3516 /// If AllowTypeMismatch is true then RetType + ArgTypes don't need to match.
3519 std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
3520 bool AllowUndefs = false, bool AllowTypeMismatch = false);
3521
3522 /// Returns true if the specified value is the overflow result from one
3523 /// of the overflow intrinsic nodes.
3525 unsigned Opc = Op.getOpcode();
3526 return (Op.getResNo() == 1 &&
3527 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
3528 Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO));
3529 }
3530
3531} // end namespace ISD
3532
3533} // end namespace llvm
3534
3535#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.
#define X(NUM, ENUM, NAME)
Definition ELF.h:851
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.
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
size_t size() const
size - Get the array size.
Definition ArrayRef.h:142
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:1065
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 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 std::optional< std::pair< APInt, APInt > > isArithmeticSequence() const
If this BuildVector is constant and represents an arithmetic sequence "<a, a+n, a+2n,...
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:420
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)
This class is used to gather all the unique data bits of a node.
Definition FoldingSet.h:208
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.
AtomicOrdering getFailureOrdering() const
For cmpxchg atomic operations, return the atomic ordering requirements when store does not occur.
bool isUnordered() const
Returns true if this memory operation doesn't have any ordering constraints other than normal aliasin...
const MDNode * getRanges() const
Return the range tag for the memory reference.
bool isAtomic() const
Returns true if this operation has an atomic ordering requirement of unordered or higher,...
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
AtomicOrdering getMergedOrdering() const
Return a single atomic ordering that is at least as strong as both the success and failure orderings ...
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
const MachinePointerInfo & getPointerInfo() const
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
Align getBaseAlign() const
Return the minimum known alignment in bytes of the base address, without the offset.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
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, PointerUnion< MachineMemOperand *, MachineMemOperand ** > MemRefs)
static bool classof(const SDNode *N)
void refineAlignment(ArrayRef< MachineMemOperand * > NewMMOs)
Update this MemSDNode's MachineMemOperand information to reflect the alignment of NewMMOs,...
void refineAlignment(MachineMemOperand *NewMMO)
unsigned getAddressSpace() const
Return the address space for the associated pointer.
size_t getNumMemOperands() const
Return the number of memory operands.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
LLVM_ABI MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT memvt, PointerUnion< MachineMemOperand *, MachineMemOperand ** > memrefs)
Constructor that supports single or multiple MMOs.
Align getAlign() const
PointerUnion< MachineMemOperand *, MachineMemOperand ** > MemRefs
Memory reference information.
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.
void refineRanges(MachineMemOperand *NewMMO)
void refineRanges(ArrayRef< MachineMemOperand * > NewMMOs)
Refine range metadata for all MMOs.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
bool hasUniqueMemOperand() const
Return true if this node has exactly one memory operand.
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)
ArrayRef< MachineMemOperand * > memoperands() const
Return the memory operands for this node.
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 bits of the poi...
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.
bool SchedulerWorklistVisited
Visited state in ScheduleDAGSDNodes::BuildSchedUnits.
void setSchedulerWorklistVisited(bool Visited)
Set visited state for ScheduleDAGSDNodes::BuildSchedUnits.
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.
int CombinerWorklistIndex
Index in worklist of DAGCombiner, or negative if the node is not in the worklist.
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().
bool getSchedulerWorklistVisited() const
Get visited state for ScheduleDAGSDNodes::BuildSchedUnits.
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:46
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:255
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
@ FREEZE
FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or is evaluated to UNDEF),...
Definition ISDOpcodes.h:241
@ 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.
@ Offset
Definition DWP.cpp:557
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition STLExtras.h:830
LLVM_ABI SDValue peekThroughExtractSubvectors(SDValue V)
Return the non-extracted vector source operand of V if it exists.
SDValue peekThroughFreeze(SDValue V)
Return the non-frozen 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:1564
APInt operator&(APInt a, const APInt &b)
Definition APInt.h:2152
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:404
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:1546
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().
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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:299
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:221
constexpr NextUseDistance max(NextUseDistance A, NextUseDistance B)
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:1916
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:2172
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...
SDValue peekThroughOneUseFreeze(SDValue V)
Return the non-frozen source operand of V if it exists and V has a single use.
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:381
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:324
uint64_t getFixedSizeInBits() const
Return the size of the specified fixed width value type in bits.
Definition ValueTypes.h:389
EVT getScalarType() const
If this is a vector type, return the element type, otherwise return this.
Definition ValueTypes.h:331
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Definition ValueTypes.h:344
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 setNoConvergent(bool b)
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 hasNoConvergent() 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