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