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