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