LLVM 23.0.0git
SelectionDAGNodes.h
Go to the documentation of this file.
1//===- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the SDNode class and derived classes, which are used to
10// represent the nodes and operations present in a SelectionDAG. These nodes
11// and operations are machine code level operations, with some similarities to
12// the GCC RTL representation.
13//
14// Clients should include the SelectionDAG.h file instead of this file directly.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
19#define LLVM_CODEGEN_SELECTIONDAGNODES_H
20
21#include "llvm/ADT/APFloat.h"
22#include "llvm/ADT/ArrayRef.h"
23#include "llvm/ADT/BitVector.h"
24#include "llvm/ADT/FoldingSet.h"
28#include "llvm/ADT/ilist_node.h"
29#include "llvm/ADT/iterator.h"
36#include "llvm/IR/Constants.h"
37#include "llvm/IR/DebugLoc.h"
38#include "llvm/IR/Instruction.h"
40#include "llvm/IR/Metadata.h"
41#include "llvm/IR/Operator.h"
48#include <algorithm>
49#include <cassert>
50#include <climits>
51#include <cstddef>
52#include <cstdint>
53#include <cstring>
54#include <iterator>
55#include <string>
56#include <tuple>
57#include <utility>
58
59namespace llvm {
60
61class APInt;
62class Constant;
63class GlobalValue;
66class MCSymbol;
67class raw_ostream;
68class SDNode;
69class SelectionDAG;
70class Type;
71class Value;
72
73LLVM_ABI void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
74 bool force = false);
75
76/// This represents a list of ValueType's that has been intern'd by
77/// a SelectionDAG. Instances of this simple value class are returned by
78/// SelectionDAG::getVTList(...).
79///
80struct SDVTList {
81 const EVT *VTs;
82 unsigned int NumVTs;
83};
84
85namespace ISD {
86
87 /// Node predicates
88
89/// If N is a BUILD_VECTOR or SPLAT_VECTOR node whose elements are all the
90/// same constant or undefined, return true and return the constant value in
91/// \p SplatValue.
92LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue);
93
94/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
95/// all of the elements are ~0 or undef. If \p BuildVectorOnly is set to
96/// true, it only checks BUILD_VECTOR.
98 bool BuildVectorOnly = false);
99
100/// Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where
101/// all of the elements are 0 or undef. If \p BuildVectorOnly is set to true, it
102/// only checks BUILD_VECTOR.
104 bool BuildVectorOnly = false);
105
106/// Return true if the specified node is a BUILD_VECTOR where all of the
107/// elements are ~0 or undef.
109
110/// Return true if the specified node is a BUILD_VECTOR where all of the
111/// elements are 0 or undef.
113
114/// Return true if the specified node is a BUILD_VECTOR node of all
115/// ConstantSDNode or undef.
117
118/// Return true if the specified node is a BUILD_VECTOR node of all
119/// ConstantFPSDNode or undef.
121
122/// Returns true if the specified node is a vector where all elements can
123/// be truncated to the specified element size without a loss in meaning.
124LLVM_ABI bool isVectorShrinkable(const SDNode *N, unsigned NewEltSize,
125 bool Signed);
126
127/// Return true if the node has at least one operand and all operands of the
128/// specified node are ISD::UNDEF.
129LLVM_ABI bool allOperandsUndef(const SDNode *N);
130
131/// Return true if the specified node is FREEZE(UNDEF).
133
134} // end namespace ISD
135
136//===----------------------------------------------------------------------===//
137/// Unlike LLVM values, Selection DAG nodes may return multiple
138/// values as the result of a computation. Many nodes return multiple values,
139/// from loads (which define a token and a return value) to ADDC (which returns
140/// a result and a carry value), to calls (which may return an arbitrary number
141/// of values).
142///
143/// As such, each use of a SelectionDAG computation must indicate the node that
144/// computes it as well as which return value to use from that node. This pair
145/// of information is represented with the SDValue value type.
146///
147class SDValue {
148 friend struct DenseMapInfo<SDValue>;
149
150 SDNode *Node = nullptr; // The node defining the value we are using.
151 unsigned ResNo = 0; // Which return value of the node we are using.
152
153public:
154 SDValue() = default;
155 SDValue(SDNode *node, unsigned resno);
156
157 /// get the index which selects a specific result in the SDNode
158 unsigned getResNo() const { return ResNo; }
159
160 /// get the SDNode which holds the desired result
161 SDNode *getNode() const { return Node; }
162
163 /// set the SDNode
164 void setNode(SDNode *N) { Node = N; }
165
166 inline SDNode *operator->() const { return Node; }
167
168 bool operator==(const SDValue &O) const {
169 return Node == O.Node && ResNo == O.ResNo;
170 }
171 bool operator!=(const SDValue &O) const {
172 return !operator==(O);
173 }
174 bool operator<(const SDValue &O) const {
175 return std::tie(Node, ResNo) < std::tie(O.Node, O.ResNo);
176 }
177 explicit operator bool() const {
178 return Node != nullptr;
179 }
180
181 SDValue getValue(unsigned R) const {
182 return SDValue(Node, R);
183 }
184
185 /// Return true if the referenced return value is an operand of N.
186 LLVM_ABI bool isOperandOf(const SDNode *N) const;
187
188 /// Return the ValueType of the referenced return value.
189 inline EVT getValueType() const;
190
191 /// Return the simple ValueType of the referenced return value.
193 return getValueType().getSimpleVT();
194 }
195
196 /// Returns the size of the value in bits.
197 ///
198 /// If the value type is a scalable vector type, the scalable property will
199 /// be set and the runtime size will be a positive integer multiple of the
200 /// base size.
202 return getValueType().getSizeInBits();
203 }
204
208
209 // Forwarding methods - These forward to the corresponding methods in SDNode.
210 inline unsigned getOpcode() const;
211 inline unsigned getNumOperands() const;
212 inline const SDValue &getOperand(unsigned i) const;
213 inline uint64_t getConstantOperandVal(unsigned i) const;
214 inline const APInt &getConstantOperandAPInt(unsigned i) const;
215 inline bool isTargetOpcode() const;
216 inline bool isMachineOpcode() const;
217 inline bool isUndef() const;
218 inline bool isAnyAdd() const;
219 inline unsigned getMachineOpcode() const;
220 inline const DebugLoc &getDebugLoc() const;
221 inline void dump() const;
222 inline void dump(const SelectionDAG *G) const;
223 inline void dumpr() const;
224 inline void dumpr(const SelectionDAG *G) const;
225
226 /// Return true if this operand (which must be a chain) reaches the
227 /// specified operand without crossing any side-effecting instructions.
228 /// In practice, this looks through token factors and non-volatile loads.
229 /// In order to remain efficient, this only
230 /// looks a couple of nodes in, it does not do an exhaustive search.
232 unsigned Depth = 2) const;
233
234 /// Return true if there are no nodes using value ResNo of Node.
235 inline bool use_empty() const;
236
237 /// Return true if there is exactly one node using value ResNo of Node, 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 /// This may only be called if isMachineOpcode returns
761 /// true. It returns the MachineInstr opcode value that the node's opcode
762 /// corresponds to.
763 unsigned getMachineOpcode() const {
764 assert(isMachineOpcode() && "Not a MachineInstr opcode!");
765 return ~NodeType;
766 }
767
768 bool getHasDebugValue() const { return SDNodeBits.HasDebugValue; }
769 void setHasDebugValue(bool b) { SDNodeBits.HasDebugValue = b; }
770
771 bool isDivergent() const { return SDNodeBits.IsDivergent; }
772
773 /// Return true if there are no uses of this node.
774 bool use_empty() const { return UseList == nullptr; }
775
776 /// Return true if there is exactly one use of this node.
777 bool hasOneUse() const { return hasSingleElement(uses()); }
778
779 /// Return the number of uses of this node. This method takes
780 /// time proportional to the number of uses.
781 size_t use_size() const { return std::distance(use_begin(), use_end()); }
782
783 /// Return the unique node id.
784 int getNodeId() const { return NodeId; }
785
786 /// Set unique node id.
787 void setNodeId(int Id) { NodeId = Id; }
788
789 /// Get worklist index for DAGCombiner
791
792 /// Set worklist index for DAGCombiner
794
795 /// Get visited state for ScheduleDAGSDNodes::BuildSchedUnits.
797
798 /// Set visited state for ScheduleDAGSDNodes::BuildSchedUnits.
799 void setSchedulerWorklistVisited(bool Visited) {
800 SchedulerWorklistVisited = Visited;
801 }
802
803 /// Return the node ordering.
804 unsigned getIROrder() const { return IROrder; }
805
806 /// Set the node ordering.
807 void setIROrder(unsigned Order) { IROrder = Order; }
808
809 /// Return the source location info.
810 const DebugLoc &getDebugLoc() const { return debugLoc; }
811
812 /// Set source location info. Try to avoid this, putting
813 /// it in the constructor is preferable.
814 void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); }
815
816 /// This class provides iterator support for SDUse
817 /// operands that use a specific SDNode.
818 class use_iterator {
819 friend class SDNode;
820
821 SDUse *Op = nullptr;
822
823 explicit use_iterator(SDUse *op) : Op(op) {}
824
825 public:
826 using iterator_category = std::forward_iterator_tag;
828 using difference_type = std::ptrdiff_t;
831
832 use_iterator() = default;
833 use_iterator(const use_iterator &I) = default;
834 use_iterator &operator=(const use_iterator &) = default;
835
836 bool operator==(const use_iterator &x) const { return Op == x.Op; }
837 bool operator!=(const use_iterator &x) const {
838 return !operator==(x);
839 }
840
841 // Iterator traversal: forward iteration only.
842 use_iterator &operator++() { // Preincrement
843 assert(Op && "Cannot increment end iterator!");
844 Op = Op->getNext();
845 return *this;
846 }
847
848 use_iterator operator++(int) { // Postincrement
849 use_iterator tmp = *this; ++*this; return tmp;
850 }
851
852 /// Retrieve a pointer to the current user node.
853 SDUse &operator*() const {
854 assert(Op && "Cannot dereference end iterator!");
855 return *Op;
856 }
857
858 SDUse *operator->() const { return &operator*(); }
859 };
860
861 class user_iterator {
862 friend class SDNode;
863 use_iterator UI;
864
865 explicit user_iterator(SDUse *op) : UI(op) {};
866
867 public:
868 using iterator_category = std::forward_iterator_tag;
870 using difference_type = std::ptrdiff_t;
873
874 user_iterator() = default;
875
876 bool operator==(const user_iterator &x) const { return UI == x.UI; }
877 bool operator!=(const user_iterator &x) const { return !operator==(x); }
878
879 user_iterator &operator++() { // Preincrement
880 ++UI;
881 return *this;
882 }
883
884 user_iterator operator++(int) { // Postincrement
885 auto tmp = *this;
886 ++*this;
887 return tmp;
888 }
889
890 // Retrieve a pointer to the current User.
891 SDNode *operator*() const { return UI->getUser(); }
892
893 SDNode *operator->() const { return operator*(); }
894
895 SDUse &getUse() const { return *UI; }
896 };
897
898 /// Provide iteration support to walk over all uses of an SDNode.
900 return use_iterator(UseList);
901 }
902
903 static use_iterator use_end() { return use_iterator(nullptr); }
904
909 return make_range(use_begin(), use_end());
910 }
911
912 /// Provide iteration support to walk over all users of an SDNode.
913 user_iterator user_begin() const { return user_iterator(UseList); }
914
915 static user_iterator user_end() { return user_iterator(nullptr); }
916
921 return make_range(user_begin(), user_end());
922 }
923
924 /// Return true if there are exactly NUSES uses of the indicated value.
925 /// This method ignores uses of other values defined by this operation.
926 bool hasNUsesOfValue(unsigned NUses, unsigned Value) const {
927 assert(Value < getNumValues() && "Bad value!");
928
929 // TODO: Only iterate over uses of a given value of the node
930 for (SDUse &U : uses()) {
931 if (U.getResNo() == Value) {
932 if (NUses == 0)
933 return false;
934 --NUses;
935 }
936 }
937
938 // Found exactly the right number of uses?
939 return NUses == 0;
940 }
941
942 /// Return true if there are any use of the indicated value.
943 /// This method ignores uses of other values defined by this operation.
944 LLVM_ABI bool hasAnyUseOfValue(unsigned Value) const;
945
946 /// Return true if this node is the only use of N.
947 LLVM_ABI bool isOnlyUserOf(const SDNode *N) const;
948
949 /// Return true if this node is an operand of N.
950 LLVM_ABI bool isOperandOf(const SDNode *N) const;
951
952 /// Return true if this node is a predecessor of N.
953 /// NOTE: Implemented on top of hasPredecessor and every bit as
954 /// expensive. Use carefully.
955 bool isPredecessorOf(const SDNode *N) const {
956 return N->hasPredecessor(this);
957 }
958
959 /// Return true if N is a predecessor of this node.
960 /// N is either an operand of this node, or can be reached by recursively
961 /// traversing up the operands.
962 /// NOTE: This is an expensive method. Use it carefully.
963 LLVM_ABI bool hasPredecessor(const SDNode *N) const;
964
965 /// Returns true if N is a predecessor of any node in Worklist. This
966 /// helper keeps Visited and Worklist sets externally to allow unions
967 /// searches to be performed in parallel, caching of results across
968 /// queries and incremental addition to Worklist. Stops early if N is
969 /// found but will resume. Remember to clear Visited and Worklists
970 /// if DAG changes. MaxSteps gives a maximum number of nodes to visit before
971 /// giving up. The TopologicalPrune flag signals that positive NodeIds are
972 /// topologically ordered (Operands have strictly smaller node id) and search
973 /// can be pruned leveraging this.
974 static bool hasPredecessorHelper(const SDNode *N,
977 unsigned int MaxSteps = 0,
978 bool TopologicalPrune = false) {
979 if (Visited.count(N))
980 return true;
981
982 SmallVector<const SDNode *, 8> DeferredNodes;
983 // Node Id's are assigned in three places: As a topological
984 // ordering (> 0), during legalization (results in values set to
985 // 0), new nodes (set to -1). If N has a topolgical id then we
986 // know that all nodes with ids smaller than it cannot be
987 // successors and we need not check them. Filter out all node
988 // that can't be matches. We add them to the worklist before exit
989 // in case of multiple calls. Note that during selection the topological id
990 // may be violated if a node's predecessor is selected before it. We mark
991 // this at selection negating the id of unselected successors and
992 // restricting topological pruning to positive ids.
993
994 int NId = N->getNodeId();
995 // If we Invalidated the Id, reconstruct original NId.
996 if (NId < -1)
997 NId = -(NId + 1);
998
999 bool Found = false;
1000 while (!Worklist.empty()) {
1001 const SDNode *M = Worklist.pop_back_val();
1002 int MId = M->getNodeId();
1003 if (TopologicalPrune && M->getOpcode() != ISD::TokenFactor && (NId > 0) &&
1004 (MId > 0) && (MId < NId)) {
1005 DeferredNodes.push_back(M);
1006 continue;
1007 }
1008 for (const SDValue &OpV : M->op_values()) {
1009 SDNode *Op = OpV.getNode();
1010 if (Visited.insert(Op).second)
1011 Worklist.push_back(Op);
1012 if (Op == N)
1013 Found = true;
1014 }
1015 if (Found)
1016 break;
1017 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
1018 break;
1019 }
1020 // Push deferred nodes back on worklist.
1021 Worklist.append(DeferredNodes.begin(), DeferredNodes.end());
1022 // If we bailed early, conservatively return found.
1023 if (MaxSteps != 0 && Visited.size() >= MaxSteps)
1024 return true;
1025 return Found;
1026 }
1027
1028 /// Return true if all the users of N are contained in Nodes.
1029 /// NOTE: Requires at least one match, but doesn't require them all.
1031 const SDNode *N);
1032
1033 /// Return the number of values used by this operation.
1034 unsigned getNumOperands() const { return NumOperands; }
1035
1036 /// Return the maximum number of operands that a SDNode can hold.
1037 static constexpr size_t getMaxNumOperands() {
1038 return std::numeric_limits<decltype(SDNode::NumOperands)>::max();
1039 }
1040
1041 /// Helper method returns the integer value of a ConstantSDNode operand.
1042 inline uint64_t getConstantOperandVal(unsigned Num) const;
1043
1044 /// Helper method returns the zero-extended integer value of a ConstantSDNode.
1045 inline uint64_t getAsZExtVal() const;
1046
1047 /// Helper method returns the APInt of a ConstantSDNode operand.
1048 inline const APInt &getConstantOperandAPInt(unsigned Num) const;
1049
1050 /// Helper method returns the APInt value of a ConstantSDNode.
1051 inline const APInt &getAsAPIntVal() const;
1052
1053 inline std::optional<APInt> bitcastToAPInt() const;
1054
1055 const SDValue &getOperand(unsigned Num) const {
1056 assert(Num < NumOperands && "Invalid child # of SDNode!");
1057 return OperandList[Num];
1058 }
1059
1061
1062 op_iterator op_begin() const { return OperandList; }
1063 op_iterator op_end() const { return OperandList+NumOperands; }
1064 ArrayRef<SDUse> ops() const { return ArrayRef(op_begin(), op_end()); }
1065
1066 /// Iterator for directly iterating over the operand SDValue's.
1068 : iterator_adaptor_base<value_op_iterator, op_iterator,
1069 std::random_access_iterator_tag, SDValue,
1070 ptrdiff_t, value_op_iterator *,
1071 value_op_iterator *> {
1072 explicit value_op_iterator(SDUse *U = nullptr)
1073 : iterator_adaptor_base(U) {}
1074
1075 const SDValue &operator*() const { return I->get(); }
1076 };
1077
1082
1084 SDVTList X = { ValueList, NumValues };
1085 return X;
1086 }
1087
1088 /// If this node has a glue operand, return the node
1089 /// to which the glue operand points. Otherwise return NULL.
1091 if (getNumOperands() != 0 &&
1092 getOperand(getNumOperands()-1).getValueType() == MVT::Glue)
1093 return getOperand(getNumOperands()-1).getNode();
1094 return nullptr;
1095 }
1096
1097 /// If this node has a glue value with a user, return
1098 /// the user (there is at most one). Otherwise return NULL.
1100 for (SDUse &U : uses())
1101 if (U.getValueType() == MVT::Glue)
1102 return U.getUser();
1103 return nullptr;
1104 }
1105
1106 SDNodeFlags getFlags() const { return Flags; }
1107 void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
1108 void dropFlags(unsigned Mask) { Flags &= ~Mask; }
1109
1110 /// Clear any flags in this node that aren't also set in Flags.
1111 /// If Flags is not in a defined state then this has no effect.
1112 LLVM_ABI void intersectFlagsWith(const SDNodeFlags Flags);
1113
1115 return Flags.Flags & SDNodeFlags::PoisonGeneratingFlags;
1116 }
1117
1118 void setCFIType(uint32_t Type) { CFIType = Type; }
1119 uint32_t getCFIType() const { return CFIType; }
1120
1121 /// Return the number of values defined/returned by this operator.
1122 unsigned getNumValues() const { return NumValues; }
1123
1124 /// Return the type of a specified result.
1125 EVT getValueType(unsigned ResNo) const {
1126 assert(ResNo < NumValues && "Illegal result number!");
1127 return ValueList[ResNo];
1128 }
1129
1130 /// Return the type of a specified result as a simple type.
1131 MVT getSimpleValueType(unsigned ResNo) const {
1132 return getValueType(ResNo).getSimpleVT();
1133 }
1134
1135 /// Returns MVT::getSizeInBits(getValueType(ResNo)).
1136 ///
1137 /// If the value type is a scalable vector type, the scalable property will
1138 /// be set and the runtime size will be a positive integer multiple of the
1139 /// base size.
1140 TypeSize getValueSizeInBits(unsigned ResNo) const {
1141 return getValueType(ResNo).getSizeInBits();
1142 }
1143
1144 using value_iterator = const EVT *;
1145
1146 value_iterator value_begin() const { return ValueList; }
1147 value_iterator value_end() const { return ValueList+NumValues; }
1151
1152 /// Return the opcode of this operation for printing.
1153 LLVM_ABI std::string getOperationName(const SelectionDAG *G = nullptr) const;
1154 LLVM_ABI static const char *getIndexedModeName(ISD::MemIndexedMode AM);
1155 LLVM_ABI void print_types(raw_ostream &OS, const SelectionDAG *G) const;
1156 LLVM_ABI void print_details(raw_ostream &OS, const SelectionDAG *G) const;
1157 LLVM_ABI void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1158 LLVM_ABI void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
1159
1160 /// Print a SelectionDAG node and all children down to
1161 /// the leaves. The given SelectionDAG allows target-specific nodes
1162 /// to be printed in human-readable form. Unlike printr, this will
1163 /// print the whole DAG, including children that appear multiple
1164 /// times.
1165 ///
1167 const SelectionDAG *G = nullptr) const;
1168
1169 /// Print a SelectionDAG node and children up to
1170 /// depth "depth." The given SelectionDAG allows target-specific
1171 /// nodes to be printed in human-readable form. Unlike printr, this
1172 /// will print children that appear multiple times wherever they are
1173 /// used.
1174 ///
1175 LLVM_ABI void printrWithDepth(raw_ostream &O, const SelectionDAG *G = nullptr,
1176 unsigned depth = 100) const;
1177
1178 /// Dump this node, for debugging.
1179 LLVM_ABI void dump() const;
1180
1181 /// Dump (recursively) this node and its use-def subgraph.
1182 LLVM_ABI void dumpr() const;
1183
1184 /// Dump this node, for debugging.
1185 /// The given SelectionDAG allows target-specific nodes to be printed
1186 /// in human-readable form.
1187 LLVM_ABI void dump(const SelectionDAG *G) const;
1188
1189 /// Dump (recursively) this node and its use-def subgraph.
1190 /// The given SelectionDAG allows target-specific nodes to be printed
1191 /// in human-readable form.
1192 LLVM_ABI void dumpr(const SelectionDAG *G) const;
1193
1194 /// printrFull to dbgs(). The given SelectionDAG allows
1195 /// target-specific nodes to be printed in human-readable form.
1196 /// Unlike dumpr, this will print the whole DAG, including children
1197 /// that appear multiple times.
1198 LLVM_ABI void dumprFull(const SelectionDAG *G = nullptr) const;
1199
1200 /// printrWithDepth to dbgs(). The given
1201 /// SelectionDAG allows target-specific nodes to be printed in
1202 /// human-readable form. Unlike dumpr, this will print children
1203 /// that appear multiple times wherever they are used.
1204 ///
1205 LLVM_ABI void dumprWithDepth(const SelectionDAG *G = nullptr,
1206 unsigned depth = 100) const;
1207
1208 /// Gather unique data for the node.
1209 LLVM_ABI void Profile(FoldingSetNodeID &ID) const;
1210
1211 /// This method should only be used by the SDUse class.
1212 void addUse(SDUse &U) { U.addToList(&UseList); }
1213
1214protected:
1216 SDVTList Ret = { getValueTypeList(VT), 1 };
1217 return Ret;
1218 }
1219
1220 /// Create an SDNode.
1221 ///
1222 /// SDNodes are created without any operands, and never own the operand
1223 /// storage. To add operands, see SelectionDAG::createOperands.
1224 SDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs)
1225 : NodeType(Opc), ValueList(VTs.VTs), NumValues(VTs.NumVTs),
1226 IROrder(Order), debugLoc(std::move(dl)) {
1227 memset(&RawSDNodeBits, 0, sizeof(RawSDNodeBits));
1228 assert(NumValues == VTs.NumVTs &&
1229 "NumValues wasn't wide enough for its operands!");
1230 }
1231
1232 /// Release the operands and set this node to have zero operands.
1233 LLVM_ABI void DropOperands();
1234};
1235
1236/// Wrapper class for IR location info (IR ordering and DebugLoc) to be passed
1237/// into SDNode creation functions.
1238/// When an SDNode is created from the DAGBuilder, the DebugLoc is extracted
1239/// from the original Instruction, and IROrder is the ordinal position of
1240/// the instruction.
1241/// When an SDNode is created after the DAG is being built, both DebugLoc and
1242/// the IROrder are propagated from the original SDNode.
1243/// So SDLoc class provides two constructors besides the default one, one to
1244/// be used by the DAGBuilder, the other to be used by others.
1245class SDLoc {
1246private:
1247 DebugLoc DL;
1248 int IROrder = 0;
1249
1250public:
1251 SDLoc() = default;
1252 SDLoc(const SDNode *N) : DL(N->getDebugLoc()), IROrder(N->getIROrder()) {}
1253 SDLoc(const SDValue V) : SDLoc(V.getNode()) {}
1254 SDLoc(const Instruction *I, int Order) : IROrder(Order) {
1255 assert(Order >= 0 && "bad IROrder");
1256 if (I)
1257 DL = I->getDebugLoc();
1258 }
1259
1260 unsigned getIROrder() const { return IROrder; }
1261 const DebugLoc &getDebugLoc() const { return DL; }
1262};
1263
1264// Define inline functions from the SDValue class.
1265
1266inline SDValue::SDValue(SDNode *node, unsigned resno)
1267 : Node(node), ResNo(resno) {
1268 // Explicitly check for !ResNo to avoid use-after-free, because there are
1269 // callers that use SDValue(N, 0) with a deleted N to indicate successful
1270 // combines.
1271 assert((!Node || !ResNo || ResNo < Node->getNumValues()) &&
1272 "Invalid result number for the given node!");
1273 assert(ResNo < -2U && "Cannot use result numbers reserved for DenseMaps.");
1274}
1275
1276inline unsigned SDValue::getOpcode() const {
1277 return Node->getOpcode();
1278}
1279
1281 return Node->getValueType(ResNo);
1282}
1283
1284inline unsigned SDValue::getNumOperands() const {
1285 return Node->getNumOperands();
1286}
1287
1288inline const SDValue &SDValue::getOperand(unsigned i) const {
1289 return Node->getOperand(i);
1290}
1291
1293 return Node->getConstantOperandVal(i);
1294}
1295
1296inline const APInt &SDValue::getConstantOperandAPInt(unsigned i) const {
1297 return Node->getConstantOperandAPInt(i);
1298}
1299
1300inline bool SDValue::isTargetOpcode() const {
1301 return Node->isTargetOpcode();
1302}
1303
1304inline bool SDValue::isMachineOpcode() const {
1305 return Node->isMachineOpcode();
1306}
1307
1308inline unsigned SDValue::getMachineOpcode() const {
1309 return Node->getMachineOpcode();
1310}
1311
1312inline bool SDValue::isUndef() const {
1313 return Node->isUndef();
1314}
1315
1316inline bool SDValue::isAnyAdd() const { return Node->isAnyAdd(); }
1317
1318inline bool SDValue::use_empty() const {
1319 return !Node->hasAnyUseOfValue(ResNo);
1320}
1321
1322inline bool SDValue::hasOneUse() const {
1323 return Node->hasNUsesOfValue(1, ResNo);
1324}
1325
1326inline bool SDValue::hasOneUser() const {
1327 auto Uses = make_filter_range(Node->uses(),
1328 [this](SDUse &U) { return U.get() == *this; });
1329 auto Users = map_range(Uses, [](SDUse &U) { return U.getUser(); });
1330 return all_equal(Users);
1331}
1332
1333inline const DebugLoc &SDValue::getDebugLoc() const {
1334 return Node->getDebugLoc();
1335}
1336
1337inline void SDValue::dump() const {
1338 return Node->dump();
1339}
1340
1341inline void SDValue::dump(const SelectionDAG *G) const {
1342 return Node->dump(G);
1343}
1344
1345inline void SDValue::dumpr() const {
1346 return Node->dumpr();
1347}
1348
1349inline void SDValue::dumpr(const SelectionDAG *G) const {
1350 return Node->dumpr(G);
1351}
1352
1353// Define inline functions from the SDUse class.
1354inline unsigned SDUse::getOperandNo() const {
1355 return this - getUser()->op_begin();
1356}
1357
1358inline void SDUse::set(const SDValue &V) {
1359 if (Val.getNode()) removeFromList();
1360 Val = V;
1361 if (V.getNode())
1362 V->addUse(*this);
1363}
1364
1365inline void SDUse::setInitial(const SDValue &V) {
1366 Val = V;
1367 V->addUse(*this);
1368}
1369
1370inline void SDUse::setNode(SDNode *N) {
1371 if (Val.getNode()) removeFromList();
1372 Val.setNode(N);
1373 if (N) N->addUse(*this);
1374}
1375
1376/// This class is used to form a handle around another node that
1377/// is persistent and is updated across invocations of replaceAllUsesWith on its
1378/// operand. This node should be directly created by end-users and not added to
1379/// the AllNodes list.
1380class HandleSDNode : public SDNode {
1381 SDUse Op;
1382
1383public:
1385 : SDNode(ISD::HANDLENODE, 0, DebugLoc(), getSDVTList(MVT::Other)) {
1386 // HandleSDNodes are never inserted into the DAG, so they won't be
1387 // auto-numbered. Use ID 65535 as a sentinel.
1388 PersistentId = 0xffff;
1389
1390 // Manually set up the operand list. This node type is special in that it's
1391 // always stack allocated and SelectionDAG does not manage its operands.
1392 // TODO: This should either (a) not be in the SDNode hierarchy, or (b) not
1393 // be so special.
1394 Op.setUser(this);
1395 Op.setInitial(X);
1396 NumOperands = 1;
1397 OperandList = &Op;
1398 }
1400
1401 const SDValue &getValue() const { return Op; }
1402};
1403
1405private:
1406 unsigned SrcAddrSpace;
1407 unsigned DestAddrSpace;
1408
1409public:
1410 AddrSpaceCastSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
1411 unsigned SrcAS, unsigned DestAS)
1412 : SDNode(ISD::ADDRSPACECAST, Order, dl, VTs), SrcAddrSpace(SrcAS),
1413 DestAddrSpace(DestAS) {}
1414
1415 unsigned getSrcAddressSpace() const { return SrcAddrSpace; }
1416 unsigned getDestAddressSpace() const { return DestAddrSpace; }
1417
1418 static bool classof(const SDNode *N) {
1419 return N->getOpcode() == ISD::ADDRSPACECAST;
1420 }
1421};
1422
1423/// This is an abstract virtual class for memory operations.
1424class MemSDNode : public SDNode {
1425private:
1426 // VT of in-memory value.
1427 EVT MemoryVT;
1428
1429protected:
1430 /// Memory reference information. Must always have at least one MMO.
1431 /// - MachineMemOperand*: exactly 1 MMO (common case)
1432 /// - MachineMemOperand**: pointer to array, size at offset -1
1434
1435public:
1436 /// Constructor that supports single or multiple MMOs. For single MMO, pass
1437 /// the MMO pointer directly. For multiple MMOs, pre-allocate storage with
1438 /// count at offset -1 and pass pointer to array.
1439 LLVM_ABI
1440 MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs,
1441 EVT memvt,
1443
1444 bool readMem() const { return getMemOperand()->isLoad(); }
1445 bool writeMem() const { return getMemOperand()->isStore(); }
1446
1447 /// Returns alignment and volatility of the memory access
1449 Align getAlign() const { return getMemOperand()->getAlign(); }
1450
1451 /// Return the SubclassData value, without HasDebugValue. This contains an
1452 /// encoding of the volatile flag, as well as bits used by subclasses. This
1453 /// function should only be used to compute a FoldingSetNodeID value.
1454 /// The HasDebugValue bit is masked out because CSE map needs to match
1455 /// nodes with debug info with nodes without debug info. Same is about
1456 /// isDivergent bit.
1457 unsigned getRawSubclassData() const {
1458 uint16_t Data;
1459 union {
1460 char RawSDNodeBits[sizeof(uint16_t)];
1462 };
1463 memcpy(&RawSDNodeBits, &this->RawSDNodeBits, sizeof(this->RawSDNodeBits));
1464 SDNodeBits.HasDebugValue = 0;
1465 SDNodeBits.IsDivergent = false;
1466 memcpy(&Data, &RawSDNodeBits, sizeof(RawSDNodeBits));
1467 return Data;
1468 }
1469
1470 bool isVolatile() const { return MemSDNodeBits.IsVolatile; }
1471 bool isNonTemporal() const { return MemSDNodeBits.IsNonTemporal; }
1472 bool isDereferenceable() const { return MemSDNodeBits.IsDereferenceable; }
1473 bool isInvariant() const { return MemSDNodeBits.IsInvariant; }
1474
1475 // Returns the offset from the location of the access.
1476 int64_t getSrcValueOffset() const { return getMemOperand()->getOffset(); }
1477
1478 /// Returns the AA info that describes the dereference.
1480
1481 /// Returns the Ranges that describes the dereference.
1482 const MDNode *getRanges() const { return getMemOperand()->getRanges(); }
1483
1484 /// Returns the synchronization scope ID for this memory operation.
1486 return getMemOperand()->getSyncScopeID();
1487 }
1488
1489 /// Return the atomic ordering requirements for this memory operation. For
1490 /// cmpxchg atomic operations, return the atomic ordering requirements when
1491 /// store occurs.
1495
1496 /// Return a single atomic ordering that is at least as strong as both the
1497 /// success and failure orderings for an atomic operation. (For operations
1498 /// other than cmpxchg, this is equivalent to getSuccessOrdering().)
1502
1503 /// Return true if the memory operation ordering is Unordered or higher.
1504 bool isAtomic() const { return getMemOperand()->isAtomic(); }
1505
1506 /// Returns true if the memory operation doesn't imply any ordering
1507 /// constraints on surrounding memory operations beyond the normal memory
1508 /// aliasing rules.
1509 bool isUnordered() const { return getMemOperand()->isUnordered(); }
1510
1511 /// Returns true if the memory operation is neither atomic or volatile.
1512 bool isSimple() const { return !isAtomic() && !isVolatile(); }
1513
1514 /// Return the type of the in-memory value.
1515 EVT getMemoryVT() const { return MemoryVT; }
1516
1517 /// Return the unique MachineMemOperand object describing the memory
1518 /// reference performed by operation.
1519 /// Asserts if multiple MMOs are present - use memoperands() instead.
1522 "Use memoperands() for nodes with multiple memory operands");
1524 }
1525
1526 /// Return the number of memory operands.
1527 size_t getNumMemOperands() const {
1529 return 1;
1531 return reinterpret_cast<size_t *>(Array)[-1];
1532 }
1533
1534 /// Return true if this node has exactly one memory operand.
1536
1537 /// Return the memory operands for this node.
1540 return ArrayRef(MemRefs.getAddrOfPtr1(), 1);
1542 size_t Count = reinterpret_cast<size_t *>(Array)[-1];
1543 return ArrayRef(Array, Count);
1544 }
1545
1547 return getMemOperand()->getPointerInfo();
1548 }
1549
1550 /// Return the address space for the associated pointer
1551 unsigned getAddressSpace() const {
1552 return getPointerInfo().getAddrSpace();
1553 }
1554
1555 /// Update this MemSDNode's MachineMemOperand information
1556 /// to reflect the alignment of NewMMOs, if they have greater alignment.
1557 /// This must only be used when the new alignment applies to all users of
1558 /// these MachineMemOperands. The NewMMOs array must parallel memoperands().
1561 assert(NewMMOs.size() == MMOs.size() && "MMO count mismatch");
1562 for (auto [MMO, NewMMO] : zip(MMOs, NewMMOs))
1563 MMO->refineAlignment(NewMMO);
1564 }
1565
1567 refineAlignment(ArrayRef(NewMMO));
1568 }
1569
1570 /// Refine range metadata for all MMOs. The NewMMOs array must parallel
1571 /// memoperands(). For each pair, if ranges differ, the stored range is
1572 /// cleared.
1575 assert(NewMMOs.size() == MMOs.size() && "MMO count mismatch");
1576 // FIXME: Union the ranges instead?
1577 for (auto [MMO, NewMMO] : zip(MMOs, NewMMOs)) {
1578 if (MMO->getRanges() && MMO->getRanges() != NewMMO->getRanges())
1579 MMO->clearRanges();
1580 }
1581 }
1582
1584 refineRanges(ArrayRef(NewMMO));
1585 }
1586
1587 const SDValue &getChain() const { return getOperand(0); }
1588
1589 const SDValue &getBasePtr() const {
1590 switch (getOpcode()) {
1591 case ISD::STORE:
1592 case ISD::ATOMIC_STORE:
1593 case ISD::VP_STORE:
1594 case ISD::MSTORE:
1595 case ISD::VP_SCATTER:
1596 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1597 return getOperand(2);
1598 case ISD::MGATHER:
1599 case ISD::MSCATTER:
1601 return getOperand(3);
1602 default:
1603 return getOperand(1);
1604 }
1605 }
1606
1607 // Methods to support isa and dyn_cast
1608 static bool classof(const SDNode *N) {
1609 // For some targets, we lower some target intrinsics to a MemIntrinsicNode
1610 // with either an intrinsic or a target opcode.
1611 switch (N->getOpcode()) {
1612 case ISD::LOAD:
1613 case ISD::STORE:
1616 case ISD::ATOMIC_SWAP:
1638 case ISD::ATOMIC_LOAD:
1639 case ISD::ATOMIC_STORE:
1640 case ISD::MLOAD:
1641 case ISD::MSTORE:
1642 case ISD::MGATHER:
1643 case ISD::MSCATTER:
1644 case ISD::VP_LOAD:
1645 case ISD::VP_STORE:
1646 case ISD::VP_GATHER:
1647 case ISD::VP_SCATTER:
1648 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
1649 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
1650 case ISD::GET_FPENV_MEM:
1651 case ISD::SET_FPENV_MEM:
1653 return true;
1654 default:
1655 return N->isMemIntrinsic();
1656 }
1657 }
1658};
1659
1660/// This is an SDNode representing atomic operations.
1661class AtomicSDNode : public MemSDNode {
1662public:
1663 AtomicSDNode(unsigned Order, const DebugLoc &dl, unsigned Opc, SDVTList VTL,
1664 EVT MemVT, MachineMemOperand *MMO, ISD::LoadExtType ETy)
1665 : MemSDNode(Opc, Order, dl, VTL, MemVT, MMO) {
1667 MMO->isAtomic()) && "then why are we using an AtomicSDNode?");
1669 "Only atomic load uses ExtTy");
1670 LoadSDNodeBits.ExtTy = ETy;
1671 }
1672
1674 assert(getOpcode() == ISD::ATOMIC_LOAD && "Only used for atomic loads.");
1675 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
1676 }
1677
1678 const SDValue &getBasePtr() const {
1679 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(2) : getOperand(1);
1680 }
1681 const SDValue &getVal() const {
1682 return getOpcode() == ISD::ATOMIC_STORE ? getOperand(1) : getOperand(2);
1683 }
1684
1685 /// Returns true if this SDNode represents cmpxchg atomic operation, false
1686 /// otherwise.
1687 bool isCompareAndSwap() const {
1688 unsigned Op = getOpcode();
1689 return Op == ISD::ATOMIC_CMP_SWAP ||
1691 }
1692
1693 /// For cmpxchg atomic operations, return the atomic ordering requirements
1694 /// when store does not occur.
1696 assert(isCompareAndSwap() && "Must be cmpxchg operation");
1698 }
1699
1700 // Methods to support isa and dyn_cast
1701 static bool classof(const SDNode *N) {
1702 return N->getOpcode() == ISD::ATOMIC_CMP_SWAP ||
1703 N->getOpcode() == ISD::ATOMIC_CMP_SWAP_WITH_SUCCESS ||
1704 N->getOpcode() == ISD::ATOMIC_SWAP ||
1705 N->getOpcode() == ISD::ATOMIC_LOAD_ADD ||
1706 N->getOpcode() == ISD::ATOMIC_LOAD_SUB ||
1707 N->getOpcode() == ISD::ATOMIC_LOAD_AND ||
1708 N->getOpcode() == ISD::ATOMIC_LOAD_CLR ||
1709 N->getOpcode() == ISD::ATOMIC_LOAD_OR ||
1710 N->getOpcode() == ISD::ATOMIC_LOAD_XOR ||
1711 N->getOpcode() == ISD::ATOMIC_LOAD_NAND ||
1712 N->getOpcode() == ISD::ATOMIC_LOAD_MIN ||
1713 N->getOpcode() == ISD::ATOMIC_LOAD_MAX ||
1714 N->getOpcode() == ISD::ATOMIC_LOAD_UMIN ||
1715 N->getOpcode() == ISD::ATOMIC_LOAD_UMAX ||
1716 N->getOpcode() == ISD::ATOMIC_LOAD_FADD ||
1717 N->getOpcode() == ISD::ATOMIC_LOAD_FSUB ||
1718 N->getOpcode() == ISD::ATOMIC_LOAD_FMAX ||
1719 N->getOpcode() == ISD::ATOMIC_LOAD_FMIN ||
1720 N->getOpcode() == ISD::ATOMIC_LOAD_FMAXIMUM ||
1721 N->getOpcode() == ISD::ATOMIC_LOAD_FMINIMUM ||
1722 N->getOpcode() == ISD::ATOMIC_LOAD_UINC_WRAP ||
1723 N->getOpcode() == ISD::ATOMIC_LOAD_UDEC_WRAP ||
1724 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_COND ||
1725 N->getOpcode() == ISD::ATOMIC_LOAD_USUB_SAT ||
1726 N->getOpcode() == ISD::ATOMIC_LOAD ||
1727 N->getOpcode() == ISD::ATOMIC_STORE;
1728 }
1729};
1730
1731/// This SDNode is used for target intrinsics that touch memory and need
1732/// an associated MachineMemOperand. Its opcode may be INTRINSIC_VOID,
1733/// INTRINSIC_W_CHAIN, PREFETCH, or a target-specific memory-referencing
1734/// opcode (see `SelectionDAGTargetInfo::isTargetMemoryOpcode`).
1736public:
1738 unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs,
1739 EVT MemoryVT,
1741 : MemSDNode(Opc, Order, dl, VTs, MemoryVT, MemRefs) {
1742 SDNodeBits.IsMemIntrinsic = true;
1743 }
1744
1745 // Methods to support isa and dyn_cast
1746 static bool classof(const SDNode *N) {
1747 // We lower some target intrinsics to their target opcode
1748 // early a node with a target opcode can be of this class
1749 return N->isMemIntrinsic();
1750 }
1751};
1752
1753/// This SDNode is used to implement the code generator
1754/// support for the llvm IR shufflevector instruction. It combines elements
1755/// from two input vectors into a new input vector, with the selection and
1756/// ordering of elements determined by an array of integers, referred to as
1757/// the shuffle mask. For input vectors of width N, mask indices of 0..N-1
1758/// refer to elements from the LHS input, and indices from N to 2N-1 the RHS.
1759/// An index of -1 is treated as undef, such that the code generator may put
1760/// any value in the corresponding element of the result.
1762 // The memory for Mask is owned by the SelectionDAG's OperandAllocator, and
1763 // is freed when the SelectionDAG object is destroyed.
1764 const int *Mask;
1765
1766protected:
1767 friend class SelectionDAG;
1768
1769 ShuffleVectorSDNode(SDVTList VTs, unsigned Order, const DebugLoc &dl,
1770 const int *M)
1771 : SDNode(ISD::VECTOR_SHUFFLE, Order, dl, VTs), Mask(M) {}
1772
1773public:
1775 EVT VT = getValueType(0);
1776 return ArrayRef(Mask, VT.getVectorNumElements());
1777 }
1778
1779 int getMaskElt(unsigned Idx) const {
1780 assert(Idx < getValueType(0).getVectorNumElements() && "Idx out of range!");
1781 return Mask[Idx];
1782 }
1783
1784 bool isSplat() const { return isSplatMask(getMask()); }
1785
1786 int getSplatIndex() const { return getSplatMaskIndex(getMask()); }
1787
1788 LLVM_ABI static bool isSplatMask(ArrayRef<int> Mask);
1789
1791 assert(isSplatMask(Mask) && "Cannot get splat index for non-splat!");
1792 for (int Elem : Mask)
1793 if (Elem >= 0)
1794 return Elem;
1795
1796 // We can choose any index value here and be correct because all elements
1797 // are undefined. Return 0 for better potential for callers to simplify.
1798 return 0;
1799 }
1800
1801 /// Change values in a shuffle permute mask assuming
1802 /// the two vector operands have swapped position.
1804 unsigned NumElems = Mask.size();
1805 for (unsigned i = 0; i != NumElems; ++i) {
1806 int idx = Mask[i];
1807 if (idx < 0)
1808 continue;
1809 else if (idx < (int)NumElems)
1810 Mask[i] = idx + NumElems;
1811 else
1812 Mask[i] = idx - NumElems;
1813 }
1814 }
1815
1816 static bool classof(const SDNode *N) {
1817 return N->getOpcode() == ISD::VECTOR_SHUFFLE;
1818 }
1819};
1820
1821class ConstantSDNode : public SDNode {
1822 friend class SelectionDAG;
1823
1824 const ConstantInt *Value;
1825
1826 ConstantSDNode(bool isTarget, bool isOpaque, const ConstantInt *val,
1827 SDVTList VTs)
1828 : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, 0, DebugLoc(),
1829 VTs),
1830 Value(val) {
1831 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1832 ConstantSDNodeBits.IsOpaque = isOpaque;
1833 }
1834
1835public:
1836 const ConstantInt *getConstantIntValue() const { return Value; }
1837 const APInt &getAPIntValue() const { return Value->getValue(); }
1838 uint64_t getZExtValue() const { return Value->getZExtValue(); }
1839 int64_t getSExtValue() const { return Value->getSExtValue(); }
1841 return Value->getLimitedValue(Limit);
1842 }
1843 MaybeAlign getMaybeAlignValue() const { return Value->getMaybeAlignValue(); }
1844 Align getAlignValue() const { return Value->getAlignValue(); }
1845
1846 bool isOne() const { return Value->isOne(); }
1847 bool isZero() const { return Value->isZero(); }
1848 bool isAllOnes() const { return Value->isMinusOne(); }
1849 bool isMaxSignedValue() const { return Value->isMaxValue(true); }
1850 bool isMinSignedValue() const { return Value->isMinValue(true); }
1851
1852 bool isOpaque() const { return ConstantSDNodeBits.IsOpaque; }
1853
1854 static bool classof(const SDNode *N) {
1855 return N->getOpcode() == ISD::Constant ||
1856 N->getOpcode() == ISD::TargetConstant;
1857 }
1858};
1859
1861 return cast<ConstantSDNode>(getOperand(Num))->getZExtValue();
1862}
1863
1865 return cast<ConstantSDNode>(this)->getZExtValue();
1866}
1867
1868const APInt &SDNode::getConstantOperandAPInt(unsigned Num) const {
1869 return cast<ConstantSDNode>(getOperand(Num))->getAPIntValue();
1870}
1871
1873 return cast<ConstantSDNode>(this)->getAPIntValue();
1874}
1875
1876class ConstantFPSDNode : public SDNode {
1877 friend class SelectionDAG;
1878
1879 const ConstantFP *Value;
1880
1881 ConstantFPSDNode(bool isTarget, const ConstantFP *val, SDVTList VTs)
1882 : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP, 0,
1883 DebugLoc(), VTs),
1884 Value(val) {
1885 assert(!isa<VectorType>(val->getType()) && "Unexpected vector type!");
1886 }
1887
1888public:
1889 const APFloat& getValueAPF() const { return Value->getValueAPF(); }
1890 const ConstantFP *getConstantFPValue() const { return Value; }
1891
1892 /// Return true if the value is positive or negative zero.
1893 bool isZero() const { return Value->isZero(); }
1894
1895 /// Return true if the value is positive zero.
1896 bool isPosZero() const { return Value->isPosZero(); }
1897
1898 /// Return true if the value is negative zero.
1899 bool isNegZero() const { return Value->isNegZero(); }
1900
1901 /// Return true if the value is a NaN.
1902 bool isNaN() const { return Value->isNaN(); }
1903
1904 /// Return true if the value is an infinity
1905 bool isInfinity() const { return Value->isInfinity(); }
1906
1907 /// Return true if the value is negative.
1908 bool isNegative() const { return Value->isNegative(); }
1909
1910 /// Returns true if this value is exactly +1.0.
1911 bool isOne() const { return Value->isOne(); }
1912
1913 /// Returns true if this value is exactly -1.0.
1914 bool isMinusOne() const { return Value->isMinusOne(); }
1915
1916 /// We don't rely on operator== working on double values, as
1917 /// it returns true for things that are clearly not equal, like -0.0 and 0.0.
1918 /// As such, this method can be used to do an exact bit-for-bit comparison of
1919 /// two floating point values.
1920
1921 /// We leave the version with the double argument here because it's just so
1922 /// convenient to write "2.0" and the like. Without this function we'd
1923 /// have to duplicate its logic everywhere it's called.
1924 bool isExactlyValue(double V) const {
1925 return Value->getValueAPF().isExactlyValue(V);
1926 }
1927 LLVM_ABI bool isExactlyValue(const APFloat &V) const;
1928
1929 LLVM_ABI static bool isValueValidForType(EVT VT, const APFloat &Val);
1930
1931 static bool classof(const SDNode *N) {
1932 return N->getOpcode() == ISD::ConstantFP ||
1933 N->getOpcode() == ISD::TargetConstantFP;
1934 }
1935};
1936
1937std::optional<APInt> SDNode::bitcastToAPInt() const {
1938 if (auto *CN = dyn_cast<ConstantSDNode>(this))
1939 return CN->getAPIntValue();
1940 if (auto *CFPN = dyn_cast<ConstantFPSDNode>(this))
1941 return CFPN->getValueAPF().bitcastToAPInt();
1942 return std::nullopt;
1943}
1944
1945/// Returns true if \p V is a constant integer zero.
1947
1948/// Returns true if \p V is a constant integer zero or an UNDEF node.
1950
1951/// Returns true if \p V is an FP constant with a value of positive zero.
1953
1954/// Returns true if \p V is an integer constant with all bits set.
1956
1957/// Returns true if \p V is a constant integer one.
1959
1960/// Returns true if \p V is a constant min signed integer value.
1962
1963/// Return the non-bitcasted source operand of \p V if it exists.
1964/// If \p V is not a bitcasted value, it is returned as-is.
1966
1967/// Return the non-bitcasted and one-use source operand of \p V if it exists.
1968/// If \p V is not a bitcasted one-use value, it is returned as-is.
1970
1971/// Return the non-extracted vector source operand of \p V if it exists.
1972/// If \p V is not an extracted subvector, it is returned as-is.
1974
1975/// Recursively peek through INSERT_VECTOR_ELT nodes, returning the source
1976/// vector operand of \p V, as long as \p V is an INSERT_VECTOR_ELT operation
1977/// that do not insert into any of the demanded vector elts.
1979 const APInt &DemandedElts);
1980
1981/// Return the non-truncated source operand of \p V if it exists.
1982/// If \p V is not a truncation, it is returned as-is.
1984
1985/// Return the non-frozen source operand of \p V if it exists.
1986/// If \p V is not a freeze, it is returned as-is.
1988 if (V.getOpcode() == ISD::FREEZE)
1989 return V.getOperand(0);
1990 return V;
1991}
1992
1993/// Return the non-frozen source operand of \p V if it exists and \p V has
1994/// a single use. If \p V is not a single-use freeze, it is returned as-is.
1996 if (V.getOpcode() == ISD::FREEZE && V.hasOneUse())
1997 return V.getOperand(0);
1998 return V;
1999}
2000
2001/// Returns true if \p V is a bitwise not operation. Assumes that an all ones
2002/// constant is canonicalized to be operand 1.
2003LLVM_ABI bool isBitwiseNot(SDValue V, bool AllowUndefs = false);
2004
2005/// If \p V is a bitwise not, returns the inverted operand. Otherwise returns
2006/// an empty SDValue. Only bits set in \p Mask are required to be inverted,
2007/// other bits may be arbitrary.
2009 bool AllowUndefs);
2010
2011/// Returns the SDNode if it is a constant splat BuildVector or constant int.
2012LLVM_ABI ConstantSDNode *isConstOrConstSplat(SDValue N,
2013 bool AllowUndefs = false,
2014 bool AllowTruncation = false);
2015
2016/// Returns the SDNode if it is a demanded constant splat BuildVector or
2017/// constant int.
2018LLVM_ABI ConstantSDNode *isConstOrConstSplat(SDValue N,
2019 const APInt &DemandedElts,
2020 bool AllowUndefs = false,
2021 bool AllowTruncation = false);
2022
2023/// Returns the SDNode if it is a constant splat BuildVector or constant float.
2024LLVM_ABI ConstantFPSDNode *isConstOrConstSplatFP(SDValue N,
2025 bool AllowUndefs = false);
2026
2027/// Returns the SDNode if it is a demanded constant splat BuildVector or
2028/// constant float.
2029LLVM_ABI ConstantFPSDNode *isConstOrConstSplatFP(SDValue N,
2030 const APInt &DemandedElts,
2031 bool AllowUndefs = false);
2032
2033/// Return true if the value is a constant 0 integer or a splatted vector of
2034/// a constant 0 integer (with no undefs by default).
2035/// Build vector implicit truncation is not an issue for null values.
2036LLVM_ABI bool isNullOrNullSplat(SDValue V, bool AllowUndefs = false);
2037
2038/// Return true if the value is a constant 1 integer or a splatted vector of a
2039/// constant 1 integer (with no undefs).
2040/// Build vector implicit truncation is allowed, but the truncated bits need to
2041/// be zero.
2042LLVM_ABI bool isOneOrOneSplat(SDValue V, bool AllowUndefs = false);
2043
2044/// Return true if the value is a constant floating-point value, or a splatted
2045/// vector of a constant floating-point value, of 1.0 (with no undefs).
2046LLVM_ABI bool isOneOrOneSplatFP(SDValue V, bool AllowUndefs = false);
2047
2048/// Return true if the value is a constant -1 integer or a splatted vector of a
2049/// constant -1 integer (with no undefs).
2050/// Does not permit build vector implicit truncation.
2051LLVM_ABI bool isAllOnesOrAllOnesSplat(SDValue V, bool AllowUndefs = false);
2052
2053/// Return true if the value is a constant 1 integer or a splatted vector of a
2054/// constant 1 integer (with no undefs).
2055/// Does not permit build vector implicit truncation.
2056LLVM_ABI bool isOnesOrOnesSplat(SDValue N, bool AllowUndefs = false);
2057
2058/// Return true if the value is a constant 0 integer or a splatted vector of a
2059/// constant 0 integer (with no undefs).
2060/// Build vector implicit truncation is allowed.
2061LLVM_ABI bool isZeroOrZeroSplat(SDValue N, bool AllowUndefs = false);
2062
2063/// Return true if the value is a constant (+/-)0.0 floating-point value or a
2064/// splatted vector thereof (with no undefs).
2065LLVM_ABI bool isZeroOrZeroSplatFP(SDValue N, bool AllowUndefs = false);
2066
2067/// Return true if \p V is either a integer or FP constant.
2070}
2071
2072class GlobalAddressSDNode : public SDNode {
2073 friend class SelectionDAG;
2074
2075 const GlobalValue *TheGlobal;
2076 int64_t Offset;
2077 unsigned TargetFlags;
2078
2079 GlobalAddressSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL,
2080 const GlobalValue *GA, SDVTList VTs, int64_t o,
2081 unsigned TF)
2082 : SDNode(Opc, Order, DL, VTs), TheGlobal(GA), Offset(o), TargetFlags(TF) {
2083 }
2084
2085public:
2086 const GlobalValue *getGlobal() const { return TheGlobal; }
2087 int64_t getOffset() const { return Offset; }
2088 unsigned getTargetFlags() const { return TargetFlags; }
2089 // Return the address space this GlobalAddress belongs to.
2090 LLVM_ABI unsigned getAddressSpace() const;
2091
2092 static bool classof(const SDNode *N) {
2093 return N->getOpcode() == ISD::GlobalAddress ||
2094 N->getOpcode() == ISD::TargetGlobalAddress ||
2095 N->getOpcode() == ISD::GlobalTLSAddress ||
2096 N->getOpcode() == ISD::TargetGlobalTLSAddress;
2097 }
2098};
2099
2100class DeactivationSymbolSDNode : public SDNode {
2101 friend class SelectionDAG;
2102
2103 const GlobalValue *TheGlobal;
2104
2105 DeactivationSymbolSDNode(const GlobalValue *GV, SDVTList VTs)
2106 : SDNode(ISD::DEACTIVATION_SYMBOL, 0, DebugLoc(), VTs), TheGlobal(GV) {}
2107
2108public:
2109 const GlobalValue *getGlobal() const { return TheGlobal; }
2110
2111 static bool classof(const SDNode *N) {
2112 return N->getOpcode() == ISD::DEACTIVATION_SYMBOL;
2113 }
2114};
2115
2116class FrameIndexSDNode : public SDNode {
2117 friend class SelectionDAG;
2118
2119 int FI;
2120
2121 FrameIndexSDNode(int fi, SDVTList VTs, bool isTarg)
2122 : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, 0, DebugLoc(),
2123 VTs),
2124 FI(fi) {}
2125
2126public:
2127 int getIndex() const { return FI; }
2128
2129 static bool classof(const SDNode *N) {
2130 return N->getOpcode() == ISD::FrameIndex ||
2131 N->getOpcode() == ISD::TargetFrameIndex;
2132 }
2133};
2134
2135/// This SDNode is used for LIFETIME_START/LIFETIME_END values.
2136class LifetimeSDNode : public SDNode {
2137 friend class SelectionDAG;
2138
2139 LifetimeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl,
2140 SDVTList VTs)
2141 : SDNode(Opcode, Order, dl, VTs) {}
2142
2143public:
2144 int64_t getFrameIndex() const {
2145 return cast<FrameIndexSDNode>(getOperand(1))->getIndex();
2146 }
2147
2148 // Methods to support isa and dyn_cast
2149 static bool classof(const SDNode *N) {
2150 return N->getOpcode() == ISD::LIFETIME_START ||
2151 N->getOpcode() == ISD::LIFETIME_END;
2152 }
2153};
2154
2155/// This SDNode is used for PSEUDO_PROBE values, which are the function guid and
2156/// the index of the basic block being probed. A pseudo probe serves as a place
2157/// holder and will be removed at the end of compilation. It does not have any
2158/// operand because we do not want the instruction selection to deal with any.
2159class PseudoProbeSDNode : public SDNode {
2160 friend class SelectionDAG;
2161 uint64_t Guid;
2162 uint64_t Index;
2163 uint32_t Attributes;
2164
2165 PseudoProbeSDNode(unsigned Opcode, unsigned Order, const DebugLoc &Dl,
2166 SDVTList VTs, uint64_t Guid, uint64_t Index, uint32_t Attr)
2167 : SDNode(Opcode, Order, Dl, VTs), Guid(Guid), Index(Index),
2168 Attributes(Attr) {}
2169
2170public:
2171 uint64_t getGuid() const { return Guid; }
2172 uint64_t getIndex() const { return Index; }
2173 uint32_t getAttributes() const { return Attributes; }
2174
2175 // Methods to support isa and dyn_cast
2176 static bool classof(const SDNode *N) {
2177 return N->getOpcode() == ISD::PSEUDO_PROBE;
2178 }
2179};
2180
2181class JumpTableSDNode : public SDNode {
2182 friend class SelectionDAG;
2183
2184 int JTI;
2185 unsigned TargetFlags;
2186
2187 JumpTableSDNode(int jti, SDVTList VTs, bool isTarg, unsigned TF)
2188 : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, 0, DebugLoc(),
2189 VTs),
2190 JTI(jti), TargetFlags(TF) {}
2191
2192public:
2193 int getIndex() const { return JTI; }
2194 unsigned getTargetFlags() const { return TargetFlags; }
2195
2196 static bool classof(const SDNode *N) {
2197 return N->getOpcode() == ISD::JumpTable ||
2198 N->getOpcode() == ISD::TargetJumpTable;
2199 }
2200};
2201
2202class ConstantPoolSDNode : public SDNode {
2203 friend class SelectionDAG;
2204
2205 union {
2208 } Val;
2209 int Offset; // It's a MachineConstantPoolValue if top bit is set.
2210 Align Alignment; // Minimum alignment requirement of CP.
2211 unsigned TargetFlags;
2212
2213 ConstantPoolSDNode(bool isTarget, const Constant *c, SDVTList VTs, int o,
2214 Align Alignment, unsigned TF)
2215 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2216 DebugLoc(), VTs),
2217 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2218 assert(Offset >= 0 && "Offset is too large");
2219 Val.ConstVal = c;
2220 }
2221
2222 ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, SDVTList VTs,
2223 int o, Align Alignment, unsigned TF)
2224 : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
2225 DebugLoc(), VTs),
2226 Offset(o), Alignment(Alignment), TargetFlags(TF) {
2227 assert(Offset >= 0 && "Offset is too large");
2228 Val.MachineCPVal = v;
2229 Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
2230 }
2231
2232public:
2234 return Offset < 0;
2235 }
2236
2237 const Constant *getConstVal() const {
2238 assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
2239 return Val.ConstVal;
2240 }
2241
2243 assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
2244 return Val.MachineCPVal;
2245 }
2246
2247 int getOffset() const {
2248 return Offset & ~(1 << (sizeof(unsigned)*CHAR_BIT-1));
2249 }
2250
2251 // Return the alignment of this constant pool object, which is either 0 (for
2252 // default alignment) or the desired value.
2253 Align getAlign() const { return Alignment; }
2254 unsigned getTargetFlags() const { return TargetFlags; }
2255
2256 LLVM_ABI Type *getType() const;
2257
2258 static bool classof(const SDNode *N) {
2259 return N->getOpcode() == ISD::ConstantPool ||
2260 N->getOpcode() == ISD::TargetConstantPool;
2261 }
2262};
2263
2264/// Completely target-dependent object reference.
2266 friend class SelectionDAG;
2267
2268 unsigned TargetFlags;
2269 int Index;
2270 int64_t Offset;
2271
2272public:
2273 TargetIndexSDNode(int Idx, SDVTList VTs, int64_t Ofs, unsigned TF)
2274 : SDNode(ISD::TargetIndex, 0, DebugLoc(), VTs), TargetFlags(TF),
2275 Index(Idx), Offset(Ofs) {}
2276
2277 unsigned getTargetFlags() const { return TargetFlags; }
2278 int getIndex() const { return Index; }
2279 int64_t getOffset() const { return Offset; }
2280
2281 static bool classof(const SDNode *N) {
2282 return N->getOpcode() == ISD::TargetIndex;
2283 }
2284};
2285
2286class BasicBlockSDNode : public SDNode {
2287 friend class SelectionDAG;
2288
2289 MachineBasicBlock *MBB;
2290
2291 /// Debug info is meaningful and potentially useful here, but we create
2292 /// blocks out of order when they're jumped to, which makes it a bit
2293 /// harder. Let's see if we need it first.
2294 explicit BasicBlockSDNode(MachineBasicBlock *mbb)
2295 : SDNode(ISD::BasicBlock, 0, DebugLoc(), getSDVTList(MVT::Other)), MBB(mbb)
2296 {}
2297
2298public:
2299 MachineBasicBlock *getBasicBlock() const { return MBB; }
2300
2301 static bool classof(const SDNode *N) {
2302 return N->getOpcode() == ISD::BasicBlock;
2303 }
2304};
2305
2306/// A "pseudo-class" with methods for operating on BUILD_VECTORs.
2308public:
2309 // These are constructed as SDNodes and then cast to BuildVectorSDNodes.
2310 explicit BuildVectorSDNode() = delete;
2311
2312 /// Check if this is a constant splat, and if so, find the
2313 /// smallest element size that splats the vector. If MinSplatBits is
2314 /// nonzero, the element size must be at least that large. Note that the
2315 /// splat element may be the entire vector (i.e., a one element vector).
2316 /// Returns the splat element value in SplatValue. Any undefined bits in
2317 /// that value are zero, and the corresponding bits in the SplatUndef mask
2318 /// are set. The SplatBitSize value is set to the splat element size in
2319 /// bits. HasAnyUndefs is set to true if any bits in the vector are
2320 /// undefined. isBigEndian describes the endianness of the target.
2321 LLVM_ABI bool isConstantSplat(APInt &SplatValue, APInt &SplatUndef,
2322 unsigned &SplatBitSize, bool &HasAnyUndefs,
2323 unsigned MinSplatBits = 0,
2324 bool isBigEndian = false) const;
2325
2326 /// Returns the demanded splatted value or a null value if this is not a
2327 /// splat.
2328 ///
2329 /// The DemandedElts mask indicates the elements that must be in the splat.
2330 /// If passed a non-null UndefElements bitvector, it will resize it to match
2331 /// the vector width and set the bits where elements are undef.
2332 LLVM_ABI SDValue getSplatValue(const APInt &DemandedElts,
2333 BitVector *UndefElements = nullptr) const;
2334
2335 /// Returns the splatted value or a null value if this is not a splat.
2336 ///
2337 /// If passed a non-null UndefElements bitvector, it will resize it to match
2338 /// the vector width and set the bits where elements are undef.
2339 LLVM_ABI SDValue getSplatValue(BitVector *UndefElements = nullptr) const;
2340
2341 /// Find the shortest repeating sequence of values in the build vector.
2342 ///
2343 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
2344 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
2345 ///
2346 /// Currently this must be a power-of-2 build vector.
2347 /// The DemandedElts mask indicates the elements that must be present,
2348 /// undemanded elements in Sequence may be null (SDValue()). If passed a
2349 /// non-null UndefElements bitvector, it will resize it to match the original
2350 /// vector width and set the bits where elements are undef. If result is
2351 /// false, Sequence will be empty.
2352 LLVM_ABI bool getRepeatedSequence(const APInt &DemandedElts,
2353 SmallVectorImpl<SDValue> &Sequence,
2354 BitVector *UndefElements = nullptr) const;
2355
2356 /// Find the shortest repeating sequence of values in the build vector.
2357 ///
2358 /// e.g. { u, X, u, X, u, u, X, u } -> { X }
2359 /// { X, Y, u, Y, u, u, X, u } -> { X, Y }
2360 ///
2361 /// Currently this must be a power-of-2 build vector.
2362 /// If passed a non-null UndefElements bitvector, it will resize it to match
2363 /// the original vector width and set the bits where elements are undef.
2364 /// If result is false, Sequence will be empty.
2366 BitVector *UndefElements = nullptr) const;
2367
2368 /// Returns the demanded splatted constant or null if this is not a constant
2369 /// splat.
2370 ///
2371 /// The DemandedElts mask indicates the elements that must be in the splat.
2372 /// If passed a non-null UndefElements bitvector, it will resize it to match
2373 /// the vector width and set the bits where elements are undef.
2375 getConstantSplatNode(const APInt &DemandedElts,
2376 BitVector *UndefElements = nullptr) const;
2377
2378 /// Returns the splatted constant or null if this is not a constant
2379 /// splat.
2380 ///
2381 /// If passed a non-null UndefElements bitvector, it will resize it to match
2382 /// the vector width and set the bits where elements are undef.
2384 getConstantSplatNode(BitVector *UndefElements = nullptr) const;
2385
2386 /// Returns the demanded splatted constant FP or null if this is not a
2387 /// constant FP splat.
2388 ///
2389 /// The DemandedElts mask indicates the elements that must be in the splat.
2390 /// If passed a non-null UndefElements bitvector, it will resize it to match
2391 /// the vector width and set the bits where elements are undef.
2393 getConstantFPSplatNode(const APInt &DemandedElts,
2394 BitVector *UndefElements = nullptr) const;
2395
2396 /// Returns the splatted constant FP or null if this is not a constant
2397 /// FP splat.
2398 ///
2399 /// If passed a non-null UndefElements bitvector, it will resize it to match
2400 /// the vector width and set the bits where elements are undef.
2402 getConstantFPSplatNode(BitVector *UndefElements = nullptr) const;
2403
2404 /// If this is a constant FP splat and the splatted constant FP is an
2405 /// exact power or 2, return the log base 2 integer value. Otherwise,
2406 /// return -1.
2407 ///
2408 /// The BitWidth specifies the necessary bit precision.
2409 LLVM_ABI int32_t getConstantFPSplatPow2ToLog2Int(BitVector *UndefElements,
2410 uint32_t BitWidth) const;
2411
2412 /// Extract the raw bit data from a build vector of Undef, Constant or
2413 /// ConstantFP node elements. Each raw bit element will be \p
2414 /// DstEltSizeInBits wide, undef elements are treated as zero, and entirely
2415 /// undefined elements are flagged in \p UndefElements.
2416 LLVM_ABI bool getConstantRawBits(bool IsLittleEndian,
2417 unsigned DstEltSizeInBits,
2418 SmallVectorImpl<APInt> &RawBitElements,
2419 BitVector &UndefElements) const;
2420
2421 LLVM_ABI bool isConstant() const;
2422
2423 /// If this BuildVector is constant and represents an arithmetic sequence
2424 /// "<a, a+n, a+2n, a+3n, ...>" where a is integer and n is a non-zero
2425 /// integer, the value "<a, n>" is returned. Arithmetic is performed modulo
2426 /// 2^BitWidth, so this also matches sequences that wrap around. Poison
2427 /// elements are ignored and can take any value.
2428 LLVM_ABI std::optional<std::pair<APInt, APInt>> isArithmeticSequence() const;
2429
2430 /// Recast bit data \p SrcBitElements to \p DstEltSizeInBits wide elements.
2431 /// Undef elements are treated as zero, and entirely undefined elements are
2432 /// flagged in \p DstUndefElements.
2433 LLVM_ABI static void recastRawBits(bool IsLittleEndian,
2434 unsigned DstEltSizeInBits,
2435 SmallVectorImpl<APInt> &DstBitElements,
2436 ArrayRef<APInt> SrcBitElements,
2437 BitVector &DstUndefElements,
2438 const BitVector &SrcUndefElements);
2439
2440 static bool classof(const SDNode *N) {
2441 return N->getOpcode() == ISD::BUILD_VECTOR;
2442 }
2443};
2444
2445/// An SDNode that holds an arbitrary LLVM IR Value. This is
2446/// used when the SelectionDAG needs to make a simple reference to something
2447/// in the LLVM IR representation.
2448///
2449class SrcValueSDNode : public SDNode {
2450 friend class SelectionDAG;
2451
2452 const Value *V;
2453
2454 /// Create a SrcValue for a general value.
2455 explicit SrcValueSDNode(const Value *v)
2456 : SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
2457
2458public:
2459 /// Return the contained Value.
2460 const Value *getValue() const { return V; }
2461
2462 static bool classof(const SDNode *N) {
2463 return N->getOpcode() == ISD::SRCVALUE;
2464 }
2465};
2466
2467class MDNodeSDNode : public SDNode {
2468 friend class SelectionDAG;
2469
2470 const MDNode *MD;
2471
2472 explicit MDNodeSDNode(const MDNode *md)
2473 : SDNode(ISD::MDNODE_SDNODE, 0, DebugLoc(), getSDVTList(MVT::Other)), MD(md)
2474 {}
2475
2476public:
2477 const MDNode *getMD() const { return MD; }
2478
2479 static bool classof(const SDNode *N) {
2480 return N->getOpcode() == ISD::MDNODE_SDNODE;
2481 }
2482};
2483
2484class RegisterSDNode : public SDNode {
2485 friend class SelectionDAG;
2486
2487 Register Reg;
2488
2489 RegisterSDNode(Register reg, SDVTList VTs)
2490 : SDNode(ISD::Register, 0, DebugLoc(), VTs), Reg(reg) {}
2491
2492public:
2493 Register getReg() const { return Reg; }
2494
2495 static bool classof(const SDNode *N) {
2496 return N->getOpcode() == ISD::Register;
2497 }
2498};
2499
2500class RegisterMaskSDNode : public SDNode {
2501 friend class SelectionDAG;
2502
2503 // The memory for RegMask is not owned by the node.
2504 const uint32_t *RegMask;
2505
2506 RegisterMaskSDNode(const uint32_t *mask)
2507 : SDNode(ISD::RegisterMask, 0, DebugLoc(), getSDVTList(MVT::Untyped)),
2508 RegMask(mask) {}
2509
2510public:
2511 const uint32_t *getRegMask() const { return RegMask; }
2512
2513 static bool classof(const SDNode *N) {
2514 return N->getOpcode() == ISD::RegisterMask;
2515 }
2516};
2517
2518class BlockAddressSDNode : public SDNode {
2519 friend class SelectionDAG;
2520
2521 const BlockAddress *BA;
2522 int64_t Offset;
2523 unsigned TargetFlags;
2524
2525 BlockAddressSDNode(unsigned NodeTy, SDVTList VTs, const BlockAddress *ba,
2526 int64_t o, unsigned Flags)
2527 : SDNode(NodeTy, 0, DebugLoc(), VTs), BA(ba), Offset(o),
2528 TargetFlags(Flags) {}
2529
2530public:
2531 const BlockAddress *getBlockAddress() const { return BA; }
2532 int64_t getOffset() const { return Offset; }
2533 unsigned getTargetFlags() const { return TargetFlags; }
2534
2535 static bool classof(const SDNode *N) {
2536 return N->getOpcode() == ISD::BlockAddress ||
2537 N->getOpcode() == ISD::TargetBlockAddress;
2538 }
2539};
2540
2541class LabelSDNode : public SDNode {
2542 friend class SelectionDAG;
2543
2544 MCSymbol *Label;
2545
2546 LabelSDNode(unsigned Opcode, unsigned Order, const DebugLoc &dl, MCSymbol *L)
2547 : SDNode(Opcode, Order, dl, getSDVTList(MVT::Other)), Label(L) {
2548 assert(LabelSDNode::classof(this) && "not a label opcode");
2549 }
2550
2551public:
2552 MCSymbol *getLabel() const { return Label; }
2553
2554 static bool classof(const SDNode *N) {
2555 return N->getOpcode() == ISD::EH_LABEL ||
2556 N->getOpcode() == ISD::ANNOTATION_LABEL;
2557 }
2558};
2559
2560class ExternalSymbolSDNode : public SDNode {
2561 friend class SelectionDAG;
2562
2563 const char *Symbol;
2564 unsigned TargetFlags;
2565
2566 ExternalSymbolSDNode(bool isTarget, const char *Sym, unsigned TF,
2567 SDVTList VTs)
2568 : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, 0,
2569 DebugLoc(), VTs),
2570 Symbol(Sym), TargetFlags(TF) {}
2571
2572public:
2573 const char *getSymbol() const { return Symbol; }
2574 unsigned getTargetFlags() const { return TargetFlags; }
2575
2576 static bool classof(const SDNode *N) {
2577 return N->getOpcode() == ISD::ExternalSymbol ||
2578 N->getOpcode() == ISD::TargetExternalSymbol;
2579 }
2580};
2581
2582class MCSymbolSDNode : public SDNode {
2583 friend class SelectionDAG;
2584
2585 MCSymbol *Symbol;
2586
2587 MCSymbolSDNode(MCSymbol *Symbol, SDVTList VTs)
2588 : SDNode(ISD::MCSymbol, 0, DebugLoc(), VTs), Symbol(Symbol) {}
2589
2590public:
2591 MCSymbol *getMCSymbol() const { return Symbol; }
2592
2593 static bool classof(const SDNode *N) {
2594 return N->getOpcode() == ISD::MCSymbol;
2595 }
2596};
2597
2598class CondCodeSDNode : public SDNode {
2599 friend class SelectionDAG;
2600
2601 ISD::CondCode Condition;
2602
2603 explicit CondCodeSDNode(ISD::CondCode Cond)
2604 : SDNode(ISD::CONDCODE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2605 Condition(Cond) {}
2606
2607public:
2608 ISD::CondCode get() const { return Condition; }
2609
2610 static bool classof(const SDNode *N) {
2611 return N->getOpcode() == ISD::CONDCODE;
2612 }
2613};
2614
2615/// This class is used to represent EVT's, which are used
2616/// to parameterize some operations.
2617class VTSDNode : public SDNode {
2618 friend class SelectionDAG;
2619
2620 EVT ValueType;
2621
2622 explicit VTSDNode(EVT VT)
2623 : SDNode(ISD::VALUETYPE, 0, DebugLoc(), getSDVTList(MVT::Other)),
2624 ValueType(VT) {}
2625
2626public:
2627 EVT getVT() const { return ValueType; }
2628
2629 static bool classof(const SDNode *N) {
2630 return N->getOpcode() == ISD::VALUETYPE;
2631 }
2632};
2633
2634/// Base class for LoadSDNode and StoreSDNode
2635class LSBaseSDNode : public MemSDNode {
2636public:
2637 LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl,
2638 SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT,
2639 MachineMemOperand *MMO)
2640 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2641 LSBaseSDNodeBits.AddressingMode = AM;
2642 assert(getAddressingMode() == AM && "Value truncated");
2643 }
2644
2645 const SDValue &getOffset() const {
2646 return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
2647 }
2648
2649 /// Return the addressing mode for this load or store:
2650 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2652 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2653 }
2654
2655 /// Return true if this is a pre/post inc/dec load/store.
2656 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2657
2658 /// Return true if this is NOT a pre/post inc/dec load/store.
2659 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2660
2661 static bool classof(const SDNode *N) {
2662 return N->getOpcode() == ISD::LOAD ||
2663 N->getOpcode() == ISD::STORE;
2664 }
2665};
2666
2667/// This class is used to represent ISD::LOAD nodes.
2668class LoadSDNode : public LSBaseSDNode {
2669 friend class SelectionDAG;
2670
2671 LoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2673 MachineMemOperand *MMO)
2674 : LSBaseSDNode(ISD::LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2675 LoadSDNodeBits.ExtTy = ETy;
2676 assert(readMem() && "Load MachineMemOperand is not a load!");
2677 assert(!writeMem() && "Load MachineMemOperand is a store!");
2678 }
2679
2680public:
2681 /// Return whether this is a plain node,
2682 /// or one of the varieties of value-extending loads.
2684 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2685 }
2686
2687 const SDValue &getBasePtr() const { return getOperand(1); }
2688 const SDValue &getOffset() const { return getOperand(2); }
2689
2690 static bool classof(const SDNode *N) {
2691 return N->getOpcode() == ISD::LOAD;
2692 }
2693};
2694
2695/// This class is used to represent ISD::STORE nodes.
2696class StoreSDNode : public LSBaseSDNode {
2697 friend class SelectionDAG;
2698
2699 StoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2700 ISD::MemIndexedMode AM, bool isTrunc, EVT MemVT,
2701 MachineMemOperand *MMO)
2702 : LSBaseSDNode(ISD::STORE, Order, dl, VTs, AM, MemVT, MMO) {
2703 StoreSDNodeBits.IsTruncating = isTrunc;
2704 assert(!readMem() && "Store MachineMemOperand is a load!");
2705 assert(writeMem() && "Store MachineMemOperand is not a store!");
2706 }
2707
2708public:
2709 /// Return true if the op does a truncation before store.
2710 /// For integers this is the same as doing a TRUNCATE and storing the result.
2711 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2712 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2713
2714 const SDValue &getValue() const { return getOperand(1); }
2715 const SDValue &getBasePtr() const { return getOperand(2); }
2716 const SDValue &getOffset() const { return getOperand(3); }
2717
2718 static bool classof(const SDNode *N) {
2719 return N->getOpcode() == ISD::STORE;
2720 }
2721};
2722
2723/// This base class is used to represent VP_LOAD, VP_STORE,
2724/// EXPERIMENTAL_VP_STRIDED_LOAD and EXPERIMENTAL_VP_STRIDED_STORE nodes
2726public:
2727 friend class SelectionDAG;
2728
2729 VPBaseLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2730 const DebugLoc &DL, SDVTList VTs,
2731 ISD::MemIndexedMode AM, EVT MemVT,
2732 MachineMemOperand *MMO)
2733 : MemSDNode(NodeTy, Order, DL, VTs, MemVT, MMO) {
2734 LSBaseSDNodeBits.AddressingMode = AM;
2735 assert(getAddressingMode() == AM && "Value truncated");
2736 }
2737
2738 // VPStridedStoreSDNode (Chain, Data, Ptr, Offset, Stride, Mask, EVL)
2739 // VPStoreSDNode (Chain, Data, Ptr, Offset, Mask, EVL)
2740 // VPStridedLoadSDNode (Chain, Ptr, Offset, Stride, Mask, EVL)
2741 // VPLoadSDNode (Chain, Ptr, Offset, Mask, EVL)
2742 // Mask is a vector of i1 elements;
2743 // the type of EVL is TLI.getVPExplicitVectorLengthTy().
2744 const SDValue &getOffset() const {
2745 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2746 getOpcode() == ISD::VP_LOAD)
2747 ? 2
2748 : 3);
2749 }
2750 const SDValue &getBasePtr() const {
2751 return getOperand((getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2752 getOpcode() == ISD::VP_LOAD)
2753 ? 1
2754 : 2);
2755 }
2756 const SDValue &getMask() const {
2757 switch (getOpcode()) {
2758 default:
2759 llvm_unreachable("Invalid opcode");
2760 case ISD::VP_LOAD:
2761 return getOperand(3);
2762 case ISD::VP_STORE:
2763 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2764 return getOperand(4);
2765 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2766 return getOperand(5);
2767 }
2768 }
2769 const SDValue &getVectorLength() const {
2770 switch (getOpcode()) {
2771 default:
2772 llvm_unreachable("Invalid opcode");
2773 case ISD::VP_LOAD:
2774 return getOperand(4);
2775 case ISD::VP_STORE:
2776 case ISD::EXPERIMENTAL_VP_STRIDED_LOAD:
2777 return getOperand(5);
2778 case ISD::EXPERIMENTAL_VP_STRIDED_STORE:
2779 return getOperand(6);
2780 }
2781 }
2782
2783 /// Return the addressing mode for this load or store:
2784 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2786 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2787 }
2788
2789 /// Return true if this is a pre/post inc/dec load/store.
2790 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2791
2792 /// Return true if this is NOT a pre/post inc/dec load/store.
2793 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2794
2795 static bool classof(const SDNode *N) {
2796 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD ||
2797 N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE ||
2798 N->getOpcode() == ISD::VP_LOAD || N->getOpcode() == ISD::VP_STORE;
2799 }
2800};
2801
2802/// This class is used to represent a VP_LOAD node
2804public:
2805 friend class SelectionDAG;
2806
2807 VPLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2808 ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool isExpanding,
2809 EVT MemVT, MachineMemOperand *MMO)
2810 : VPBaseLoadStoreSDNode(ISD::VP_LOAD, Order, dl, VTs, AM, MemVT, MMO) {
2811 LoadSDNodeBits.ExtTy = ETy;
2812 LoadSDNodeBits.IsExpanding = isExpanding;
2813 }
2814
2816 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2817 }
2818
2819 const SDValue &getBasePtr() const { return getOperand(1); }
2820 const SDValue &getOffset() const { return getOperand(2); }
2821 const SDValue &getMask() const { return getOperand(3); }
2822 const SDValue &getVectorLength() const { return getOperand(4); }
2823
2824 static bool classof(const SDNode *N) {
2825 return N->getOpcode() == ISD::VP_LOAD;
2826 }
2827 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2828};
2829
2830/// This class is used to represent an EXPERIMENTAL_VP_STRIDED_LOAD node.
2832public:
2833 friend class SelectionDAG;
2834
2835 VPStridedLoadSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2837 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2838 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_LOAD, Order, DL, VTs,
2839 AM, MemVT, MMO) {
2840 LoadSDNodeBits.ExtTy = ETy;
2841 LoadSDNodeBits.IsExpanding = IsExpanding;
2842 }
2843
2845 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2846 }
2847
2848 const SDValue &getBasePtr() const { return getOperand(1); }
2849 const SDValue &getOffset() const { return getOperand(2); }
2850 const SDValue &getStride() const { return getOperand(3); }
2851 const SDValue &getMask() const { return getOperand(4); }
2852 const SDValue &getVectorLength() const { return getOperand(5); }
2853
2854 static bool classof(const SDNode *N) {
2855 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_LOAD;
2856 }
2857 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
2858};
2859
2860/// This class is used to represent a VP_STORE node
2862public:
2863 friend class SelectionDAG;
2864
2865 VPStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2866 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
2867 EVT MemVT, MachineMemOperand *MMO)
2868 : VPBaseLoadStoreSDNode(ISD::VP_STORE, Order, dl, VTs, AM, MemVT, MMO) {
2869 StoreSDNodeBits.IsTruncating = isTrunc;
2870 StoreSDNodeBits.IsCompressing = isCompressing;
2871 }
2872
2873 /// Return true if this is a truncating store.
2874 /// For integers this is the same as doing a TRUNCATE and storing the result.
2875 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2876 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2877
2878 /// Returns true if the op does a compression to the vector before storing.
2879 /// The node contiguously stores the active elements (integers or floats)
2880 /// in src (those with their respective bit set in writemask k) to unaligned
2881 /// memory at base_addr.
2882 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2883
2884 const SDValue &getValue() const { return getOperand(1); }
2885 const SDValue &getBasePtr() const { return getOperand(2); }
2886 const SDValue &getOffset() const { return getOperand(3); }
2887 const SDValue &getMask() const { return getOperand(4); }
2888 const SDValue &getVectorLength() const { return getOperand(5); }
2889
2890 static bool classof(const SDNode *N) {
2891 return N->getOpcode() == ISD::VP_STORE;
2892 }
2893};
2894
2895/// This class is used to represent an EXPERIMENTAL_VP_STRIDED_STORE node.
2897public:
2898 friend class SelectionDAG;
2899
2900 VPStridedStoreSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
2901 ISD::MemIndexedMode AM, bool IsTrunc, bool IsCompressing,
2902 EVT MemVT, MachineMemOperand *MMO)
2903 : VPBaseLoadStoreSDNode(ISD::EXPERIMENTAL_VP_STRIDED_STORE, Order, DL,
2904 VTs, AM, MemVT, MMO) {
2905 StoreSDNodeBits.IsTruncating = IsTrunc;
2906 StoreSDNodeBits.IsCompressing = IsCompressing;
2907 }
2908
2909 /// Return true if this is a truncating store.
2910 /// For integers this is the same as doing a TRUNCATE and storing the result.
2911 /// For floats, it is the same as doing an FP_ROUND and storing the result.
2912 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
2913
2914 /// Returns true if the op does a compression to the vector before storing.
2915 /// The node contiguously stores the active elements (integers or floats)
2916 /// in src (those with their respective bit set in writemask k) to unaligned
2917 /// memory at base_addr.
2918 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
2919
2920 const SDValue &getValue() const { return getOperand(1); }
2921 const SDValue &getBasePtr() const { return getOperand(2); }
2922 const SDValue &getOffset() const { return getOperand(3); }
2923 const SDValue &getStride() const { return getOperand(4); }
2924 const SDValue &getMask() const { return getOperand(5); }
2925 const SDValue &getVectorLength() const { return getOperand(6); }
2926
2927 static bool classof(const SDNode *N) {
2928 return N->getOpcode() == ISD::EXPERIMENTAL_VP_STRIDED_STORE;
2929 }
2930};
2931
2932/// This base class is used to represent MLOAD and MSTORE nodes
2934public:
2935 friend class SelectionDAG;
2936
2937 MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order,
2938 const DebugLoc &dl, SDVTList VTs,
2939 ISD::MemIndexedMode AM, EVT MemVT,
2940 MachineMemOperand *MMO)
2941 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
2942 LSBaseSDNodeBits.AddressingMode = AM;
2943 assert(getAddressingMode() == AM && "Value truncated");
2944 }
2945
2946 // MaskedLoadSDNode (Chain, ptr, offset, mask, passthru)
2947 // MaskedStoreSDNode (Chain, data, ptr, offset, mask)
2948 // Mask is a vector of i1 elements
2949 const SDValue &getOffset() const {
2950 return getOperand(getOpcode() == ISD::MLOAD ? 2 : 3);
2951 }
2952 const SDValue &getMask() const {
2953 return getOperand(getOpcode() == ISD::MLOAD ? 3 : 4);
2954 }
2955
2956 /// Return the addressing mode for this load or store:
2957 /// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
2959 return static_cast<ISD::MemIndexedMode>(LSBaseSDNodeBits.AddressingMode);
2960 }
2961
2962 /// Return true if this is a pre/post inc/dec load/store.
2963 bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
2964
2965 /// Return true if this is NOT a pre/post inc/dec load/store.
2966 bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
2967
2968 static bool classof(const SDNode *N) {
2969 return N->getOpcode() == ISD::MLOAD ||
2970 N->getOpcode() == ISD::MSTORE;
2971 }
2972};
2973
2974/// This class is used to represent an MLOAD node
2976public:
2977 friend class SelectionDAG;
2978
2979 MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
2981 bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
2982 : MaskedLoadStoreSDNode(ISD::MLOAD, Order, dl, VTs, AM, MemVT, MMO) {
2983 LoadSDNodeBits.ExtTy = ETy;
2984 LoadSDNodeBits.IsExpanding = IsExpanding;
2985 }
2986
2988 return static_cast<ISD::LoadExtType>(LoadSDNodeBits.ExtTy);
2989 }
2990
2991 const SDValue &getBasePtr() const { return getOperand(1); }
2992 const SDValue &getOffset() const { return getOperand(2); }
2993 const SDValue &getMask() const { return getOperand(3); }
2994 const SDValue &getPassThru() const { return getOperand(4); }
2995
2996 static bool classof(const SDNode *N) {
2997 return N->getOpcode() == ISD::MLOAD;
2998 }
2999
3000 bool isExpandingLoad() const { return LoadSDNodeBits.IsExpanding; }
3001};
3002
3003/// This class is used to represent an MSTORE node
3005public:
3006 friend class SelectionDAG;
3007
3008 MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
3009 ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing,
3010 EVT MemVT, MachineMemOperand *MMO)
3011 : MaskedLoadStoreSDNode(ISD::MSTORE, Order, dl, VTs, AM, MemVT, MMO) {
3012 StoreSDNodeBits.IsTruncating = isTrunc;
3013 StoreSDNodeBits.IsCompressing = isCompressing;
3014 }
3015
3016 /// Return true if the op does a truncation before store.
3017 /// For integers this is the same as doing a TRUNCATE and storing the result.
3018 /// For floats, it is the same as doing an FP_ROUND and storing the result.
3019 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
3020
3021 /// Returns true if the op does a compression to the vector before storing.
3022 /// The node contiguously stores the active elements (integers or floats)
3023 /// in src (those with their respective bit set in writemask k) to unaligned
3024 /// memory at base_addr.
3025 bool isCompressingStore() const { return StoreSDNodeBits.IsCompressing; }
3026
3027 const SDValue &getValue() const { return getOperand(1); }
3028 const SDValue &getBasePtr() const { return getOperand(2); }
3029 const SDValue &getOffset() const { return getOperand(3); }
3030 const SDValue &getMask() const { return getOperand(4); }
3031
3032 static bool classof(const SDNode *N) {
3033 return N->getOpcode() == ISD::MSTORE;
3034 }
3035};
3036
3037/// This is a base class used to represent
3038/// VP_GATHER and VP_SCATTER nodes
3039///
3041public:
3042 friend class SelectionDAG;
3043
3044 VPGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order,
3045 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3046 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3047 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3048 LSBaseSDNodeBits.AddressingMode = IndexType;
3049 assert(getIndexType() == IndexType && "Value truncated");
3050 }
3051
3052 /// How is Index applied to BasePtr when computing addresses.
3054 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3055 }
3056 bool isIndexScaled() const {
3057 return !cast<ConstantSDNode>(getScale())->isOne();
3058 }
3059 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
3060
3061 // In the both nodes address is Op1, mask is Op2:
3062 // VPGatherSDNode (Chain, base, index, scale, mask, vlen)
3063 // VPScatterSDNode (Chain, value, base, index, scale, mask, vlen)
3064 // Mask is a vector of i1 elements
3065 const SDValue &getBasePtr() const {
3066 return getOperand((getOpcode() == ISD::VP_GATHER) ? 1 : 2);
3067 }
3068 const SDValue &getIndex() const {
3069 return getOperand((getOpcode() == ISD::VP_GATHER) ? 2 : 3);
3070 }
3071 const SDValue &getScale() const {
3072 return getOperand((getOpcode() == ISD::VP_GATHER) ? 3 : 4);
3073 }
3074 const SDValue &getMask() const {
3075 return getOperand((getOpcode() == ISD::VP_GATHER) ? 4 : 5);
3076 }
3077 const SDValue &getVectorLength() const {
3078 return getOperand((getOpcode() == ISD::VP_GATHER) ? 5 : 6);
3079 }
3080
3081 static bool classof(const SDNode *N) {
3082 return N->getOpcode() == ISD::VP_GATHER ||
3083 N->getOpcode() == ISD::VP_SCATTER;
3084 }
3085};
3086
3087/// This class is used to represent an VP_GATHER node
3088///
3090public:
3091 friend class SelectionDAG;
3092
3093 VPGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3094 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3095 : VPGatherScatterSDNode(ISD::VP_GATHER, Order, dl, VTs, MemVT, MMO,
3096 IndexType) {}
3097
3098 static bool classof(const SDNode *N) {
3099 return N->getOpcode() == ISD::VP_GATHER;
3100 }
3101};
3102
3103/// This class is used to represent an VP_SCATTER node
3104///
3106public:
3107 friend class SelectionDAG;
3108
3109 VPScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3110 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3111 : VPGatherScatterSDNode(ISD::VP_SCATTER, Order, dl, VTs, MemVT, MMO,
3112 IndexType) {}
3113
3114 const SDValue &getValue() const { return getOperand(1); }
3115
3116 static bool classof(const SDNode *N) {
3117 return N->getOpcode() == ISD::VP_SCATTER;
3118 }
3119};
3120
3121/// This is a base class used to represent
3122/// MGATHER and MSCATTER nodes
3123///
3125public:
3126 friend class SelectionDAG;
3127
3129 const DebugLoc &dl, SDVTList VTs, EVT MemVT,
3130 MachineMemOperand *MMO, ISD::MemIndexType IndexType)
3131 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3132 LSBaseSDNodeBits.AddressingMode = IndexType;
3133 assert(getIndexType() == IndexType && "Value truncated");
3134 }
3135
3136 /// How is Index applied to BasePtr when computing addresses.
3138 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3139 }
3140 bool isIndexScaled() const {
3141 return !cast<ConstantSDNode>(getScale())->isOne();
3142 }
3143 bool isIndexSigned() const { return isIndexTypeSigned(getIndexType()); }
3144
3145 // In the both nodes address is Op1, mask is Op2:
3146 // MaskedGatherSDNode (Chain, passthru, mask, base, index, scale)
3147 // MaskedScatterSDNode (Chain, value, mask, base, index, scale)
3148 // Mask is a vector of i1 elements
3149 const SDValue &getBasePtr() const { return getOperand(3); }
3150 const SDValue &getIndex() const { return getOperand(4); }
3151 const SDValue &getMask() const { return getOperand(2); }
3152 const SDValue &getScale() const { return getOperand(5); }
3153
3154 static bool classof(const SDNode *N) {
3155 return N->getOpcode() == ISD::MGATHER || N->getOpcode() == ISD::MSCATTER ||
3156 N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
3157 }
3158};
3159
3160/// This class is used to represent an MGATHER node
3161///
3163public:
3164 friend class SelectionDAG;
3165
3166 MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
3167 EVT MemVT, MachineMemOperand *MMO,
3168 ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
3169 : MaskedGatherScatterSDNode(ISD::MGATHER, Order, dl, VTs, MemVT, MMO,
3170 IndexType) {
3171 LoadSDNodeBits.ExtTy = ETy;
3172 }
3173
3174 const SDValue &getPassThru() const { return getOperand(1); }
3175
3179
3180 static bool classof(const SDNode *N) {
3181 return N->getOpcode() == ISD::MGATHER;
3182 }
3183};
3184
3185/// This class is used to represent an MSCATTER node
3186///
3188public:
3189 friend class SelectionDAG;
3190
3191 MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs,
3192 EVT MemVT, MachineMemOperand *MMO,
3193 ISD::MemIndexType IndexType, bool IsTrunc)
3194 : MaskedGatherScatterSDNode(ISD::MSCATTER, Order, dl, VTs, MemVT, MMO,
3195 IndexType) {
3196 StoreSDNodeBits.IsTruncating = IsTrunc;
3197 }
3198
3199 /// Return true if the op does a truncation before store.
3200 /// For integers this is the same as doing a TRUNCATE and storing the result.
3201 /// For floats, it is the same as doing an FP_ROUND and storing the result.
3202 bool isTruncatingStore() const { return StoreSDNodeBits.IsTruncating; }
3203
3204 const SDValue &getValue() const { return getOperand(1); }
3205
3206 static bool classof(const SDNode *N) {
3207 return N->getOpcode() == ISD::MSCATTER;
3208 }
3209};
3210
3212public:
3213 friend class SelectionDAG;
3214
3215 MaskedHistogramSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs,
3216 EVT MemVT, MachineMemOperand *MMO,
3217 ISD::MemIndexType IndexType)
3218 : MaskedGatherScatterSDNode(ISD::EXPERIMENTAL_VECTOR_HISTOGRAM, Order, DL,
3219 VTs, MemVT, MMO, IndexType) {}
3220
3222 return static_cast<ISD::MemIndexType>(LSBaseSDNodeBits.AddressingMode);
3223 }
3224
3225 const SDValue &getBasePtr() const { return getOperand(3); }
3226 const SDValue &getIndex() const { return getOperand(4); }
3227 const SDValue &getMask() const { return getOperand(2); }
3228 const SDValue &getScale() const { return getOperand(5); }
3229 const SDValue &getInc() const { return getOperand(1); }
3230 const SDValue &getIntID() const { return getOperand(6); }
3231
3232 static bool classof(const SDNode *N) {
3233 return N->getOpcode() == ISD::EXPERIMENTAL_VECTOR_HISTOGRAM;
3234 }
3235};
3236
3238public:
3239 friend class SelectionDAG;
3240
3241 VPLoadFFSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, EVT MemVT,
3242 MachineMemOperand *MMO)
3243 : MemSDNode(ISD::VP_LOAD_FF, Order, DL, VTs, MemVT, MMO) {}
3244
3245 const SDValue &getBasePtr() const { return getOperand(1); }
3246 const SDValue &getMask() const { return getOperand(2); }
3247 const SDValue &getVectorLength() const { return getOperand(3); }
3248
3249 static bool classof(const SDNode *N) {
3250 return N->getOpcode() == ISD::VP_LOAD_FF;
3251 }
3252};
3253
3255public:
3256 friend class SelectionDAG;
3257
3258 FPStateAccessSDNode(unsigned NodeTy, unsigned Order, const DebugLoc &dl,
3259 SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
3260 : MemSDNode(NodeTy, Order, dl, VTs, MemVT, MMO) {
3261 assert((NodeTy == ISD::GET_FPENV_MEM || NodeTy == ISD::SET_FPENV_MEM) &&
3262 "Expected FP state access node");
3263 }
3264
3265 static bool classof(const SDNode *N) {
3266 return N->getOpcode() == ISD::GET_FPENV_MEM ||
3267 N->getOpcode() == ISD::SET_FPENV_MEM;
3268 }
3269};
3270
3271/// An SDNode that represents everything that will be needed
3272/// to construct a MachineInstr. These nodes are created during the
3273/// instruction selection proper phase.
3274///
3275/// Note that the only supported way to set the `memoperands` is by calling the
3276/// `SelectionDAG::setNodeMemRefs` function as the memory management happens
3277/// inside the DAG rather than in the node.
3278class MachineSDNode : public SDNode {
3279private:
3280 friend class SelectionDAG;
3281
3282 MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc &DL, SDVTList VTs)
3283 : SDNode(Opc, Order, DL, VTs) {}
3284
3285 // We use a pointer union between a single `MachineMemOperand` pointer and
3286 // a pointer to an array of `MachineMemOperand` pointers. This is null when
3287 // the number of these is zero, the single pointer variant used when the
3288 // number is one, and the array is used for larger numbers.
3289 //
3290 // The array is allocated via the `SelectionDAG`'s allocator and so will
3291 // always live until the DAG is cleaned up and doesn't require ownership here.
3292 //
3293 // We can't use something simpler like `TinyPtrVector` here because `SDNode`
3294 // subclasses aren't managed in a conforming C++ manner. See the comments on
3295 // `SelectionDAG::MorphNodeTo` which details what all goes on, but the
3296 // constraint here is that these don't manage memory with their constructor or
3297 // destructor and can be initialized to a good state even if they start off
3298 // uninitialized.
3300
3301 // Note that this could be folded into the above `MemRefs` member if doing so
3302 // is advantageous at some point. We don't need to store this in most cases.
3303 // However, at the moment this doesn't appear to make the allocation any
3304 // smaller and makes the code somewhat simpler to read.
3305 int NumMemRefs = 0;
3306
3307public:
3309
3311 // Special case the common cases.
3312 if (NumMemRefs == 0)
3313 return {};
3314 if (NumMemRefs == 1)
3315 return ArrayRef(MemRefs.getAddrOfPtr1(), 1);
3316
3317 // Otherwise we have an actual array.
3318 return ArrayRef(cast<MachineMemOperand **>(MemRefs), NumMemRefs);
3319 }
3320 mmo_iterator memoperands_begin() const { return memoperands().begin(); }
3321 mmo_iterator memoperands_end() const { return memoperands().end(); }
3322 bool memoperands_empty() const { return memoperands().empty(); }
3323
3324 /// Clear out the memory reference descriptor list.
3326 MemRefs = nullptr;
3327 NumMemRefs = 0;
3328 }
3329
3330 static bool classof(const SDNode *N) {
3331 return N->isMachineOpcode();
3332 }
3333};
3334
3335/// An SDNode that records if a register contains a value that is guaranteed to
3336/// be aligned accordingly.
3338 Align Alignment;
3339
3340public:
3341 AssertAlignSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, Align A)
3342 : SDNode(ISD::AssertAlign, Order, DL, VTs), Alignment(A) {}
3343
3344 Align getAlign() const { return Alignment; }
3345
3346 static bool classof(const SDNode *N) {
3347 return N->getOpcode() == ISD::AssertAlign;
3348 }
3349};
3350
3351class SDNodeIterator {
3352 const SDNode *Node;
3353 unsigned Operand;
3354
3355 SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
3356
3357public:
3358 using iterator_category = std::forward_iterator_tag;
3360 using difference_type = std::ptrdiff_t;
3363
3364 bool operator==(const SDNodeIterator& x) const {
3365 return Operand == x.Operand;
3366 }
3367 bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
3368
3370 return Node->getOperand(Operand).getNode();
3371 }
3372 pointer operator->() const { return operator*(); }
3373
3374 SDNodeIterator& operator++() { // Preincrement
3375 ++Operand;
3376 return *this;
3377 }
3378 SDNodeIterator operator++(int) { // Postincrement
3379 SDNodeIterator tmp = *this; ++*this; return tmp;
3380 }
3381 size_t operator-(SDNodeIterator Other) const {
3382 assert(Node == Other.Node &&
3383 "Cannot compare iterators of two different nodes!");
3384 return Operand - Other.Operand;
3385 }
3386
3387 static SDNodeIterator begin(const SDNode *N) { return SDNodeIterator(N, 0); }
3388 static SDNodeIterator end (const SDNode *N) {
3389 return SDNodeIterator(N, N->getNumOperands());
3390 }
3391
3392 unsigned getOperand() const { return Operand; }
3393 const SDNode *getNode() const { return Node; }
3394};
3395
3396template <> struct GraphTraits<SDNode*> {
3397 using NodeRef = SDNode *;
3399
3400 static NodeRef getEntryNode(SDNode *N) { return N; }
3401
3405
3409};
3410
3411/// A representation of the largest SDNode, for use in sizeof().
3412///
3413/// This needs to be a union because the largest node differs on 32 bit systems
3414/// with 4 and 8 byte pointer alignment, respectively.
3419
3420/// The SDNode class with the greatest alignment requirement.
3422
3423namespace ISD {
3424
3425 /// Returns true if the specified node is a non-extending and unindexed load.
3426 inline bool isNormalLoad(const SDNode *N) {
3427 auto *Ld = dyn_cast<LoadSDNode>(N);
3428 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
3429 Ld->getAddressingMode() == ISD::UNINDEXED;
3430 }
3431
3432 /// Returns true if the specified node is a non-extending load.
3433 inline bool isNON_EXTLoad(const SDNode *N) {
3434 auto *Ld = dyn_cast<LoadSDNode>(N);
3435 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD;
3436 }
3437
3438 /// Returns true if the specified node is a EXTLOAD.
3439 inline bool isEXTLoad(const SDNode *N) {
3440 auto *Ld = dyn_cast<LoadSDNode>(N);
3441 return Ld && Ld->getExtensionType() == ISD::EXTLOAD;
3442 }
3443
3444 /// Returns true if the specified node is a SEXTLOAD.
3445 inline bool isSEXTLoad(const SDNode *N) {
3446 auto *Ld = dyn_cast<LoadSDNode>(N);
3447 return Ld && Ld->getExtensionType() == ISD::SEXTLOAD;
3448 }
3449
3450 /// Returns true if the specified node is a ZEXTLOAD.
3451 inline bool isZEXTLoad(const SDNode *N) {
3452 auto *Ld = dyn_cast<LoadSDNode>(N);
3453 return Ld && Ld->getExtensionType() == ISD::ZEXTLOAD;
3454 }
3455
3456 /// Returns true if the specified node is an unindexed load.
3457 inline bool isUNINDEXEDLoad(const SDNode *N) {
3458 auto *Ld = dyn_cast<LoadSDNode>(N);
3459 return Ld && Ld->getAddressingMode() == ISD::UNINDEXED;
3460 }
3461
3462 /// Returns true if the specified node is a non-truncating
3463 /// and unindexed store.
3464 inline bool isNormalStore(const SDNode *N) {
3465 auto *St = dyn_cast<StoreSDNode>(N);
3466 return St && !St->isTruncatingStore() &&
3467 St->getAddressingMode() == ISD::UNINDEXED;
3468 }
3469
3470 /// Returns true if the specified node is an unindexed store.
3471 inline bool isUNINDEXEDStore(const SDNode *N) {
3472 auto *St = dyn_cast<StoreSDNode>(N);
3473 return St && St->getAddressingMode() == ISD::UNINDEXED;
3474 }
3475
3476 /// Returns true if the specified node is a non-extending and unindexed
3477 /// masked load.
3478 inline bool isNormalMaskedLoad(const SDNode *N) {
3479 auto *Ld = dyn_cast<MaskedLoadSDNode>(N);
3480 return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
3481 Ld->getAddressingMode() == ISD::UNINDEXED;
3482 }
3483
3484 /// Returns true if the specified node is a non-extending and unindexed
3485 /// masked store.
3486 inline bool isNormalMaskedStore(const SDNode *N) {
3487 auto *St = dyn_cast<MaskedStoreSDNode>(N);
3488 return St && !St->isTruncatingStore() &&
3489 St->getAddressingMode() == ISD::UNINDEXED;
3490 }
3491
3492 /// Attempt to match a unary predicate against a scalar/splat constant or
3493 /// every element of a constant BUILD_VECTOR.
3494 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
3495 template <typename ConstNodeType>
3497 std::function<bool(ConstNodeType *)> Match,
3498 bool AllowUndefs = false,
3499 bool AllowTruncation = false);
3500
3501 /// Hook for matching ConstantSDNode predicate
3503 std::function<bool(ConstantSDNode *)> Match,
3504 bool AllowUndefs = false,
3505 bool AllowTruncation = false) {
3506 return matchUnaryPredicateImpl<ConstantSDNode>(Op, Match, AllowUndefs,
3507 AllowTruncation);
3508 }
3509
3510 /// Hook for matching ConstantFPSDNode predicate
3511 inline bool
3513 std::function<bool(ConstantFPSDNode *)> Match,
3514 bool AllowUndefs = false) {
3515 return matchUnaryPredicateImpl<ConstantFPSDNode>(Op, Match, AllowUndefs);
3516 }
3517
3518 /// Attempt to match a binary predicate against a pair of scalar/splat
3519 /// constants or every element of a pair of constant BUILD_VECTORs.
3520 /// If AllowUndef is true, then UNDEF elements will pass nullptr to Match.
3521 /// If AllowTypeMismatch is true then RetType + ArgTypes don't need to match.
3524 std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
3525 bool AllowUndefs = false, bool AllowTypeMismatch = false);
3526
3527 /// Returns true if the specified value is the overflow result from one
3528 /// of the overflow intrinsic nodes.
3530 unsigned Opc = Op.getOpcode();
3531 return (Op.getResNo() == 1 &&
3532 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
3533 Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO));
3534 }
3535
3536} // end namespace ISD
3537
3538} // end namespace llvm
3539
3540#endif // LLVM_CODEGEN_SELECTIONDAGNODES_H
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
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
Load MIR Sample Profile
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
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)
This class is used to gather all the unique data bits of a node.
Definition FoldingSet.h:208
static bool classof(const SDNode *N)
LLVM_ABI unsigned getAddressSpace() const
static bool classof(const SDNode *N)
const GlobalValue * getGlobal() const
const SDValue & getValue() const
static bool classof(const SDNode *N)
unsigned getTargetFlags() const
LSBaseSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, MachineMemOperand *MMO)
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
static bool classof(const SDNode *N)
MCSymbol * getLabel() const
static bool classof(const SDNode *N)
int64_t getFrameIndex() const
static bool classof(const SDNode *N)
const SDValue & getBasePtr() const
friend class SelectionDAG
const SDValue & getOffset() const
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
static bool classof(const SDNode *N)
MCSymbol * getMCSymbol() const
static bool classof(const SDNode *N)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
static bool classof(const SDNode *N)
const MDNode * getMD() const
Metadata node.
Definition Metadata.h: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.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
ArrayRef< MachineMemOperand * > memoperands() const
void clearMemRefs()
Clear out the memory reference descriptor list.
mmo_iterator memoperands_begin() const
static bool classof(const SDNode *N)
ArrayRef< MachineMemOperand * >::const_iterator mmo_iterator
mmo_iterator memoperands_end() const
static bool classof(const SDNode *N)
MaskedGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType, ISD::LoadExtType ETy)
const SDValue & getPassThru() const
ISD::LoadExtType getExtensionType() const
static bool classof(const SDNode *N)
MaskedGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getInc() const
MaskedHistogramSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getScale() const
static bool classof(const SDNode *N)
const SDValue & getMask() const
const SDValue & getIntID() const
const SDValue & getIndex() const
const SDValue & getBasePtr() const
ISD::MemIndexType getIndexType() const
MaskedLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getBasePtr() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
const SDValue & getPassThru() const
static bool classof(const SDNode *N)
const SDValue & getOffset() const
const SDValue & getMask() const
MaskedLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, MachineMemOperand *MMO)
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
static bool classof(const SDNode *N)
const SDValue & getOffset() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
MaskedScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType, bool IsTrunc)
const SDValue & getValue() const
static bool classof(const SDNode *N)
bool isTruncatingStore() const
Return true if the op does a truncation before store.
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
MaskedStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getOffset() const
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
static bool classof(const SDNode *N)
MemIntrinsicSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemoryVT, PointerUnion< MachineMemOperand *, MachineMemOperand ** > MemRefs)
static bool classof(const SDNode *N)
void refineAlignment(ArrayRef< MachineMemOperand * > NewMMOs)
Update this MemSDNode's MachineMemOperand information to reflect the alignment of NewMMOs,...
void refineAlignment(MachineMemOperand *NewMMO)
unsigned getAddressSpace() const
Return the address space for the associated pointer.
size_t getNumMemOperands() const
Return the number of memory operands.
Align getBaseAlign() const
Returns alignment and volatility of the memory access.
const MDNode * getRanges() const
Returns the Ranges that describes the dereference.
LLVM_ABI MemSDNode(unsigned Opc, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT memvt, PointerUnion< MachineMemOperand *, MachineMemOperand ** > memrefs)
Constructor that supports single or multiple MMOs.
Align getAlign() const
PointerUnion< MachineMemOperand *, MachineMemOperand ** > MemRefs
Memory reference information.
bool isVolatile() const
AAMDNodes getAAInfo() const
Returns the AA info that describes the dereference.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID for this memory operation.
int64_t getSrcValueOffset() const
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
void refineRanges(MachineMemOperand *NewMMO)
void refineRanges(ArrayRef< MachineMemOperand * > NewMMOs)
Refine range metadata for all MMOs.
AtomicOrdering getSuccessOrdering() const
Return the atomic ordering requirements for this memory operation.
MachineMemOperand * getMemOperand() const
Return the unique MachineMemOperand object describing the memory reference performed by operation.
const SDValue & getBasePtr() const
const MachinePointerInfo & getPointerInfo() const
bool hasUniqueMemOperand() const
Return true if this node has exactly one memory operand.
AtomicOrdering getMergedOrdering() const
Return a single atomic ordering that is at least as strong as both the success and failure orderings ...
const SDValue & getChain() const
bool isNonTemporal() const
bool isInvariant() const
bool isDereferenceable() const
bool isUnordered() const
Returns true if the memory operation doesn't imply any ordering constraints on surrounding memory ope...
bool isAtomic() const
Return true if the memory operation ordering is Unordered or higher.
static bool classof(const SDNode *N)
ArrayRef< MachineMemOperand * > memoperands() const
Return the memory operands for this node.
unsigned getRawSubclassData() const
Return the SubclassData value, without HasDebugValue.
EVT getMemoryVT() const
Return the type of the in-memory value.
LLVM_ABI void dump() const
User-friendly dump.
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.
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
Definition SmallPtrSet.h:99
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const Value * getValue() const
Return the contained Value.
static bool classof(const SDNode *N)
const SDValue & getBasePtr() const
const SDValue & getOffset() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if the op does a truncation before store.
static bool classof(const SDNode *N)
Completely target-dependent object reference.
TargetIndexSDNode(int Idx, SDVTList VTs, int64_t Ofs, unsigned TF)
static bool classof(const SDNode *N)
unsigned getTargetFlags() const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
const SDValue & getMask() const
static bool classof(const SDNode *N)
bool isIndexed() const
Return true if this is a pre/post inc/dec load/store.
VPBaseLoadStoreSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &DL, SDVTList VTs, ISD::MemIndexedMode AM, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getOffset() const
ISD::MemIndexedMode getAddressingMode() const
Return the addressing mode for this load or store: unindexed, pre-inc, pre-dec, post-inc,...
const SDValue & getVectorLength() const
bool isUnindexed() const
Return true if this is NOT a pre/post inc/dec load/store.
const SDValue & getBasePtr() const
VPGatherSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
static bool classof(const SDNode *N)
const SDValue & getScale() const
ISD::MemIndexType getIndexType() const
How is Index applied to BasePtr when computing addresses.
const SDValue & getVectorLength() const
const SDValue & getIndex() const
VPGatherScatterSDNode(ISD::NodeType NodeTy, unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getBasePtr() const
static bool classof(const SDNode *N)
const SDValue & getMask() const
const SDValue & getMask() const
const SDValue & getBasePtr() const
VPLoadFFSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO)
static bool classof(const SDNode *N)
const SDValue & getVectorLength() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
ISD::LoadExtType getExtensionType() const
const SDValue & getMask() const
VPLoadSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool isExpanding, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getBasePtr() const
static bool classof(const SDNode *N)
static bool classof(const SDNode *N)
VPScatterSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, EVT MemVT, MachineMemOperand *MMO, ISD::MemIndexType IndexType)
const SDValue & getValue() const
const SDValue & getMask() const
VPStoreSDNode(unsigned Order, const DebugLoc &dl, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, bool isCompressing, EVT MemVT, MachineMemOperand *MMO)
static bool classof(const SDNode *N)
const SDValue & getVectorLength() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
const SDValue & getOffset() const
bool isTruncatingStore() const
Return true if this is a truncating store.
const SDValue & getBasePtr() const
const SDValue & getValue() const
const SDValue & getMask() const
ISD::LoadExtType getExtensionType() const
const SDValue & getStride() const
const SDValue & getOffset() const
const SDValue & getVectorLength() const
static bool classof(const SDNode *N)
const SDValue & getBasePtr() const
VPStridedLoadSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, bool IsExpanding, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getBasePtr() const
const SDValue & getMask() const
const SDValue & getValue() const
bool isTruncatingStore() const
Return true if this is a truncating store.
VPStridedStoreSDNode(unsigned Order, const DebugLoc &DL, SDVTList VTs, ISD::MemIndexedMode AM, bool IsTrunc, bool IsCompressing, EVT MemVT, MachineMemOperand *MMO)
const SDValue & getOffset() const
const SDValue & getVectorLength() const
static bool classof(const SDNode *N)
const SDValue & getStride() const
bool isCompressingStore() const
Returns true if the op does a compression to the vector before storing.
friend class SelectionDAG
static bool classof(const SDNode *N)
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This file defines the ilist_node class template, which is a convenient base class for creating classe...
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define UINT64_MAX
Definition DataTypes.h:77
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
ISD namespace - This namespace contains an enum which represents all of the SelectionDAG node types a...
Definition ISDOpcodes.h:24
LLVM_ABI bool isConstantSplatVectorAllOnes(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are ~0 ...
bool isNormalMaskedLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed masked load.
bool isNormalMaskedStore(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed masked store.
bool isNON_EXTLoad(const SDNode *N)
Returns true if the specified node is a non-extending load.
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
Definition ISDOpcodes.h:41
@ TargetConstantPool
Definition ISDOpcodes.h:189
@ MDNODE_SDNODE
MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to reference metadata in the IR.
@ PTRADD
PTRADD represents pointer arithmetic semantics, for targets that opt in using shouldPreservePtrArith(...
@ POISON
POISON - A poison node.
Definition ISDOpcodes.h:236
@ MLOAD
Masked load and store - consecutive vector load and store operations with additional mask operand tha...
@ TargetBlockAddress
Definition ISDOpcodes.h:191
@ DEACTIVATION_SYMBOL
Untyped node storing deactivation symbol reference (DeactivationSymbolSDNode).
@ ATOMIC_STORE
OUTCHAIN = ATOMIC_STORE(INCHAIN, val, ptr) This corresponds to "store atomic" instruction.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
@ ATOMIC_LOAD_USUB_COND
@ GlobalAddress
Definition ISDOpcodes.h:88
@ ATOMIC_CMP_SWAP_WITH_SUCCESS
Val, Success, OUTCHAIN = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap) N.b.
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
@ GlobalTLSAddress
Definition ISDOpcodes.h:89
@ SRCVALUE
SRCVALUE - This is a node type that holds a Value* that is used to make reference to a value in the L...
@ EH_LABEL
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
@ ATOMIC_LOAD_USUB_SAT
@ ANNOTATION_LABEL
ANNOTATION_LABEL - Represents a mid basic block label used by annotations.
@ TargetExternalSymbol
Definition ISDOpcodes.h:190
@ TargetJumpTable
Definition ISDOpcodes.h:188
@ TargetIndex
TargetIndex - Like a constant pool entry, but with completely target-dependent semantics.
Definition ISDOpcodes.h:198
@ SSUBO
Same for subtraction.
Definition ISDOpcodes.h:352
@ ATOMIC_LOAD
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
@ UNDEF
UNDEF - An undefined node.
Definition ISDOpcodes.h:233
@ AssertAlign
AssertAlign - These nodes record if a register contains a value that has a known alignment and the tr...
Definition ISDOpcodes.h:69
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ SADDO
RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
Definition ISDOpcodes.h:348
@ TargetGlobalAddress
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
Definition ISDOpcodes.h:185
@ STRICT_FP_TO_FP16
@ ATOMIC_LOAD_FMAXIMUM
@ STRICT_FP16_TO_FP
@ AssertNoFPClass
AssertNoFPClass - These nodes record if a register contains a float value that is known to be not som...
Definition ISDOpcodes.h:78
@ VECTOR_SHUFFLE
VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as VEC1/VEC2.
Definition ISDOpcodes.h: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_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.
bool matchUnaryFpPredicate(SDValue Op, std::function< bool(ConstantFPSDNode *)> Match, bool AllowUndefs=false)
Hook for matching ConstantFPSDNode predicate.
LLVM_ABI bool isConstantSplatVectorAllZeros(const SDNode *N, bool BuildVectorOnly=false)
Return true if the specified node is a BUILD_VECTOR or SPLAT_VECTOR where all of the elements are 0 o...
LLVM_ABI bool isVectorShrinkable(const SDNode *N, unsigned NewEltSize, bool Signed)
Returns true if the specified node is a vector where all elements can be truncated to the specified e...
bool isUNINDEXEDLoad(const SDNode *N)
Returns true if the specified node is an unindexed load.
bool isEXTLoad(const SDNode *N)
Returns true if the specified node is a EXTLOAD.
LLVM_ABI bool allOperandsUndef(const SDNode *N)
Return true if the node has at least one operand and all operands of the specified node are ISD::UNDE...
LLVM_ABI bool isFreezeUndef(const SDNode *N)
Return true if the specified node is FREEZE(UNDEF).
MemIndexType
MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's index parameter when calcula...
LLVM_ABI bool isBuildVectorAllZeros(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are 0 or undef.
bool matchUnaryPredicateImpl(SDValue Op, std::function< bool(ConstNodeType *)> Match, bool AllowUndefs=false, bool AllowTruncation=false)
Attempt to match a unary predicate against a scalar/splat constant or every element of a constant BUI...
LLVM_ABI bool isConstantSplatVector(const SDNode *N, APInt &SplatValue)
Node predicates.
LLVM_ABI bool matchBinaryPredicate(SDValue LHS, SDValue RHS, std::function< bool(ConstantSDNode *, ConstantSDNode *)> Match, bool AllowUndefs=false, bool AllowTypeMismatch=false)
Attempt to match a binary predicate against a pair of scalar/splat constants or every element of a pa...
bool isUNINDEXEDStore(const SDNode *N)
Returns true if the specified node is an unindexed store.
bool matchUnaryPredicate(SDValue Op, std::function< bool(ConstantSDNode *)> Match, bool AllowUndefs=false, bool AllowTruncation=false)
Hook for matching ConstantSDNode predicate.
MemIndexedMode
MemIndexedMode enum - This enum defines the load / store indexed addressing modes.
LLVM_ABI bool isBuildVectorOfConstantFPSDNodes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR node of all ConstantFPSDNode or undef.
bool isSEXTLoad(const SDNode *N)
Returns true if the specified node is a SEXTLOAD.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
LLVM_ABI bool isBuildVectorAllOnes(const SDNode *N)
Return true if the specified node is a BUILD_VECTOR where all of the elements are ~0 or undef.
LoadExtType
LoadExtType enum - This enum defines the three variants of LOADEXT (load with extension).
LLVM_ABI bool isVPOpcode(unsigned Opcode)
Whether this is a vector-predicated Opcode.
bool isNormalLoad(const SDNode *N)
Returns true if the specified node is a non-extending and unindexed load.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
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:1572
APInt operator&(APInt a, const APInt &b)
Definition APInt.h:2154
LLVM_ABI SDValue getBitwiseNotOperand(SDValue V, SDValue Mask, bool AllowUndefs)
If V is a bitwise not, returns the inverted operand.
LLVM_ABI SDValue peekThroughBitcasts(SDValue V)
Return the non-bitcasted source operand of V if it exists.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool isIntOrFPConstant(SDValue V)
Return true if V is either a integer or FP constant.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
FoldingSetBase::Node FoldingSetNode
Definition FoldingSet.h:404
LLVM_ABI bool isOneOrOneSplatFP(SDValue V, bool AllowUndefs=false)
Return true if the value is a constant floating-point value, or a splatted vector of a constant float...
LLVM_ABI bool isNullOrNullSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndefs=false)
Return true if the value is a constant 0 integer or a splatted vector of a constant 0 integer (with n...
Definition Utils.cpp:1554
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:2174
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:860
#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
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