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