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