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