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