File indexing completed on 2026-05-10 08:43:35
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CODEGEN_SELECTIONDAG_H
0015 #define LLVM_CODEGEN_SELECTIONDAG_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/DenseMap.h"
0019 #include "llvm/ADT/DenseSet.h"
0020 #include "llvm/ADT/FoldingSet.h"
0021 #include "llvm/ADT/SmallVector.h"
0022 #include "llvm/ADT/StringMap.h"
0023 #include "llvm/ADT/ilist.h"
0024 #include "llvm/ADT/iterator.h"
0025 #include "llvm/ADT/iterator_range.h"
0026 #include "llvm/CodeGen/DAGCombine.h"
0027 #include "llvm/CodeGen/ISDOpcodes.h"
0028 #include "llvm/CodeGen/MachineFunction.h"
0029 #include "llvm/CodeGen/MachineMemOperand.h"
0030 #include "llvm/CodeGen/MachinePassManager.h"
0031 #include "llvm/CodeGen/SelectionDAGNodes.h"
0032 #include "llvm/CodeGen/ValueTypes.h"
0033 #include "llvm/CodeGenTypes/MachineValueType.h"
0034 #include "llvm/IR/ConstantRange.h"
0035 #include "llvm/IR/DebugLoc.h"
0036 #include "llvm/IR/Metadata.h"
0037 #include "llvm/IR/RuntimeLibcalls.h"
0038 #include "llvm/Support/Allocator.h"
0039 #include "llvm/Support/ArrayRecycler.h"
0040 #include "llvm/Support/CodeGen.h"
0041 #include "llvm/Support/ErrorHandling.h"
0042 #include "llvm/Support/RecyclingAllocator.h"
0043 #include <cassert>
0044 #include <cstdint>
0045 #include <functional>
0046 #include <map>
0047 #include <set>
0048 #include <string>
0049 #include <tuple>
0050 #include <utility>
0051 #include <vector>
0052
0053 namespace llvm {
0054
0055 class DIExpression;
0056 class DILabel;
0057 class DIVariable;
0058 class Function;
0059 class Pass;
0060 class Type;
0061 template <class GraphType> struct GraphTraits;
0062 template <typename T, unsigned int N> class SmallSetVector;
0063 template <typename T, typename Enable> struct FoldingSetTrait;
0064 class BatchAAResults;
0065 class BlockAddress;
0066 class BlockFrequencyInfo;
0067 class Constant;
0068 class ConstantFP;
0069 class ConstantInt;
0070 class DataLayout;
0071 struct fltSemantics;
0072 class FunctionLoweringInfo;
0073 class FunctionVarLocs;
0074 class GlobalValue;
0075 struct KnownBits;
0076 class LLVMContext;
0077 class MachineBasicBlock;
0078 class MachineConstantPoolValue;
0079 class MachineModuleInfo;
0080 class MCSymbol;
0081 class OptimizationRemarkEmitter;
0082 class ProfileSummaryInfo;
0083 class SDDbgValue;
0084 class SDDbgOperand;
0085 class SDDbgLabel;
0086 class SelectionDAG;
0087 class SelectionDAGTargetInfo;
0088 class TargetLibraryInfo;
0089 class TargetLowering;
0090 class TargetMachine;
0091 class TargetSubtargetInfo;
0092 class Value;
0093
0094 template <typename T> class GenericSSAContext;
0095 using SSAContext = GenericSSAContext<Function>;
0096 template <typename T> class GenericUniformityInfo;
0097 using UniformityInfo = GenericUniformityInfo<SSAContext>;
0098
0099 class SDVTListNode : public FoldingSetNode {
0100 friend struct FoldingSetTrait<SDVTListNode>;
0101
0102
0103
0104
0105
0106
0107 FoldingSetNodeIDRef FastID;
0108 const EVT *VTs;
0109 unsigned int NumVTs;
0110
0111
0112 unsigned HashValue;
0113
0114 public:
0115 SDVTListNode(const FoldingSetNodeIDRef ID, const EVT *VT, unsigned int Num) :
0116 FastID(ID), VTs(VT), NumVTs(Num) {
0117 HashValue = ID.ComputeHash();
0118 }
0119
0120 SDVTList getSDVTList() {
0121 SDVTList result = {VTs, NumVTs};
0122 return result;
0123 }
0124 };
0125
0126
0127
0128 template<> struct FoldingSetTrait<SDVTListNode> : DefaultFoldingSetTrait<SDVTListNode> {
0129 static void Profile(const SDVTListNode &X, FoldingSetNodeID& ID) {
0130 ID = X.FastID;
0131 }
0132
0133 static bool Equals(const SDVTListNode &X, const FoldingSetNodeID &ID,
0134 unsigned IDHash, FoldingSetNodeID &TempID) {
0135 if (X.HashValue != IDHash)
0136 return false;
0137 return ID == X.FastID;
0138 }
0139
0140 static unsigned ComputeHash(const SDVTListNode &X, FoldingSetNodeID &TempID) {
0141 return X.HashValue;
0142 }
0143 };
0144
0145 template <> struct ilist_alloc_traits<SDNode> {
0146 static void deleteNode(SDNode *) {
0147 llvm_unreachable("ilist_traits<SDNode> shouldn't see a deleteNode call!");
0148 }
0149 };
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162 class SDDbgInfo {
0163 BumpPtrAllocator Alloc;
0164 SmallVector<SDDbgValue*, 32> DbgValues;
0165 SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
0166 SmallVector<SDDbgLabel*, 4> DbgLabels;
0167 using DbgValMapType = DenseMap<const SDNode *, SmallVector<SDDbgValue *, 2>>;
0168 DbgValMapType DbgValMap;
0169
0170 public:
0171 SDDbgInfo() = default;
0172 SDDbgInfo(const SDDbgInfo &) = delete;
0173 SDDbgInfo &operator=(const SDDbgInfo &) = delete;
0174
0175 void add(SDDbgValue *V, bool isParameter);
0176
0177 void add(SDDbgLabel *L) { DbgLabels.push_back(L); }
0178
0179
0180
0181 void erase(const SDNode *Node);
0182
0183 void clear() {
0184 DbgValMap.clear();
0185 DbgValues.clear();
0186 ByvalParmDbgValues.clear();
0187 DbgLabels.clear();
0188 Alloc.Reset();
0189 }
0190
0191 BumpPtrAllocator &getAlloc() { return Alloc; }
0192
0193 bool empty() const {
0194 return DbgValues.empty() && ByvalParmDbgValues.empty() && DbgLabels.empty();
0195 }
0196
0197 ArrayRef<SDDbgValue*> getSDDbgValues(const SDNode *Node) const {
0198 auto I = DbgValMap.find(Node);
0199 if (I != DbgValMap.end())
0200 return I->second;
0201 return ArrayRef<SDDbgValue*>();
0202 }
0203
0204 using DbgIterator = SmallVectorImpl<SDDbgValue*>::iterator;
0205 using DbgLabelIterator = SmallVectorImpl<SDDbgLabel*>::iterator;
0206
0207 DbgIterator DbgBegin() { return DbgValues.begin(); }
0208 DbgIterator DbgEnd() { return DbgValues.end(); }
0209 DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
0210 DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); }
0211 DbgLabelIterator DbgLabelBegin() { return DbgLabels.begin(); }
0212 DbgLabelIterator DbgLabelEnd() { return DbgLabels.end(); }
0213 };
0214
0215 void checkForCycles(const SelectionDAG *DAG, bool force = false);
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 class SelectionDAG {
0229 const TargetMachine &TM;
0230 const SelectionDAGTargetInfo *TSI = nullptr;
0231 const TargetLowering *TLI = nullptr;
0232 const TargetLibraryInfo *LibInfo = nullptr;
0233 const FunctionVarLocs *FnVarLocs = nullptr;
0234 MachineFunction *MF;
0235 MachineFunctionAnalysisManager *MFAM = nullptr;
0236 Pass *SDAGISelPass = nullptr;
0237 LLVMContext *Context;
0238 CodeGenOptLevel OptLevel;
0239
0240 UniformityInfo *UA = nullptr;
0241 FunctionLoweringInfo * FLI = nullptr;
0242
0243
0244
0245 OptimizationRemarkEmitter *ORE;
0246
0247 ProfileSummaryInfo *PSI = nullptr;
0248 BlockFrequencyInfo *BFI = nullptr;
0249 MachineModuleInfo *MMI = nullptr;
0250
0251
0252 std::set<EVT, EVT::compareRawBits> EVTs;
0253
0254
0255 FoldingSet<SDVTListNode> VTListMap;
0256
0257
0258 BumpPtrAllocator Allocator;
0259
0260
0261 SDNode EntryNode;
0262
0263
0264 SDValue Root;
0265
0266
0267 ilist<SDNode> AllNodes;
0268
0269
0270
0271 using NodeAllocatorType = RecyclingAllocator<BumpPtrAllocator, SDNode,
0272 sizeof(LargestSDNode),
0273 alignof(MostAlignedSDNode)>;
0274
0275
0276 NodeAllocatorType NodeAllocator;
0277
0278
0279
0280 FoldingSet<SDNode> CSEMap;
0281
0282
0283 BumpPtrAllocator OperandAllocator;
0284 ArrayRecycler<SDUse> OperandRecycler;
0285
0286
0287 SDDbgInfo *DbgInfo;
0288
0289 using CallSiteInfo = MachineFunction::CallSiteInfo;
0290 using CalledGlobalInfo = MachineFunction::CalledGlobalInfo;
0291
0292 struct NodeExtraInfo {
0293 CallSiteInfo CSInfo;
0294 MDNode *HeapAllocSite = nullptr;
0295 MDNode *PCSections = nullptr;
0296 MDNode *MMRA = nullptr;
0297 CalledGlobalInfo CalledGlobal{};
0298 bool NoMerge = false;
0299 };
0300
0301 DenseMap<const SDNode *, NodeExtraInfo> SDEI;
0302
0303
0304
0305
0306
0307
0308 uint16_t NextPersistentId = 0;
0309
0310 public:
0311
0312
0313
0314
0315
0316
0317 struct DAGUpdateListener {
0318 DAGUpdateListener *const Next;
0319 SelectionDAG &DAG;
0320
0321 explicit DAGUpdateListener(SelectionDAG &D)
0322 : Next(D.UpdateListeners), DAG(D) {
0323 DAG.UpdateListeners = this;
0324 }
0325
0326 virtual ~DAGUpdateListener() {
0327 assert(DAG.UpdateListeners == this &&
0328 "DAGUpdateListeners must be destroyed in LIFO order");
0329 DAG.UpdateListeners = Next;
0330 }
0331
0332
0333
0334 virtual void NodeDeleted(SDNode *N, SDNode *E);
0335
0336
0337 virtual void NodeUpdated(SDNode *N);
0338
0339
0340 virtual void NodeInserted(SDNode *N);
0341 };
0342
0343 struct DAGNodeDeletedListener : public DAGUpdateListener {
0344 std::function<void(SDNode *, SDNode *)> Callback;
0345
0346 DAGNodeDeletedListener(SelectionDAG &DAG,
0347 std::function<void(SDNode *, SDNode *)> Callback)
0348 : DAGUpdateListener(DAG), Callback(std::move(Callback)) {}
0349
0350 void NodeDeleted(SDNode *N, SDNode *E) override { Callback(N, E); }
0351
0352 private:
0353 virtual void anchor();
0354 };
0355
0356 struct DAGNodeInsertedListener : public DAGUpdateListener {
0357 std::function<void(SDNode *)> Callback;
0358
0359 DAGNodeInsertedListener(SelectionDAG &DAG,
0360 std::function<void(SDNode *)> Callback)
0361 : DAGUpdateListener(DAG), Callback(std::move(Callback)) {}
0362
0363 void NodeInserted(SDNode *N) override { Callback(N); }
0364
0365 private:
0366 virtual void anchor();
0367 };
0368
0369
0370
0371 class FlagInserter {
0372 SelectionDAG &DAG;
0373 SDNodeFlags Flags;
0374 FlagInserter *LastInserter;
0375
0376 public:
0377 FlagInserter(SelectionDAG &SDAG, SDNodeFlags Flags)
0378 : DAG(SDAG), Flags(Flags),
0379 LastInserter(SDAG.getFlagInserter()) {
0380 SDAG.setFlagInserter(this);
0381 }
0382 FlagInserter(SelectionDAG &SDAG, SDNode *N)
0383 : FlagInserter(SDAG, N->getFlags()) {}
0384
0385 FlagInserter(const FlagInserter &) = delete;
0386 FlagInserter &operator=(const FlagInserter &) = delete;
0387 ~FlagInserter() { DAG.setFlagInserter(LastInserter); }
0388
0389 SDNodeFlags getFlags() const { return Flags; }
0390 };
0391
0392
0393
0394
0395
0396
0397 bool NewNodesMustHaveLegalTypes = false;
0398
0399 private:
0400
0401 friend struct DAGUpdateListener;
0402
0403
0404
0405 DAGUpdateListener *UpdateListeners = nullptr;
0406
0407
0408
0409 bool setSubgraphColorHelper(SDNode *N, const char *Color,
0410 DenseSet<SDNode *> &visited,
0411 int level, bool &printed);
0412
0413 template <typename SDNodeT, typename... ArgTypes>
0414 SDNodeT *newSDNode(ArgTypes &&... Args) {
0415 return new (NodeAllocator.template Allocate<SDNodeT>())
0416 SDNodeT(std::forward<ArgTypes>(Args)...);
0417 }
0418
0419
0420
0421
0422
0423
0424
0425 template <typename SDNodeT, typename... ArgTypes>
0426 static uint16_t getSyntheticNodeSubclassData(unsigned IROrder,
0427 ArgTypes &&... Args) {
0428
0429
0430
0431 return SDNodeT(IROrder, DebugLoc(), std::forward<ArgTypes>(Args)...)
0432 .getRawSubclassData();
0433 }
0434
0435 template <typename SDNodeTy>
0436 static uint16_t getSyntheticNodeSubclassData(unsigned Opc, unsigned Order,
0437 SDVTList VTs, EVT MemoryVT,
0438 MachineMemOperand *MMO) {
0439 return SDNodeTy(Opc, Order, DebugLoc(), VTs, MemoryVT, MMO)
0440 .getRawSubclassData();
0441 }
0442
0443 void createOperands(SDNode *Node, ArrayRef<SDValue> Vals);
0444
0445 void removeOperands(SDNode *Node) {
0446 if (!Node->OperandList)
0447 return;
0448 OperandRecycler.deallocate(
0449 ArrayRecycler<SDUse>::Capacity::get(Node->NumOperands),
0450 Node->OperandList);
0451 Node->NumOperands = 0;
0452 Node->OperandList = nullptr;
0453 }
0454 void CreateTopologicalOrder(std::vector<SDNode*>& Order);
0455
0456 public:
0457
0458 static constexpr unsigned MaxRecursionDepth = 6;
0459
0460
0461 static unsigned getHasPredecessorMaxSteps();
0462
0463 explicit SelectionDAG(const TargetMachine &TM, CodeGenOptLevel);
0464 SelectionDAG(const SelectionDAG &) = delete;
0465 SelectionDAG &operator=(const SelectionDAG &) = delete;
0466 ~SelectionDAG();
0467
0468
0469 void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE,
0470 Pass *PassPtr, const TargetLibraryInfo *LibraryInfo,
0471 UniformityInfo *UA, ProfileSummaryInfo *PSIin,
0472 BlockFrequencyInfo *BFIin, MachineModuleInfo &MMI,
0473 FunctionVarLocs const *FnVarLocs);
0474
0475 void init(MachineFunction &NewMF, OptimizationRemarkEmitter &NewORE,
0476 MachineFunctionAnalysisManager &AM,
0477 const TargetLibraryInfo *LibraryInfo, UniformityInfo *UA,
0478 ProfileSummaryInfo *PSIin, BlockFrequencyInfo *BFIin,
0479 MachineModuleInfo &MMI, FunctionVarLocs const *FnVarLocs) {
0480 init(NewMF, NewORE, nullptr, LibraryInfo, UA, PSIin, BFIin, MMI, FnVarLocs);
0481 MFAM = &AM;
0482 }
0483
0484 void setFunctionLoweringInfo(FunctionLoweringInfo * FuncInfo) {
0485 FLI = FuncInfo;
0486 }
0487
0488
0489
0490 void clear();
0491
0492 MachineFunction &getMachineFunction() const { return *MF; }
0493 const Pass *getPass() const { return SDAGISelPass; }
0494 MachineFunctionAnalysisManager *getMFAM() { return MFAM; }
0495
0496 CodeGenOptLevel getOptLevel() const { return OptLevel; }
0497 const DataLayout &getDataLayout() const { return MF->getDataLayout(); }
0498 const TargetMachine &getTarget() const { return TM; }
0499 const TargetSubtargetInfo &getSubtarget() const { return MF->getSubtarget(); }
0500 template <typename STC> const STC &getSubtarget() const {
0501 return MF->getSubtarget<STC>();
0502 }
0503 const TargetLowering &getTargetLoweringInfo() const { return *TLI; }
0504 const TargetLibraryInfo &getLibInfo() const { return *LibInfo; }
0505 const SelectionDAGTargetInfo &getSelectionDAGInfo() const { return *TSI; }
0506 const UniformityInfo *getUniformityInfo() const { return UA; }
0507
0508
0509 const FunctionVarLocs *getFunctionVarLocs() const { return FnVarLocs; }
0510 LLVMContext *getContext() const { return Context; }
0511 OptimizationRemarkEmitter &getORE() const { return *ORE; }
0512 ProfileSummaryInfo *getPSI() const { return PSI; }
0513 BlockFrequencyInfo *getBFI() const { return BFI; }
0514 MachineModuleInfo *getMMI() const { return MMI; }
0515
0516 FlagInserter *getFlagInserter() { return Inserter; }
0517 void setFlagInserter(FlagInserter *FI) { Inserter = FI; }
0518
0519
0520
0521
0522
0523
0524
0525
0526 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0527 LLVM_DUMP_METHOD void dumpDotGraph(const Twine &FileName, const Twine &Title);
0528 #endif
0529
0530
0531 void viewGraph(const std::string &Title);
0532 void viewGraph();
0533
0534 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0535 std::map<const SDNode *, std::string> NodeGraphAttrs;
0536 #endif
0537
0538
0539
0540 void clearGraphAttrs();
0541
0542
0543 void setGraphAttrs(const SDNode *N, const char *Attrs);
0544
0545
0546
0547 std::string getGraphAttrs(const SDNode *N) const;
0548
0549
0550 void setGraphColor(const SDNode *N, const char *Color);
0551
0552
0553 void setSubgraphColor(SDNode *N, const char *Color);
0554
0555 using allnodes_const_iterator = ilist<SDNode>::const_iterator;
0556
0557 allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); }
0558 allnodes_const_iterator allnodes_end() const { return AllNodes.end(); }
0559
0560 using allnodes_iterator = ilist<SDNode>::iterator;
0561
0562 allnodes_iterator allnodes_begin() { return AllNodes.begin(); }
0563 allnodes_iterator allnodes_end() { return AllNodes.end(); }
0564
0565 ilist<SDNode>::size_type allnodes_size() const {
0566 return AllNodes.size();
0567 }
0568
0569 iterator_range<allnodes_iterator> allnodes() {
0570 return make_range(allnodes_begin(), allnodes_end());
0571 }
0572 iterator_range<allnodes_const_iterator> allnodes() const {
0573 return make_range(allnodes_begin(), allnodes_end());
0574 }
0575
0576
0577 const SDValue &getRoot() const { return Root; }
0578
0579
0580 SDValue getEntryNode() const {
0581 return SDValue(const_cast<SDNode *>(&EntryNode), 0);
0582 }
0583
0584
0585
0586 const SDValue &setRoot(SDValue N) {
0587 assert((!N.getNode() || N.getValueType() == MVT::Other) &&
0588 "DAG root value is not a chain!");
0589 if (N.getNode())
0590 checkForCycles(N.getNode(), this);
0591 Root = N;
0592 if (N.getNode())
0593 checkForCycles(this);
0594 return Root;
0595 }
0596
0597 #if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
0598 void VerifyDAGDivergence();
0599 #endif
0600
0601
0602
0603
0604
0605 void Combine(CombineLevel Level, BatchAAResults *BatchAA,
0606 CodeGenOptLevel OptLevel);
0607
0608
0609
0610
0611
0612
0613
0614 bool LegalizeTypes();
0615
0616
0617
0618
0619
0620
0621
0622 void Legalize();
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643 bool LegalizeOp(SDNode *N, SmallSetVector<SDNode *, 16> &UpdatedNodes);
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656 bool LegalizeVectors();
0657
0658
0659 void RemoveDeadNodes();
0660
0661
0662
0663 void DeleteNode(SDNode *N);
0664
0665
0666 SDVTList getVTList(EVT VT);
0667 SDVTList getVTList(EVT VT1, EVT VT2);
0668 SDVTList getVTList(EVT VT1, EVT VT2, EVT VT3);
0669 SDVTList getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4);
0670 SDVTList getVTList(ArrayRef<EVT> VTs);
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681 SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT,
0682 bool isTarget = false, bool isOpaque = false);
0683 SDValue getConstant(const APInt &Val, const SDLoc &DL, EVT VT,
0684 bool isTarget = false, bool isOpaque = false);
0685
0686 SDValue getSignedConstant(int64_t Val, const SDLoc &DL, EVT VT,
0687 bool isTarget = false, bool isOpaque = false);
0688
0689 SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget = false,
0690 bool IsOpaque = false);
0691
0692 SDValue getConstant(const ConstantInt &Val, const SDLoc &DL, EVT VT,
0693 bool isTarget = false, bool isOpaque = false);
0694 SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL,
0695 bool isTarget = false);
0696 SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL);
0697 SDValue getShiftAmountConstant(const APInt &Val, EVT VT, const SDLoc &DL);
0698 SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL,
0699 bool isTarget = false);
0700
0701 SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT,
0702 bool isOpaque = false) {
0703 return getConstant(Val, DL, VT, true, isOpaque);
0704 }
0705 SDValue getTargetConstant(const APInt &Val, const SDLoc &DL, EVT VT,
0706 bool isOpaque = false) {
0707 return getConstant(Val, DL, VT, true, isOpaque);
0708 }
0709 SDValue getTargetConstant(const ConstantInt &Val, const SDLoc &DL, EVT VT,
0710 bool isOpaque = false) {
0711 return getConstant(Val, DL, VT, true, isOpaque);
0712 }
0713 SDValue getSignedTargetConstant(int64_t Val, const SDLoc &DL, EVT VT,
0714 bool isOpaque = false) {
0715 return getSignedConstant(Val, DL, VT, true, isOpaque);
0716 }
0717
0718
0719
0720 SDValue getBoolConstant(bool V, const SDLoc &DL, EVT VT, EVT OpVT);
0721
0722
0723
0724
0725
0726
0727
0728
0729
0730
0731 SDValue getConstantFP(double Val, const SDLoc &DL, EVT VT,
0732 bool isTarget = false);
0733 SDValue getConstantFP(const APFloat &Val, const SDLoc &DL, EVT VT,
0734 bool isTarget = false);
0735 SDValue getConstantFP(const ConstantFP &V, const SDLoc &DL, EVT VT,
0736 bool isTarget = false);
0737 SDValue getTargetConstantFP(double Val, const SDLoc &DL, EVT VT) {
0738 return getConstantFP(Val, DL, VT, true);
0739 }
0740 SDValue getTargetConstantFP(const APFloat &Val, const SDLoc &DL, EVT VT) {
0741 return getConstantFP(Val, DL, VT, true);
0742 }
0743 SDValue getTargetConstantFP(const ConstantFP &Val, const SDLoc &DL, EVT VT) {
0744 return getConstantFP(Val, DL, VT, true);
0745 }
0746
0747
0748 SDValue getGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT,
0749 int64_t offset = 0, bool isTargetGA = false,
0750 unsigned TargetFlags = 0);
0751 SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT,
0752 int64_t offset = 0, unsigned TargetFlags = 0) {
0753 return getGlobalAddress(GV, DL, VT, offset, true, TargetFlags);
0754 }
0755 SDValue getFrameIndex(int FI, EVT VT, bool isTarget = false);
0756 SDValue getTargetFrameIndex(int FI, EVT VT) {
0757 return getFrameIndex(FI, VT, true);
0758 }
0759 SDValue getJumpTable(int JTI, EVT VT, bool isTarget = false,
0760 unsigned TargetFlags = 0);
0761 SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags = 0) {
0762 return getJumpTable(JTI, VT, true, TargetFlags);
0763 }
0764 SDValue getJumpTableDebugInfo(int JTI, SDValue Chain, const SDLoc &DL);
0765 SDValue getConstantPool(const Constant *C, EVT VT,
0766 MaybeAlign Align = std::nullopt, int Offs = 0,
0767 bool isT = false, unsigned TargetFlags = 0);
0768 SDValue getTargetConstantPool(const Constant *C, EVT VT,
0769 MaybeAlign Align = std::nullopt, int Offset = 0,
0770 unsigned TargetFlags = 0) {
0771 return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
0772 }
0773 SDValue getConstantPool(MachineConstantPoolValue *C, EVT VT,
0774 MaybeAlign Align = std::nullopt, int Offs = 0,
0775 bool isT = false, unsigned TargetFlags = 0);
0776 SDValue getTargetConstantPool(MachineConstantPoolValue *C, EVT VT,
0777 MaybeAlign Align = std::nullopt, int Offset = 0,
0778 unsigned TargetFlags = 0) {
0779 return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
0780 }
0781
0782
0783 SDValue getBasicBlock(MachineBasicBlock *MBB);
0784 SDValue getExternalSymbol(const char *Sym, EVT VT);
0785 SDValue getTargetExternalSymbol(const char *Sym, EVT VT,
0786 unsigned TargetFlags = 0);
0787 SDValue getMCSymbol(MCSymbol *Sym, EVT VT);
0788
0789 SDValue getValueType(EVT);
0790 SDValue getRegister(Register Reg, EVT VT);
0791 SDValue getRegisterMask(const uint32_t *RegMask);
0792 SDValue getEHLabel(const SDLoc &dl, SDValue Root, MCSymbol *Label);
0793 SDValue getLabelNode(unsigned Opcode, const SDLoc &dl, SDValue Root,
0794 MCSymbol *Label);
0795 SDValue getBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset = 0,
0796 bool isTarget = false, unsigned TargetFlags = 0);
0797 SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT,
0798 int64_t Offset = 0, unsigned TargetFlags = 0) {
0799 return getBlockAddress(BA, VT, Offset, true, TargetFlags);
0800 }
0801
0802 SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg,
0803 SDValue N) {
0804 return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
0805 getRegister(Reg, N.getValueType()), N);
0806 }
0807
0808
0809
0810
0811 SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N,
0812 SDValue Glue) {
0813 SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
0814 SDValue Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Glue };
0815 return getNode(ISD::CopyToReg, dl, VTs,
0816 ArrayRef(Ops, Glue.getNode() ? 4 : 3));
0817 }
0818
0819
0820 SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, SDValue Reg, SDValue N,
0821 SDValue Glue) {
0822 SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
0823 SDValue Ops[] = { Chain, Reg, N, Glue };
0824 return getNode(ISD::CopyToReg, dl, VTs,
0825 ArrayRef(Ops, Glue.getNode() ? 4 : 3));
0826 }
0827
0828 SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT) {
0829 SDVTList VTs = getVTList(VT, MVT::Other);
0830 SDValue Ops[] = { Chain, getRegister(Reg, VT) };
0831 return getNode(ISD::CopyFromReg, dl, VTs, Ops);
0832 }
0833
0834
0835
0836
0837 SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT,
0838 SDValue Glue) {
0839 SDVTList VTs = getVTList(VT, MVT::Other, MVT::Glue);
0840 SDValue Ops[] = { Chain, getRegister(Reg, VT), Glue };
0841 return getNode(ISD::CopyFromReg, dl, VTs,
0842 ArrayRef(Ops, Glue.getNode() ? 3 : 2));
0843 }
0844
0845 SDValue getCondCode(ISD::CondCode Cond);
0846
0847
0848
0849
0850 SDValue getVectorShuffle(EVT VT, const SDLoc &dl, SDValue N1, SDValue N2,
0851 ArrayRef<int> Mask);
0852
0853
0854
0855
0856
0857 SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef<SDValue> Ops) {
0858
0859 return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
0860 }
0861
0862
0863
0864
0865
0866 SDValue getBuildVector(EVT VT, const SDLoc &DL, ArrayRef<SDUse> Ops) {
0867
0868 return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
0869 }
0870
0871
0872
0873
0874 SDValue getSplatBuildVector(EVT VT, const SDLoc &DL, SDValue Op) {
0875
0876 if (Op.getOpcode() == ISD::UNDEF) {
0877 assert((VT.getVectorElementType() == Op.getValueType() ||
0878 (VT.isInteger() &&
0879 VT.getVectorElementType().bitsLE(Op.getValueType()))) &&
0880 "A splatted value must have a width equal or (for integers) "
0881 "greater than the vector element type!");
0882 return getNode(ISD::UNDEF, SDLoc(), VT);
0883 }
0884
0885 SmallVector<SDValue, 16> Ops(VT.getVectorNumElements(), Op);
0886 return getNode(ISD::BUILD_VECTOR, DL, VT, Ops);
0887 }
0888
0889
0890
0891 SDValue getSplatVector(EVT VT, const SDLoc &DL, SDValue Op) {
0892 if (Op.getOpcode() == ISD::UNDEF) {
0893 assert((VT.getVectorElementType() == Op.getValueType() ||
0894 (VT.isInteger() &&
0895 VT.getVectorElementType().bitsLE(Op.getValueType()))) &&
0896 "A splatted value must have a width equal or (for integers) "
0897 "greater than the vector element type!");
0898 return getNode(ISD::UNDEF, SDLoc(), VT);
0899 }
0900 return getNode(ISD::SPLAT_VECTOR, DL, VT, Op);
0901 }
0902
0903
0904
0905
0906
0907 SDValue getSplat(EVT VT, const SDLoc &DL, SDValue Op) {
0908 assert(VT.isVector() && "Can't splat to non-vector type");
0909 return VT.isScalableVector() ?
0910 getSplatVector(VT, DL, Op) : getSplatBuildVector(VT, DL, Op);
0911 }
0912
0913
0914
0915 SDValue getStepVector(const SDLoc &DL, EVT ResVT, const APInt &StepVal);
0916
0917
0918
0919 SDValue getStepVector(const SDLoc &DL, EVT ResVT);
0920
0921
0922
0923
0924
0925 SDValue getCommutedVectorShuffle(const ShuffleVectorSDNode &SV);
0926
0927
0928
0929 SDValue getFPExtendOrRound(SDValue Op, const SDLoc &DL, EVT VT);
0930
0931
0932
0933 std::pair<SDValue, SDValue>
0934 getStrictFPExtendOrRound(SDValue Op, SDValue Chain, const SDLoc &DL, EVT VT);
0935
0936
0937 static unsigned getOpcode_EXTEND(unsigned Opcode) {
0938 switch (Opcode) {
0939 case ISD::ANY_EXTEND:
0940 case ISD::ANY_EXTEND_VECTOR_INREG:
0941 return ISD::ANY_EXTEND;
0942 case ISD::ZERO_EXTEND:
0943 case ISD::ZERO_EXTEND_VECTOR_INREG:
0944 return ISD::ZERO_EXTEND;
0945 case ISD::SIGN_EXTEND:
0946 case ISD::SIGN_EXTEND_VECTOR_INREG:
0947 return ISD::SIGN_EXTEND;
0948 }
0949 llvm_unreachable("Unknown opcode");
0950 }
0951
0952
0953 static unsigned getOpcode_EXTEND_VECTOR_INREG(unsigned Opcode) {
0954 switch (Opcode) {
0955 case ISD::ANY_EXTEND:
0956 case ISD::ANY_EXTEND_VECTOR_INREG:
0957 return ISD::ANY_EXTEND_VECTOR_INREG;
0958 case ISD::ZERO_EXTEND:
0959 case ISD::ZERO_EXTEND_VECTOR_INREG:
0960 return ISD::ZERO_EXTEND_VECTOR_INREG;
0961 case ISD::SIGN_EXTEND:
0962 case ISD::SIGN_EXTEND_VECTOR_INREG:
0963 return ISD::SIGN_EXTEND_VECTOR_INREG;
0964 }
0965 llvm_unreachable("Unknown opcode");
0966 }
0967
0968
0969
0970 SDValue getAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
0971
0972
0973
0974 SDValue getSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
0975
0976
0977
0978 SDValue getZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
0979
0980
0981
0982
0983 SDValue getExtOrTrunc(SDValue Op, const SDLoc &DL,
0984 EVT VT, unsigned Opcode) {
0985 switch(Opcode) {
0986 case ISD::ANY_EXTEND:
0987 return getAnyExtOrTrunc(Op, DL, VT);
0988 case ISD::ZERO_EXTEND:
0989 return getZExtOrTrunc(Op, DL, VT);
0990 case ISD::SIGN_EXTEND:
0991 return getSExtOrTrunc(Op, DL, VT);
0992 }
0993 llvm_unreachable("Unsupported opcode");
0994 }
0995
0996
0997
0998
0999 SDValue getExtOrTrunc(bool IsSigned, SDValue Op, const SDLoc &DL, EVT VT) {
1000 return IsSigned ? getSExtOrTrunc(Op, DL, VT) : getZExtOrTrunc(Op, DL, VT);
1001 }
1002
1003
1004
1005
1006 SDValue getBitcastedAnyExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
1007
1008
1009
1010
1011 SDValue getBitcastedSExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
1012
1013
1014
1015
1016 SDValue getBitcastedZExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
1017
1018
1019
1020 SDValue getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT);
1021
1022
1023
1024 SDValue getVPZeroExtendInReg(SDValue Op, SDValue Mask, SDValue EVL,
1025 const SDLoc &DL, EVT VT);
1026
1027
1028
1029
1030 SDValue getPtrExtOrTrunc(SDValue Op, const SDLoc &DL, EVT VT);
1031
1032
1033
1034
1035 SDValue getPtrExtendInReg(SDValue Op, const SDLoc &DL, EVT VT);
1036
1037
1038
1039
1040 SDValue getBoolExtOrTrunc(SDValue Op, const SDLoc &SL, EVT VT, EVT OpVT);
1041
1042
1043 SDValue getNegative(SDValue Val, const SDLoc &DL, EVT VT);
1044
1045
1046 SDValue getNOT(const SDLoc &DL, SDValue Val, EVT VT);
1047
1048
1049 SDValue getLogicalNOT(const SDLoc &DL, SDValue Val, EVT VT);
1050
1051
1052
1053 SDValue getVPLogicalNOT(const SDLoc &DL, SDValue Val, SDValue Mask,
1054 SDValue EVL, EVT VT);
1055
1056
1057
1058
1059
1060 SDValue getVPZExtOrTrunc(const SDLoc &DL, EVT VT, SDValue Op, SDValue Mask,
1061 SDValue EVL);
1062
1063
1064
1065
1066
1067
1068 SDValue getVPPtrExtOrTrunc(const SDLoc &DL, EVT VT, SDValue Op, SDValue Mask,
1069 SDValue EVL);
1070
1071
1072
1073 SDValue getMemBasePlusOffset(SDValue Base, TypeSize Offset, const SDLoc &DL,
1074 const SDNodeFlags Flags = SDNodeFlags());
1075 SDValue getMemBasePlusOffset(SDValue Base, SDValue Offset, const SDLoc &DL,
1076 const SDNodeFlags Flags = SDNodeFlags());
1077
1078
1079
1080
1081 SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, TypeSize Offset) {
1082 return getMemBasePlusOffset(Ptr, Offset, SL, SDNodeFlags::NoUnsignedWrap);
1083 }
1084
1085 SDValue getObjectPtrOffset(const SDLoc &SL, SDValue Ptr, SDValue Offset) {
1086
1087
1088 return getMemBasePlusOffset(Ptr, Offset, SL, SDNodeFlags::NoUnsignedWrap);
1089 }
1090
1091
1092
1093
1094 SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize,
1095 const SDLoc &DL) {
1096 SDVTList VTs = getVTList(MVT::Other, MVT::Glue);
1097 SDValue Ops[] = { Chain,
1098 getIntPtrConstant(InSize, DL, true),
1099 getIntPtrConstant(OutSize, DL, true) };
1100 return getNode(ISD::CALLSEQ_START, DL, VTs, Ops);
1101 }
1102
1103
1104
1105
1106 SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2,
1107 SDValue InGlue, const SDLoc &DL) {
1108 SDVTList NodeTys = getVTList(MVT::Other, MVT::Glue);
1109 SmallVector<SDValue, 4> Ops;
1110 Ops.push_back(Chain);
1111 Ops.push_back(Op1);
1112 Ops.push_back(Op2);
1113 if (InGlue.getNode())
1114 Ops.push_back(InGlue);
1115 return getNode(ISD::CALLSEQ_END, DL, NodeTys, Ops);
1116 }
1117
1118 SDValue getCALLSEQ_END(SDValue Chain, uint64_t Size1, uint64_t Size2,
1119 SDValue Glue, const SDLoc &DL) {
1120 return getCALLSEQ_END(
1121 Chain, getIntPtrConstant(Size1, DL, true),
1122 getIntPtrConstant(Size2, DL, true), Glue, DL);
1123 }
1124
1125
1126 bool isUndef(unsigned Opcode, ArrayRef<SDValue> Ops);
1127
1128
1129 SDValue getUNDEF(EVT VT) {
1130 return getNode(ISD::UNDEF, SDLoc(), VT);
1131 }
1132
1133
1134 SDValue getVScale(const SDLoc &DL, EVT VT, APInt MulImm,
1135 bool ConstantFold = true);
1136
1137 SDValue getElementCount(const SDLoc &DL, EVT VT, ElementCount EC,
1138 bool ConstantFold = true);
1139
1140
1141 SDValue getGLOBAL_OFFSET_TABLE(EVT VT) {
1142 return getNode(ISD::GLOBAL_OFFSET_TABLE, SDLoc(), VT);
1143 }
1144
1145
1146
1147 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1148 ArrayRef<SDUse> Ops);
1149 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1150 ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
1151 SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys,
1152 ArrayRef<SDValue> Ops);
1153 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
1154 ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
1155
1156
1157 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT,
1158 ArrayRef<SDValue> Ops);
1159 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
1160 ArrayRef<SDValue> Ops);
1161 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand);
1162 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1163 SDValue N2);
1164 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1165 SDValue N2, SDValue N3);
1166
1167
1168 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT);
1169 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue Operand,
1170 const SDNodeFlags Flags);
1171 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1172 SDValue N2, const SDNodeFlags Flags);
1173 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1174 SDValue N2, SDValue N3, const SDNodeFlags Flags);
1175 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1176 SDValue N2, SDValue N3, SDValue N4);
1177 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1178 SDValue N2, SDValue N3, SDValue N4, const SDNodeFlags Flags);
1179 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1180 SDValue N2, SDValue N3, SDValue N4, SDValue N5);
1181 SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, SDValue N1,
1182 SDValue N2, SDValue N3, SDValue N4, SDValue N5,
1183 const SDNodeFlags Flags);
1184
1185
1186
1187 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList);
1188 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, SDValue N);
1189 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, SDValue N1,
1190 SDValue N2);
1191 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, SDValue N1,
1192 SDValue N2, SDValue N3);
1193 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, SDValue N1,
1194 SDValue N2, SDValue N3, SDValue N4);
1195 SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList, SDValue N1,
1196 SDValue N2, SDValue N3, SDValue N4, SDValue N5);
1197
1198
1199
1200
1201 SDValue getStackArgumentTokenFactor(SDValue Chain);
1202
1203
1204
1205
1206 SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
1207 SDValue Size, Align Alignment, bool isVol,
1208 bool AlwaysInline, const CallInst *CI,
1209 std::optional<bool> OverrideTailCall,
1210 MachinePointerInfo DstPtrInfo,
1211 MachinePointerInfo SrcPtrInfo,
1212 const AAMDNodes &AAInfo = AAMDNodes(),
1213 BatchAAResults *BatchAA = nullptr);
1214
1215
1216
1217
1218 SDValue getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
1219 SDValue Size, Align Alignment, bool isVol,
1220 const CallInst *CI, std::optional<bool> OverrideTailCall,
1221 MachinePointerInfo DstPtrInfo,
1222 MachinePointerInfo SrcPtrInfo,
1223 const AAMDNodes &AAInfo = AAMDNodes(),
1224 BatchAAResults *BatchAA = nullptr);
1225
1226 SDValue getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
1227 SDValue Size, Align Alignment, bool isVol,
1228 bool AlwaysInline, const CallInst *CI,
1229 MachinePointerInfo DstPtrInfo,
1230 const AAMDNodes &AAInfo = AAMDNodes());
1231
1232 SDValue getAtomicMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst,
1233 SDValue Src, SDValue Size, Type *SizeTy,
1234 unsigned ElemSz, bool isTailCall,
1235 MachinePointerInfo DstPtrInfo,
1236 MachinePointerInfo SrcPtrInfo);
1237
1238 SDValue getAtomicMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst,
1239 SDValue Src, SDValue Size, Type *SizeTy,
1240 unsigned ElemSz, bool isTailCall,
1241 MachinePointerInfo DstPtrInfo,
1242 MachinePointerInfo SrcPtrInfo);
1243
1244 SDValue getAtomicMemset(SDValue Chain, const SDLoc &dl, SDValue Dst,
1245 SDValue Value, SDValue Size, Type *SizeTy,
1246 unsigned ElemSz, bool isTailCall,
1247 MachinePointerInfo DstPtrInfo);
1248
1249
1250
1251 SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS,
1252 ISD::CondCode Cond, SDValue Chain = SDValue(),
1253 bool IsSignaling = false) {
1254 assert(LHS.getValueType().isVector() == RHS.getValueType().isVector() &&
1255 "Vector/scalar operand type mismatch for setcc");
1256 assert(LHS.getValueType().isVector() == VT.isVector() &&
1257 "Vector/scalar result type mismatch for setcc");
1258 assert(Cond != ISD::SETCC_INVALID &&
1259 "Cannot create a setCC of an invalid node.");
1260 if (Chain)
1261 return getNode(IsSignaling ? ISD::STRICT_FSETCCS : ISD::STRICT_FSETCC, DL,
1262 {VT, MVT::Other}, {Chain, LHS, RHS, getCondCode(Cond)});
1263 return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
1264 }
1265
1266
1267
1268 SDValue getSetCCVP(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS,
1269 ISD::CondCode Cond, SDValue Mask, SDValue EVL) {
1270 assert(LHS.getValueType().isVector() && RHS.getValueType().isVector() &&
1271 "Cannot compare scalars");
1272 assert(Cond != ISD::SETCC_INVALID &&
1273 "Cannot create a setCC of an invalid node.");
1274 return getNode(ISD::VP_SETCC, DL, VT, LHS, RHS, getCondCode(Cond), Mask,
1275 EVL);
1276 }
1277
1278
1279
1280 SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS,
1281 SDValue RHS, SDNodeFlags Flags = SDNodeFlags()) {
1282 assert(LHS.getValueType() == VT && RHS.getValueType() == VT &&
1283 "Cannot use select on differing types");
1284 auto Opcode = Cond.getValueType().isVector() ? ISD::VSELECT : ISD::SELECT;
1285 return getNode(Opcode, DL, VT, Cond, LHS, RHS, Flags);
1286 }
1287
1288
1289
1290 SDValue getSelectCC(const SDLoc &DL, SDValue LHS, SDValue RHS, SDValue True,
1291 SDValue False, ISD::CondCode Cond) {
1292 return getNode(ISD::SELECT_CC, DL, True.getValueType(), LHS, RHS, True,
1293 False, getCondCode(Cond));
1294 }
1295
1296
1297 SDValue simplifySelect(SDValue Cond, SDValue TVal, SDValue FVal);
1298
1299
1300 SDValue simplifyShift(SDValue X, SDValue Y);
1301
1302
1303
1304 SDValue simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y,
1305 SDNodeFlags Flags);
1306
1307
1308
1309 SDValue getVAArg(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
1310 SDValue SV, unsigned Align);
1311
1312
1313
1314
1315
1316 SDValue getAtomicCmpSwap(unsigned Opcode, const SDLoc &dl, EVT MemVT,
1317 SDVTList VTs, SDValue Chain, SDValue Ptr,
1318 SDValue Cmp, SDValue Swp, MachineMemOperand *MMO);
1319
1320
1321
1322 SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, SDValue Chain,
1323 SDValue Ptr, SDValue Val, MachineMemOperand *MMO);
1324
1325
1326
1327 SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT, EVT VT,
1328 SDValue Chain, SDValue Ptr, MachineMemOperand *MMO);
1329
1330
1331
1332 SDValue getAtomic(unsigned Opcode, const SDLoc &dl, EVT MemVT,
1333 SDVTList VTList, ArrayRef<SDValue> Ops,
1334 MachineMemOperand *MMO);
1335
1336
1337
1338
1339
1340 SDValue getMemIntrinsicNode(
1341 unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef<SDValue> Ops,
1342 EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment,
1343 MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad |
1344 MachineMemOperand::MOStore,
1345 LocationSize Size = 0, const AAMDNodes &AAInfo = AAMDNodes());
1346
1347 inline SDValue getMemIntrinsicNode(
1348 unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef<SDValue> Ops,
1349 EVT MemVT, MachinePointerInfo PtrInfo,
1350 MaybeAlign Alignment = std::nullopt,
1351 MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad |
1352 MachineMemOperand::MOStore,
1353 LocationSize Size = 0, const AAMDNodes &AAInfo = AAMDNodes()) {
1354
1355 return getMemIntrinsicNode(Opcode, dl, VTList, Ops, MemVT, PtrInfo,
1356 Alignment.value_or(getEVTAlign(MemVT)), Flags,
1357 Size, AAInfo);
1358 }
1359
1360 SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList,
1361 ArrayRef<SDValue> Ops, EVT MemVT,
1362 MachineMemOperand *MMO);
1363
1364
1365
1366
1367 SDValue getLifetimeNode(bool IsStart, const SDLoc &dl, SDValue Chain,
1368 int FrameIndex, int64_t Size, int64_t Offset = -1);
1369
1370
1371
1372
1373 SDValue getPseudoProbeNode(const SDLoc &Dl, SDValue Chain, uint64_t Guid,
1374 uint64_t Index, uint32_t Attr);
1375
1376
1377 SDValue getMergeValues(ArrayRef<SDValue> Ops, const SDLoc &dl);
1378
1379
1380
1381
1382
1383
1384 SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
1385 MachinePointerInfo PtrInfo,
1386 MaybeAlign Alignment = MaybeAlign(),
1387 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1388 const AAMDNodes &AAInfo = AAMDNodes(),
1389 const MDNode *Ranges = nullptr);
1390 SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
1391 MachineMemOperand *MMO);
1392 SDValue
1393 getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain,
1394 SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT,
1395 MaybeAlign Alignment = MaybeAlign(),
1396 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1397 const AAMDNodes &AAInfo = AAMDNodes());
1398 SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT,
1399 SDValue Chain, SDValue Ptr, EVT MemVT,
1400 MachineMemOperand *MMO);
1401 SDValue getIndexedLoad(SDValue OrigLoad, const SDLoc &dl, SDValue Base,
1402 SDValue Offset, ISD::MemIndexedMode AM);
1403 SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
1404 const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
1405 MachinePointerInfo PtrInfo, EVT MemVT, Align Alignment,
1406 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1407 const AAMDNodes &AAInfo = AAMDNodes(),
1408 const MDNode *Ranges = nullptr);
1409 inline SDValue getLoad(
1410 ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT, const SDLoc &dl,
1411 SDValue Chain, SDValue Ptr, SDValue Offset, MachinePointerInfo PtrInfo,
1412 EVT MemVT, MaybeAlign Alignment = MaybeAlign(),
1413 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1414 const AAMDNodes &AAInfo = AAMDNodes(), const MDNode *Ranges = nullptr) {
1415
1416 return getLoad(AM, ExtType, VT, dl, Chain, Ptr, Offset, PtrInfo, MemVT,
1417 Alignment.value_or(getEVTAlign(MemVT)), MMOFlags, AAInfo,
1418 Ranges);
1419 }
1420 SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
1421 const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
1422 EVT MemVT, MachineMemOperand *MMO);
1423
1424
1425
1426
1427
1428
1429 SDValue
1430 getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
1431 MachinePointerInfo PtrInfo, Align Alignment,
1432 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1433 const AAMDNodes &AAInfo = AAMDNodes());
1434 inline SDValue
1435 getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
1436 MachinePointerInfo PtrInfo, MaybeAlign Alignment = MaybeAlign(),
1437 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1438 const AAMDNodes &AAInfo = AAMDNodes()) {
1439 return getStore(Chain, dl, Val, Ptr, PtrInfo,
1440 Alignment.value_or(getEVTAlign(Val.getValueType())),
1441 MMOFlags, AAInfo);
1442 }
1443 SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
1444 MachineMemOperand *MMO);
1445 SDValue
1446 getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
1447 MachinePointerInfo PtrInfo, EVT SVT, Align Alignment,
1448 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1449 const AAMDNodes &AAInfo = AAMDNodes());
1450 inline SDValue
1451 getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
1452 MachinePointerInfo PtrInfo, EVT SVT,
1453 MaybeAlign Alignment = MaybeAlign(),
1454 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1455 const AAMDNodes &AAInfo = AAMDNodes()) {
1456 return getTruncStore(Chain, dl, Val, Ptr, PtrInfo, SVT,
1457 Alignment.value_or(getEVTAlign(SVT)), MMOFlags,
1458 AAInfo);
1459 }
1460 SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val,
1461 SDValue Ptr, EVT SVT, MachineMemOperand *MMO);
1462 SDValue getIndexedStore(SDValue OrigStore, const SDLoc &dl, SDValue Base,
1463 SDValue Offset, ISD::MemIndexedMode AM);
1464
1465 SDValue getLoadVP(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
1466 const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
1467 SDValue Mask, SDValue EVL, MachinePointerInfo PtrInfo,
1468 EVT MemVT, Align Alignment,
1469 MachineMemOperand::Flags MMOFlags, const AAMDNodes &AAInfo,
1470 const MDNode *Ranges = nullptr, bool IsExpanding = false);
1471 inline SDValue
1472 getLoadVP(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
1473 const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
1474 SDValue Mask, SDValue EVL, MachinePointerInfo PtrInfo, EVT MemVT,
1475 MaybeAlign Alignment = MaybeAlign(),
1476 MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
1477 const AAMDNodes &AAInfo = AAMDNodes(),
1478 const MDNode *Ranges = nullptr, bool IsExpanding = false) {
1479
1480 return getLoadVP(AM, ExtType, VT, dl, Chain, Ptr, Offset, Mask, EVL,
1481 PtrInfo, MemVT, Alignment.value_or(getEVTAlign(MemVT)),
1482 MMOFlags, AAInfo, Ranges, IsExpanding);
1483 }
1484 SDValue getLoadVP(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
1485 const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
1486 SDValue Mask, SDValue EVL, EVT MemVT,
1487 MachineMemOperand *MMO, bool IsExpanding = false);
1488 SDValue getLoadVP(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
1489 SDValue Mask, SDValue EVL, MachinePointerInfo PtrInfo,
1490 MaybeAlign Alignment, MachineMemOperand::Flags MMOFlags,
1491 const AAMDNodes &AAInfo, const MDNode *Ranges = nullptr,
1492 bool IsExpanding = false);
1493 SDValue getLoadVP(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
1494 SDValue Mask, SDValue EVL, MachineMemOperand *MMO,
1495 bool IsExpanding = false);
1496 SDValue getExtLoadVP(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT,
1497 SDValue Chain, SDValue Ptr, SDValue Mask, SDValue EVL,
1498 MachinePointerInfo PtrInfo, EVT MemVT,
1499 MaybeAlign Alignment, MachineMemOperand::Flags MMOFlags,
1500 const AAMDNodes &AAInfo, bool IsExpanding = false);
1501 SDValue getExtLoadVP(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT,
1502 SDValue Chain, SDValue Ptr, SDValue Mask, SDValue EVL,
1503 EVT MemVT, MachineMemOperand *MMO,
1504 bool IsExpanding = false);
1505 SDValue getIndexedLoadVP(SDValue OrigLoad, const SDLoc &dl, SDValue Base,
1506 SDValue Offset, ISD::MemIndexedMode AM);
1507 SDValue getStoreVP(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
1508 SDValue Offset, SDValue Mask, SDValue EVL, EVT MemVT,
1509 MachineMemOperand *MMO, ISD::MemIndexedMode AM,
1510 bool IsTruncating = false, bool IsCompressing = false);
1511 SDValue getTruncStoreVP(SDValue Chain, const SDLoc &dl, SDValue Val,
1512 SDValue Ptr, SDValue Mask, SDValue EVL,
1513 MachinePointerInfo PtrInfo, EVT SVT, Align Alignment,
1514 MachineMemOperand::Flags MMOFlags,
1515 const AAMDNodes &AAInfo, bool IsCompressing = false);
1516 SDValue getTruncStoreVP(SDValue Chain, const SDLoc &dl, SDValue Val,
1517 SDValue Ptr, SDValue Mask, SDValue EVL, EVT SVT,
1518 MachineMemOperand *MMO, bool IsCompressing = false);
1519 SDValue getIndexedStoreVP(SDValue OrigStore, const SDLoc &dl, SDValue Base,
1520 SDValue Offset, ISD::MemIndexedMode AM);
1521
1522 SDValue getStridedLoadVP(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
1523 EVT VT, const SDLoc &DL, SDValue Chain, SDValue Ptr,
1524 SDValue Offset, SDValue Stride, SDValue Mask,
1525 SDValue EVL, EVT MemVT, MachineMemOperand *MMO,
1526 bool IsExpanding = false);
1527 SDValue getStridedLoadVP(EVT VT, const SDLoc &DL, SDValue Chain, SDValue Ptr,
1528 SDValue Stride, SDValue Mask, SDValue EVL,
1529 MachineMemOperand *MMO, bool IsExpanding = false);
1530 SDValue getExtStridedLoadVP(ISD::LoadExtType ExtType, const SDLoc &DL, EVT VT,
1531 SDValue Chain, SDValue Ptr, SDValue Stride,
1532 SDValue Mask, SDValue EVL, EVT MemVT,
1533 MachineMemOperand *MMO, bool IsExpanding = false);
1534 SDValue getStridedStoreVP(SDValue Chain, const SDLoc &DL, SDValue Val,
1535 SDValue Ptr, SDValue Offset, SDValue Stride,
1536 SDValue Mask, SDValue EVL, EVT MemVT,
1537 MachineMemOperand *MMO, ISD::MemIndexedMode AM,
1538 bool IsTruncating = false,
1539 bool IsCompressing = false);
1540 SDValue getTruncStridedStoreVP(SDValue Chain, const SDLoc &DL, SDValue Val,
1541 SDValue Ptr, SDValue Stride, SDValue Mask,
1542 SDValue EVL, EVT SVT, MachineMemOperand *MMO,
1543 bool IsCompressing = false);
1544
1545 SDValue getGatherVP(SDVTList VTs, EVT VT, const SDLoc &dl,
1546 ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
1547 ISD::MemIndexType IndexType);
1548 SDValue getScatterVP(SDVTList VTs, EVT VT, const SDLoc &dl,
1549 ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
1550 ISD::MemIndexType IndexType);
1551
1552 SDValue getMaskedLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Base,
1553 SDValue Offset, SDValue Mask, SDValue Src0, EVT MemVT,
1554 MachineMemOperand *MMO, ISD::MemIndexedMode AM,
1555 ISD::LoadExtType, bool IsExpanding = false);
1556 SDValue getIndexedMaskedLoad(SDValue OrigLoad, const SDLoc &dl, SDValue Base,
1557 SDValue Offset, ISD::MemIndexedMode AM);
1558 SDValue getMaskedStore(SDValue Chain, const SDLoc &dl, SDValue Val,
1559 SDValue Base, SDValue Offset, SDValue Mask, EVT MemVT,
1560 MachineMemOperand *MMO, ISD::MemIndexedMode AM,
1561 bool IsTruncating = false, bool IsCompressing = false);
1562 SDValue getIndexedMaskedStore(SDValue OrigStore, const SDLoc &dl,
1563 SDValue Base, SDValue Offset,
1564 ISD::MemIndexedMode AM);
1565 SDValue getMaskedGather(SDVTList VTs, EVT MemVT, const SDLoc &dl,
1566 ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
1567 ISD::MemIndexType IndexType, ISD::LoadExtType ExtTy);
1568 SDValue getMaskedScatter(SDVTList VTs, EVT MemVT, const SDLoc &dl,
1569 ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
1570 ISD::MemIndexType IndexType,
1571 bool IsTruncating = false);
1572 SDValue getMaskedHistogram(SDVTList VTs, EVT MemVT, const SDLoc &dl,
1573 ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
1574 ISD::MemIndexType IndexType);
1575
1576 SDValue getGetFPEnv(SDValue Chain, const SDLoc &dl, SDValue Ptr, EVT MemVT,
1577 MachineMemOperand *MMO);
1578 SDValue getSetFPEnv(SDValue Chain, const SDLoc &dl, SDValue Ptr, EVT MemVT,
1579 MachineMemOperand *MMO);
1580
1581
1582 SDValue getSrcValue(const Value *v);
1583
1584
1585 SDValue getMDNode(const MDNode *MD);
1586
1587
1588
1589 SDValue getBitcast(EVT VT, SDValue V);
1590
1591
1592 SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS,
1593 unsigned DestAS);
1594
1595
1596 SDValue getFreeze(SDValue V);
1597
1598
1599 SDValue getAssertAlign(const SDLoc &DL, SDValue V, Align A);
1600
1601
1602
1603 void canonicalizeCommutativeBinop(unsigned Opcode, SDValue &N1,
1604 SDValue &N2) const;
1605
1606
1607
1608 SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
1609
1610
1611
1612 SDValue getPartialReduceAdd(SDLoc DL, EVT ReducedTy, SDValue Op1,
1613 SDValue Op2);
1614
1615
1616
1617
1618
1619
1620 bool expandMultipleResultFPLibCall(RTLIB::Libcall LC, SDNode *Node,
1621 SmallVectorImpl<SDValue> &Results,
1622 std::optional<unsigned> CallRetResNo = {});
1623
1624
1625 SDValue expandVAArg(SDNode *Node);
1626
1627
1628 SDValue expandVACopy(SDNode *Node);
1629
1630
1631
1632
1633
1634 SDValue getSymbolFunctionGlobalAddress(SDValue Op,
1635 Function **TargetFunction = nullptr);
1636
1637
1638
1639
1640
1641
1642
1643 SDNode *UpdateNodeOperands(SDNode *N, SDValue Op);
1644 SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2);
1645 SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
1646 SDValue Op3);
1647 SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
1648 SDValue Op3, SDValue Op4);
1649 SDNode *UpdateNodeOperands(SDNode *N, SDValue Op1, SDValue Op2,
1650 SDValue Op3, SDValue Op4, SDValue Op5);
1651 SDNode *UpdateNodeOperands(SDNode *N, ArrayRef<SDValue> Ops);
1652
1653
1654
1655
1656 SDValue getTokenFactor(const SDLoc &DL, SmallVectorImpl<SDValue> &Vals);
1657
1658
1659
1660 void setNodeMemRefs(MachineSDNode *N,
1661 ArrayRef<MachineMemOperand *> NewMemRefs);
1662
1663
1664 bool calculateDivergence(SDNode *N);
1665
1666
1667 void updateDivergence(SDNode * N);
1668
1669
1670
1671
1672
1673 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT);
1674 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT, SDValue Op1);
1675 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT,
1676 SDValue Op1, SDValue Op2);
1677 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT,
1678 SDValue Op1, SDValue Op2, SDValue Op3);
1679 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT,
1680 ArrayRef<SDValue> Ops);
1681 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT1, EVT VT2);
1682 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT1,
1683 EVT VT2, ArrayRef<SDValue> Ops);
1684 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT1,
1685 EVT VT2, EVT VT3, ArrayRef<SDValue> Ops);
1686 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, EVT VT1,
1687 EVT VT2, SDValue Op1, SDValue Op2);
1688 SDNode *SelectNodeTo(SDNode *N, unsigned MachineOpc, SDVTList VTs,
1689 ArrayRef<SDValue> Ops);
1690
1691
1692
1693 SDNode *MorphNodeTo(SDNode *N, unsigned Opc, SDVTList VTs,
1694 ArrayRef<SDValue> Ops);
1695
1696
1697
1698
1699 SDNode *mutateStrictFPToFP(SDNode *Node);
1700
1701
1702
1703
1704
1705
1706
1707 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT);
1708 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT,
1709 SDValue Op1);
1710 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT,
1711 SDValue Op1, SDValue Op2);
1712 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT,
1713 SDValue Op1, SDValue Op2, SDValue Op3);
1714 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT,
1715 ArrayRef<SDValue> Ops);
1716 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1,
1717 EVT VT2, SDValue Op1, SDValue Op2);
1718 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1,
1719 EVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
1720 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1,
1721 EVT VT2, ArrayRef<SDValue> Ops);
1722 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1,
1723 EVT VT2, EVT VT3, SDValue Op1, SDValue Op2);
1724 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1,
1725 EVT VT2, EVT VT3, SDValue Op1, SDValue Op2,
1726 SDValue Op3);
1727 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, EVT VT1,
1728 EVT VT2, EVT VT3, ArrayRef<SDValue> Ops);
1729 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl,
1730 ArrayRef<EVT> ResultTys, ArrayRef<SDValue> Ops);
1731 MachineSDNode *getMachineNode(unsigned Opcode, const SDLoc &dl, SDVTList VTs,
1732 ArrayRef<SDValue> Ops);
1733
1734
1735 SDValue getTargetExtractSubreg(int SRIdx, const SDLoc &DL, EVT VT,
1736 SDValue Operand);
1737
1738
1739 SDValue getTargetInsertSubreg(int SRIdx, const SDLoc &DL, EVT VT,
1740 SDValue Operand, SDValue Subreg);
1741
1742
1743 SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTList,
1744 ArrayRef<SDValue> Ops, const SDNodeFlags Flags);
1745 SDNode *getNodeIfExists(unsigned Opcode, SDVTList VTList,
1746 ArrayRef<SDValue> Ops);
1747
1748
1749 bool doesNodeExist(unsigned Opcode, SDVTList VTList, ArrayRef<SDValue> Ops);
1750
1751
1752 SDDbgValue *getDbgValue(DIVariable *Var, DIExpression *Expr, SDNode *N,
1753 unsigned R, bool IsIndirect, const DebugLoc &DL,
1754 unsigned O);
1755
1756
1757 SDDbgValue *getConstantDbgValue(DIVariable *Var, DIExpression *Expr,
1758 const Value *C, const DebugLoc &DL,
1759 unsigned O);
1760
1761
1762 SDDbgValue *getFrameIndexDbgValue(DIVariable *Var, DIExpression *Expr,
1763 unsigned FI, bool IsIndirect,
1764 const DebugLoc &DL, unsigned O);
1765
1766
1767 SDDbgValue *getFrameIndexDbgValue(DIVariable *Var, DIExpression *Expr,
1768 unsigned FI,
1769 ArrayRef<SDNode *> Dependencies,
1770 bool IsIndirect, const DebugLoc &DL,
1771 unsigned O);
1772
1773
1774 SDDbgValue *getVRegDbgValue(DIVariable *Var, DIExpression *Expr,
1775 unsigned VReg, bool IsIndirect,
1776 const DebugLoc &DL, unsigned O);
1777
1778
1779 SDDbgValue *getDbgValueList(DIVariable *Var, DIExpression *Expr,
1780 ArrayRef<SDDbgOperand> Locs,
1781 ArrayRef<SDNode *> Dependencies, bool IsIndirect,
1782 const DebugLoc &DL, unsigned O, bool IsVariadic);
1783
1784
1785 SDDbgLabel *getDbgLabel(DILabel *Label, const DebugLoc &DL, unsigned O);
1786
1787
1788
1789
1790 void transferDbgValues(SDValue From, SDValue To, unsigned OffsetInBits = 0,
1791 unsigned SizeInBits = 0, bool InvalidateDbg = true);
1792
1793
1794
1795
1796 void RemoveDeadNode(SDNode *N);
1797
1798
1799
1800 void RemoveDeadNodes(SmallVectorImpl<SDNode *> &DeadNodes);
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817 void ReplaceAllUsesWith(SDValue From, SDValue To);
1818 void ReplaceAllUsesWith(SDNode *From, SDNode *To);
1819 void ReplaceAllUsesWith(SDNode *From, const SDValue *To);
1820
1821
1822
1823 void ReplaceAllUsesOfValueWith(SDValue From, SDValue To);
1824
1825
1826
1827
1828 void ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To,
1829 unsigned Num);
1830
1831
1832
1833
1834
1835
1836 SDValue makeEquivalentMemoryOrdering(SDValue OldChain, SDValue NewMemOpChain);
1837
1838
1839
1840
1841
1842
1843 SDValue makeEquivalentMemoryOrdering(LoadSDNode *OldLoad, SDValue NewMemOp);
1844
1845
1846
1847
1848 unsigned AssignTopologicalOrder();
1849
1850
1851
1852
1853 void RepositionNode(allnodes_iterator Position, SDNode *N) {
1854 AllNodes.insert(Position, AllNodes.remove(N));
1855 }
1856
1857
1858
1859 void AddDbgValue(SDDbgValue *DB, bool isParameter);
1860
1861
1862 void AddDbgLabel(SDDbgLabel *DB);
1863
1864
1865 ArrayRef<SDDbgValue*> GetDbgValues(const SDNode* SD) const {
1866 return DbgInfo->getSDDbgValues(SD);
1867 }
1868
1869 public:
1870
1871
1872 bool hasDebugValues() const { return !DbgInfo->empty(); }
1873
1874 SDDbgInfo::DbgIterator DbgBegin() const { return DbgInfo->DbgBegin(); }
1875 SDDbgInfo::DbgIterator DbgEnd() const { return DbgInfo->DbgEnd(); }
1876
1877 SDDbgInfo::DbgIterator ByvalParmDbgBegin() const {
1878 return DbgInfo->ByvalParmDbgBegin();
1879 }
1880 SDDbgInfo::DbgIterator ByvalParmDbgEnd() const {
1881 return DbgInfo->ByvalParmDbgEnd();
1882 }
1883
1884 SDDbgInfo::DbgLabelIterator DbgLabelBegin() const {
1885 return DbgInfo->DbgLabelBegin();
1886 }
1887 SDDbgInfo::DbgLabelIterator DbgLabelEnd() const {
1888 return DbgInfo->DbgLabelEnd();
1889 }
1890
1891
1892
1893 void salvageDebugInfo(SDNode &N);
1894
1895 void dump() const;
1896
1897
1898
1899
1900
1901 Align getReducedAlign(EVT VT, bool UseABI);
1902
1903
1904 SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment);
1905
1906
1907
1908 SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1);
1909
1910
1911
1912 SDValue CreateStackTemporary(EVT VT1, EVT VT2);
1913
1914 SDValue FoldSymbolOffset(unsigned Opcode, EVT VT,
1915 const GlobalAddressSDNode *GA,
1916 const SDNode *N2);
1917
1918 SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
1919 ArrayRef<SDValue> Ops,
1920 SDNodeFlags Flags = SDNodeFlags());
1921
1922
1923
1924 SDValue foldConstantFPMath(unsigned Opcode, const SDLoc &DL, EVT VT,
1925 ArrayRef<SDValue> Ops);
1926
1927
1928 SDValue FoldSetCC(EVT VT, SDValue N1, SDValue N2, ISD::CondCode Cond,
1929 const SDLoc &dl);
1930
1931
1932
1933 bool SignBitIsZero(SDValue Op, unsigned Depth = 0) const;
1934
1935
1936
1937
1938 bool MaskedValueIsZero(SDValue Op, const APInt &Mask,
1939 unsigned Depth = 0) const;
1940
1941
1942
1943
1944 bool MaskedValueIsZero(SDValue Op, const APInt &Mask,
1945 const APInt &DemandedElts, unsigned Depth = 0) const;
1946
1947
1948
1949 bool MaskedVectorIsZero(SDValue Op, const APInt &DemandedElts,
1950 unsigned Depth = 0) const;
1951
1952
1953
1954 bool MaskedValueIsAllOnes(SDValue Op, const APInt &Mask,
1955 unsigned Depth = 0) const;
1956
1957
1958 APInt computeVectorKnownZeroElements(SDValue Op, const APInt &DemandedElts,
1959 unsigned Depth = 0) const;
1960
1961
1962
1963
1964
1965
1966 KnownBits computeKnownBits(SDValue Op, unsigned Depth = 0) const;
1967
1968
1969
1970
1971
1972
1973 KnownBits computeKnownBits(SDValue Op, const APInt &DemandedElts,
1974 unsigned Depth = 0) const;
1975
1976
1977
1978
1979
1980 enum OverflowKind {
1981 OFK_Never,
1982 OFK_Sometime,
1983 OFK_Always,
1984 };
1985
1986
1987 OverflowKind computeOverflowForSignedAdd(SDValue N0, SDValue N1) const;
1988
1989
1990 OverflowKind computeOverflowForUnsignedAdd(SDValue N0, SDValue N1) const;
1991
1992
1993 OverflowKind computeOverflowForAdd(bool IsSigned, SDValue N0,
1994 SDValue N1) const {
1995 return IsSigned ? computeOverflowForSignedAdd(N0, N1)
1996 : computeOverflowForUnsignedAdd(N0, N1);
1997 }
1998
1999
2000 bool willNotOverflowAdd(bool IsSigned, SDValue N0, SDValue N1) const {
2001 return computeOverflowForAdd(IsSigned, N0, N1) == OFK_Never;
2002 }
2003
2004
2005 OverflowKind computeOverflowForSignedSub(SDValue N0, SDValue N1) const;
2006
2007
2008 OverflowKind computeOverflowForUnsignedSub(SDValue N0, SDValue N1) const;
2009
2010
2011 OverflowKind computeOverflowForSub(bool IsSigned, SDValue N0,
2012 SDValue N1) const {
2013 return IsSigned ? computeOverflowForSignedSub(N0, N1)
2014 : computeOverflowForUnsignedSub(N0, N1);
2015 }
2016
2017
2018 bool willNotOverflowSub(bool IsSigned, SDValue N0, SDValue N1) const {
2019 return computeOverflowForSub(IsSigned, N0, N1) == OFK_Never;
2020 }
2021
2022
2023 OverflowKind computeOverflowForSignedMul(SDValue N0, SDValue N1) const;
2024
2025
2026 OverflowKind computeOverflowForUnsignedMul(SDValue N0, SDValue N1) const;
2027
2028
2029 OverflowKind computeOverflowForMul(bool IsSigned, SDValue N0,
2030 SDValue N1) const {
2031 return IsSigned ? computeOverflowForSignedMul(N0, N1)
2032 : computeOverflowForUnsignedMul(N0, N1);
2033 }
2034
2035
2036 bool willNotOverflowMul(bool IsSigned, SDValue N0, SDValue N1) const {
2037 return computeOverflowForMul(IsSigned, N0, N1) == OFK_Never;
2038 }
2039
2040
2041
2042
2043 bool isKnownToBeAPowerOfTwo(SDValue Val, unsigned Depth = 0) const;
2044
2045
2046
2047 bool isKnownToBeAPowerOfTwoFP(SDValue Val, unsigned Depth = 0) const;
2048
2049
2050
2051
2052
2053
2054
2055
2056 unsigned ComputeNumSignBits(SDValue Op, unsigned Depth = 0) const;
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066 unsigned ComputeNumSignBits(SDValue Op, const APInt &DemandedElts,
2067 unsigned Depth = 0) const;
2068
2069
2070
2071
2072
2073 unsigned ComputeMaxSignificantBits(SDValue Op, unsigned Depth = 0) const;
2074
2075
2076
2077
2078
2079 unsigned ComputeMaxSignificantBits(SDValue Op, const APInt &DemandedElts,
2080 unsigned Depth = 0) const;
2081
2082
2083
2084 bool isGuaranteedNotToBeUndefOrPoison(SDValue Op, bool PoisonOnly = false,
2085 unsigned Depth = 0) const;
2086
2087
2088
2089
2090 bool isGuaranteedNotToBeUndefOrPoison(SDValue Op, const APInt &DemandedElts,
2091 bool PoisonOnly = false,
2092 unsigned Depth = 0) const;
2093
2094
2095 bool isGuaranteedNotToBePoison(SDValue Op, unsigned Depth = 0) const {
2096 return isGuaranteedNotToBeUndefOrPoison(Op, true, Depth);
2097 }
2098
2099
2100
2101 bool isGuaranteedNotToBePoison(SDValue Op, const APInt &DemandedElts,
2102 unsigned Depth = 0) const {
2103 return isGuaranteedNotToBeUndefOrPoison(Op, DemandedElts,
2104 true, Depth);
2105 }
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116 bool canCreateUndefOrPoison(SDValue Op, const APInt &DemandedElts,
2117 bool PoisonOnly = false,
2118 bool ConsiderFlags = true,
2119 unsigned Depth = 0) const;
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129 bool canCreateUndefOrPoison(SDValue Op, bool PoisonOnly = false,
2130 bool ConsiderFlags = true,
2131 unsigned Depth = 0) const;
2132
2133
2134
2135
2136
2137
2138 bool isADDLike(SDValue Op, bool NoWrap = false) const;
2139
2140
2141
2142
2143
2144
2145 bool isBaseWithConstantOffset(SDValue Op) const;
2146
2147
2148
2149
2150 bool isKnownNeverNaN(SDValue Op, bool SNaN = false, unsigned Depth = 0) const;
2151
2152
2153 bool isKnownNeverSNaN(SDValue Op, unsigned Depth = 0) const {
2154 return isKnownNeverNaN(Op, true, Depth);
2155 }
2156
2157
2158
2159 bool isKnownNeverZeroFloat(SDValue Op) const;
2160
2161
2162 bool isKnownNeverZero(SDValue Op, unsigned Depth = 0) const;
2163
2164
2165
2166 bool cannotBeOrderedNegativeFP(SDValue Op) const;
2167
2168
2169
2170
2171 bool isEqualTo(SDValue A, SDValue B) const;
2172
2173
2174
2175 bool haveNoCommonBitsSet(SDValue A, SDValue B) const;
2176
2177
2178
2179
2180
2181
2182
2183
2184 bool isSplatValue(SDValue V, const APInt &DemandedElts, APInt &UndefElts,
2185 unsigned Depth = 0) const;
2186
2187
2188 bool isSplatValue(SDValue V, bool AllowUndefs = false) const;
2189
2190
2191 SDValue getSplatSourceVector(SDValue V, int &SplatIndex);
2192
2193
2194
2195
2196
2197 SDValue getSplatValue(SDValue V, bool LegalTypes = false);
2198
2199
2200
2201 std::optional<ConstantRange>
2202 getValidShiftAmountRange(SDValue V, const APInt &DemandedElts,
2203 unsigned Depth) const;
2204
2205
2206
2207 std::optional<uint64_t> getValidShiftAmount(SDValue V,
2208 const APInt &DemandedElts,
2209 unsigned Depth = 0) const;
2210
2211
2212
2213 std::optional<uint64_t> getValidShiftAmount(SDValue V,
2214 unsigned Depth = 0) const;
2215
2216
2217
2218 std::optional<uint64_t> getValidMinimumShiftAmount(SDValue V,
2219 const APInt &DemandedElts,
2220 unsigned Depth = 0) const;
2221
2222
2223
2224 std::optional<uint64_t> getValidMinimumShiftAmount(SDValue V,
2225 unsigned Depth = 0) const;
2226
2227
2228
2229 std::optional<uint64_t> getValidMaximumShiftAmount(SDValue V,
2230 const APInt &DemandedElts,
2231 unsigned Depth = 0) const;
2232
2233
2234
2235 std::optional<uint64_t> getValidMaximumShiftAmount(SDValue V,
2236 unsigned Depth = 0) const;
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246 SDValue matchBinOpReduction(SDNode *Extract, ISD::NodeType &BinOp,
2247 ArrayRef<ISD::NodeType> CandidateBinOps,
2248 bool AllowPartials = false);
2249
2250
2251
2252
2253
2254
2255
2256 SDValue UnrollVectorOp(SDNode *N, unsigned ResNE = 0);
2257
2258
2259
2260 std::pair<SDValue, SDValue> UnrollVectorOverflowOp(SDNode *N,
2261 unsigned ResNE = 0);
2262
2263
2264
2265
2266
2267 bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base,
2268 unsigned Bytes, int Dist) const;
2269
2270
2271
2272 MaybeAlign InferPtrAlign(SDValue Ptr) const;
2273
2274
2275
2276 std::pair<SDValue, SDValue> SplitScalar(const SDValue &N, const SDLoc &DL,
2277 const EVT &LoVT, const EVT &HiVT);
2278
2279
2280
2281 std::pair<EVT, EVT> GetSplitDestVTs(const EVT &VT) const;
2282
2283
2284
2285
2286 std::pair<EVT, EVT> GetDependentSplitDestVTs(const EVT &VT, const EVT &EnvVT,
2287 bool *HiIsEmpty) const;
2288
2289
2290
2291 std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL,
2292 const EVT &LoVT, const EVT &HiVT);
2293
2294
2295 std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL) {
2296 EVT LoVT, HiVT;
2297 std::tie(LoVT, HiVT) = GetSplitDestVTs(N.getValueType());
2298 return SplitVector(N, DL, LoVT, HiVT);
2299 }
2300
2301
2302 std::pair<SDValue, SDValue> SplitEVL(SDValue N, EVT VecVT, const SDLoc &DL);
2303
2304
2305
2306 std::pair<SDValue, SDValue> SplitVectorOperand(const SDNode *N, unsigned OpNo)
2307 {
2308 return SplitVector(N->getOperand(OpNo), SDLoc(N));
2309 }
2310
2311
2312 SDValue WidenVector(const SDValue &N, const SDLoc &DL);
2313
2314
2315
2316
2317
2318 void ExtractVectorElements(SDValue Op, SmallVectorImpl<SDValue> &Args,
2319 unsigned Start = 0, unsigned Count = 0,
2320 EVT EltVT = EVT());
2321
2322
2323 Align getEVTAlign(EVT MemoryVT) const;
2324
2325
2326 bool isConstantIntBuildVectorOrConstantInt(SDValue N,
2327 bool AllowOpaques = true) const;
2328
2329
2330 bool isConstantFPBuildVectorOrConstantFP(SDValue N) const;
2331
2332
2333
2334 inline bool isConstantValueOfAnyType(SDValue N) const {
2335 return isConstantIntBuildVectorOrConstantInt(N) ||
2336 isConstantFPBuildVectorOrConstantFP(N);
2337 }
2338
2339
2340
2341 std::optional<bool> isBoolConstant(SDValue N,
2342 bool AllowTruncation = false) const;
2343
2344
2345 void addCallSiteInfo(const SDNode *Node, CallSiteInfo &&CallInfo) {
2346 SDEI[Node].CSInfo = std::move(CallInfo);
2347 }
2348
2349 CallSiteInfo getCallSiteInfo(const SDNode *Node) {
2350 auto I = SDEI.find(Node);
2351 return I != SDEI.end() ? std::move(I->second).CSInfo : CallSiteInfo();
2352 }
2353
2354 void addHeapAllocSite(const SDNode *Node, MDNode *MD) {
2355 SDEI[Node].HeapAllocSite = MD;
2356 }
2357
2358 MDNode *getHeapAllocSite(const SDNode *Node) const {
2359 auto I = SDEI.find(Node);
2360 return I != SDEI.end() ? I->second.HeapAllocSite : nullptr;
2361 }
2362
2363 void addPCSections(const SDNode *Node, MDNode *MD) {
2364 SDEI[Node].PCSections = MD;
2365 }
2366
2367 void addMMRAMetadata(const SDNode *Node, MDNode *MMRA) {
2368 SDEI[Node].MMRA = MMRA;
2369 }
2370
2371 MDNode *getPCSections(const SDNode *Node) const {
2372 auto It = SDEI.find(Node);
2373 return It != SDEI.end() ? It->second.PCSections : nullptr;
2374 }
2375
2376
2377 MDNode *getMMRAMetadata(const SDNode *Node) const {
2378 auto It = SDEI.find(Node);
2379 return It != SDEI.end() ? It->second.MMRA : nullptr;
2380 }
2381
2382 void addCalledGlobal(const SDNode *Node, const GlobalValue *GV,
2383 unsigned OpFlags) {
2384 SDEI[Node].CalledGlobal = {GV, OpFlags};
2385 }
2386
2387 std::optional<CalledGlobalInfo> getCalledGlobal(const SDNode *Node) {
2388 auto I = SDEI.find(Node);
2389 return I != SDEI.end()
2390 ? std::make_optional(std::move(I->second).CalledGlobal)
2391 : std::nullopt;
2392 }
2393
2394 void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
2395 if (NoMerge)
2396 SDEI[Node].NoMerge = NoMerge;
2397 }
2398
2399 bool getNoMergeSiteInfo(const SDNode *Node) const {
2400 auto I = SDEI.find(Node);
2401 return I != SDEI.end() ? I->second.NoMerge : false;
2402 }
2403
2404
2405 void copyExtraInfo(SDNode *From, SDNode *To);
2406
2407
2408
2409 DenormalMode getDenormalMode(EVT VT) const {
2410 return MF->getDenormalMode(VT.getFltSemantics());
2411 }
2412
2413 bool shouldOptForSize() const;
2414
2415
2416 SDValue getNeutralElement(unsigned Opcode, const SDLoc &DL, EVT VT,
2417 SDNodeFlags Flags);
2418
2419
2420
2421
2422 bool isSafeToSpeculativelyExecute(unsigned Opcode) const {
2423 switch (Opcode) {
2424 case ISD::SDIV:
2425 case ISD::SREM:
2426 case ISD::SDIVREM:
2427 case ISD::UDIV:
2428 case ISD::UREM:
2429 case ISD::UDIVREM:
2430 return false;
2431 default:
2432 return true;
2433 }
2434 }
2435
2436
2437
2438
2439
2440 bool isSafeToSpeculativelyExecuteNode(const SDNode *N) const {
2441 switch (N->getOpcode()) {
2442 case ISD::UDIV:
2443 return isKnownNeverZero(N->getOperand(1));
2444 default:
2445 return isSafeToSpeculativelyExecute(N->getOpcode());
2446 }
2447 }
2448
2449 SDValue makeStateFunctionCall(unsigned LibFunc, SDValue Ptr, SDValue InChain,
2450 const SDLoc &DLoc);
2451
2452 private:
2453 void InsertNode(SDNode *N);
2454 bool RemoveNodeFromCSEMaps(SDNode *N);
2455 void AddModifiedNodeToCSEMaps(SDNode *N);
2456 SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos);
2457 SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2,
2458 void *&InsertPos);
2459 SDNode *FindModifiedNodeSlot(SDNode *N, ArrayRef<SDValue> Ops,
2460 void *&InsertPos);
2461 SDNode *UpdateSDLocOnMergeSDNode(SDNode *N, const SDLoc &loc);
2462
2463 void DeleteNodeNotInCSEMaps(SDNode *N);
2464 void DeallocateNode(SDNode *N);
2465
2466 void allnodes_clear();
2467
2468
2469
2470
2471
2472 SDNode *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
2473
2474
2475
2476
2477 SDNode *FindNodeOrInsertPos(const FoldingSetNodeID &ID, const SDLoc &DL,
2478 void *&InsertPos);
2479
2480
2481 std::vector<CondCodeSDNode*> CondCodeNodes;
2482
2483 std::vector<SDNode*> ValueTypeNodes;
2484 std::map<EVT, SDNode*, EVT::compareRawBits> ExtendedValueTypeNodes;
2485 StringMap<SDNode*> ExternalSymbols;
2486
2487 std::map<std::pair<std::string, unsigned>, SDNode *> TargetExternalSymbols;
2488 DenseMap<MCSymbol *, SDNode *> MCSymbols;
2489
2490 FlagInserter *Inserter = nullptr;
2491 };
2492
2493 template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
2494 using nodes_iterator = pointer_iterator<SelectionDAG::allnodes_iterator>;
2495
2496 static nodes_iterator nodes_begin(SelectionDAG *G) {
2497 return nodes_iterator(G->allnodes_begin());
2498 }
2499
2500 static nodes_iterator nodes_end(SelectionDAG *G) {
2501 return nodes_iterator(G->allnodes_end());
2502 }
2503 };
2504
2505 }
2506
2507 #endif