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