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