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