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