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