17330f729Sjoerg //===---- ScheduleDAGSDNodes.h - SDNode Scheduling --------------*- C++ -*-===// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg // 97330f729Sjoerg // This file implements the ScheduleDAGSDNodes class, which implements 107330f729Sjoerg // scheduling for an SDNode-based dependency graph. 117330f729Sjoerg // 127330f729Sjoerg //===----------------------------------------------------------------------===// 137330f729Sjoerg 147330f729Sjoerg #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H 157330f729Sjoerg #define LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H 167330f729Sjoerg 177330f729Sjoerg #include "llvm/CodeGen/ISDOpcodes.h" 187330f729Sjoerg #include "llvm/CodeGen/MachineBasicBlock.h" 197330f729Sjoerg #include "llvm/CodeGen/ScheduleDAG.h" 207330f729Sjoerg #include "llvm/CodeGen/SelectionDAGNodes.h" 217330f729Sjoerg #include "llvm/Support/Casting.h" 227330f729Sjoerg #include "llvm/Support/MachineValueType.h" 237330f729Sjoerg #include <cassert> 247330f729Sjoerg #include <string> 257330f729Sjoerg #include <vector> 267330f729Sjoerg 277330f729Sjoerg namespace llvm { 287330f729Sjoerg 297330f729Sjoerg class AAResults; 307330f729Sjoerg class InstrItineraryData; 317330f729Sjoerg 327330f729Sjoerg /// ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs. 337330f729Sjoerg /// 347330f729Sjoerg /// Edges between SUnits are initially based on edges in the SelectionDAG, 357330f729Sjoerg /// and additional edges can be added by the schedulers as heuristics. 367330f729Sjoerg /// SDNodes such as Constants, Registers, and a few others that are not 377330f729Sjoerg /// interesting to schedulers are not allocated SUnits. 387330f729Sjoerg /// 397330f729Sjoerg /// SDNodes with MVT::Glue operands are grouped along with the flagged 407330f729Sjoerg /// nodes into a single SUnit so that they are scheduled together. 417330f729Sjoerg /// 427330f729Sjoerg /// SDNode-based scheduling graphs do not use SDep::Anti or SDep::Output 437330f729Sjoerg /// edges. Physical register dependence information is not carried in 447330f729Sjoerg /// the DAG and must be handled explicitly by schedulers. 457330f729Sjoerg /// 467330f729Sjoerg class ScheduleDAGSDNodes : public ScheduleDAG { 477330f729Sjoerg public: 487330f729Sjoerg MachineBasicBlock *BB; 497330f729Sjoerg SelectionDAG *DAG; // DAG of the current basic block 507330f729Sjoerg const InstrItineraryData *InstrItins; 517330f729Sjoerg 527330f729Sjoerg /// The schedule. Null SUnit*'s represent noop instructions. 537330f729Sjoerg std::vector<SUnit*> Sequence; 547330f729Sjoerg 557330f729Sjoerg explicit ScheduleDAGSDNodes(MachineFunction &mf); 567330f729Sjoerg 577330f729Sjoerg ~ScheduleDAGSDNodes() override = default; 587330f729Sjoerg 597330f729Sjoerg /// Run - perform scheduling. 607330f729Sjoerg /// 617330f729Sjoerg void Run(SelectionDAG *dag, MachineBasicBlock *bb); 627330f729Sjoerg 637330f729Sjoerg /// isPassiveNode - Return true if the node is a non-scheduled leaf. 647330f729Sjoerg /// isPassiveNode(SDNode * Node)657330f729Sjoerg static bool isPassiveNode(SDNode *Node) { 667330f729Sjoerg if (isa<ConstantSDNode>(Node)) return true; 677330f729Sjoerg if (isa<ConstantFPSDNode>(Node)) return true; 687330f729Sjoerg if (isa<RegisterSDNode>(Node)) return true; 697330f729Sjoerg if (isa<RegisterMaskSDNode>(Node)) return true; 707330f729Sjoerg if (isa<GlobalAddressSDNode>(Node)) return true; 717330f729Sjoerg if (isa<BasicBlockSDNode>(Node)) return true; 727330f729Sjoerg if (isa<FrameIndexSDNode>(Node)) return true; 737330f729Sjoerg if (isa<ConstantPoolSDNode>(Node)) return true; 747330f729Sjoerg if (isa<TargetIndexSDNode>(Node)) return true; 757330f729Sjoerg if (isa<JumpTableSDNode>(Node)) return true; 767330f729Sjoerg if (isa<ExternalSymbolSDNode>(Node)) return true; 777330f729Sjoerg if (isa<MCSymbolSDNode>(Node)) return true; 787330f729Sjoerg if (isa<BlockAddressSDNode>(Node)) return true; 797330f729Sjoerg if (Node->getOpcode() == ISD::EntryToken || 807330f729Sjoerg isa<MDNodeSDNode>(Node)) return true; 817330f729Sjoerg return false; 827330f729Sjoerg } 837330f729Sjoerg 847330f729Sjoerg /// NewSUnit - Creates a new SUnit and return a ptr to it. 857330f729Sjoerg /// 867330f729Sjoerg SUnit *newSUnit(SDNode *N); 877330f729Sjoerg 887330f729Sjoerg /// Clone - Creates a clone of the specified SUnit. It does not copy the 897330f729Sjoerg /// predecessors / successors info nor the temporary scheduling states. 907330f729Sjoerg /// 917330f729Sjoerg SUnit *Clone(SUnit *Old); 927330f729Sjoerg 937330f729Sjoerg /// BuildSchedGraph - Build the SUnit graph from the selection dag that we 947330f729Sjoerg /// are input. This SUnit graph is similar to the SelectionDAG, but 957330f729Sjoerg /// excludes nodes that aren't interesting to scheduling, and represents 967330f729Sjoerg /// flagged together nodes with a single SUnit. 977330f729Sjoerg void BuildSchedGraph(AAResults *AA); 987330f729Sjoerg 997330f729Sjoerg /// InitNumRegDefsLeft - Determine the # of regs defined by this node. 1007330f729Sjoerg /// 1017330f729Sjoerg void InitNumRegDefsLeft(SUnit *SU); 1027330f729Sjoerg 1037330f729Sjoerg /// computeLatency - Compute node latency. 1047330f729Sjoerg /// 1057330f729Sjoerg virtual void computeLatency(SUnit *SU); 1067330f729Sjoerg 1077330f729Sjoerg virtual void computeOperandLatency(SDNode *Def, SDNode *Use, 1087330f729Sjoerg unsigned OpIdx, SDep& dep) const; 1097330f729Sjoerg 1107330f729Sjoerg /// Schedule - Order nodes according to selected style, filling 1117330f729Sjoerg /// in the Sequence member. 1127330f729Sjoerg /// 1137330f729Sjoerg virtual void Schedule() = 0; 1147330f729Sjoerg 1157330f729Sjoerg /// VerifyScheduledSequence - Verify that all SUnits are scheduled and 1167330f729Sjoerg /// consistent with the Sequence of scheduled instructions. 1177330f729Sjoerg void VerifyScheduledSequence(bool isBottomUp); 1187330f729Sjoerg 1197330f729Sjoerg /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock 1207330f729Sjoerg /// according to the order specified in Sequence. 1217330f729Sjoerg /// 1227330f729Sjoerg virtual MachineBasicBlock* 1237330f729Sjoerg EmitSchedule(MachineBasicBlock::iterator &InsertPos); 1247330f729Sjoerg 1257330f729Sjoerg void dumpNode(const SUnit &SU) const override; 1267330f729Sjoerg void dump() const override; 1277330f729Sjoerg void dumpSchedule() const; 1287330f729Sjoerg 1297330f729Sjoerg std::string getGraphNodeLabel(const SUnit *SU) const override; 1307330f729Sjoerg 1317330f729Sjoerg std::string getDAGName() const override; 1327330f729Sjoerg 1337330f729Sjoerg virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const; 1347330f729Sjoerg 1357330f729Sjoerg /// RegDefIter - In place iteration over the values defined by an 1367330f729Sjoerg /// SUnit. This does not need copies of the iterator or any other STLisms. 1377330f729Sjoerg /// The iterator creates itself, rather than being provided by the SchedDAG. 1387330f729Sjoerg class RegDefIter { 1397330f729Sjoerg const ScheduleDAGSDNodes *SchedDAG; 1407330f729Sjoerg const SDNode *Node; 1417330f729Sjoerg unsigned DefIdx; 1427330f729Sjoerg unsigned NodeNumDefs; 1437330f729Sjoerg MVT ValueType; 1447330f729Sjoerg 1457330f729Sjoerg public: 1467330f729Sjoerg RegDefIter(const SUnit *SU, const ScheduleDAGSDNodes *SD); 1477330f729Sjoerg IsValid()1487330f729Sjoerg bool IsValid() const { return Node != nullptr; } 1497330f729Sjoerg GetValue()1507330f729Sjoerg MVT GetValue() const { 1517330f729Sjoerg assert(IsValid() && "bad iterator"); 1527330f729Sjoerg return ValueType; 1537330f729Sjoerg } 1547330f729Sjoerg GetNode()1557330f729Sjoerg const SDNode *GetNode() const { 1567330f729Sjoerg return Node; 1577330f729Sjoerg } 1587330f729Sjoerg GetIdx()1597330f729Sjoerg unsigned GetIdx() const { 1607330f729Sjoerg return DefIdx-1; 1617330f729Sjoerg } 1627330f729Sjoerg 1637330f729Sjoerg void Advance(); 1647330f729Sjoerg 1657330f729Sjoerg private: 1667330f729Sjoerg void InitNodeNumDefs(); 1677330f729Sjoerg }; 1687330f729Sjoerg 1697330f729Sjoerg protected: 1707330f729Sjoerg /// ForceUnitLatencies - Return true if all scheduling edges should be given 1717330f729Sjoerg /// a latency value of one. The default is to return false; schedulers may 1727330f729Sjoerg /// override this as needed. forceUnitLatencies()1737330f729Sjoerg virtual bool forceUnitLatencies() const { return false; } 1747330f729Sjoerg 1757330f729Sjoerg private: 1767330f729Sjoerg /// ClusterNeighboringLoads - Cluster loads from "near" addresses into 1777330f729Sjoerg /// combined SUnits. 1787330f729Sjoerg void ClusterNeighboringLoads(SDNode *Node); 1797330f729Sjoerg /// ClusterNodes - Cluster certain nodes which should be scheduled together. 1807330f729Sjoerg /// 1817330f729Sjoerg void ClusterNodes(); 1827330f729Sjoerg 1837330f729Sjoerg /// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph. 1847330f729Sjoerg void BuildSchedUnits(); 1857330f729Sjoerg void AddSchedEdges(); 1867330f729Sjoerg 187*82d56013Sjoerg void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, Register> &VRBaseMap, 1887330f729Sjoerg MachineBasicBlock::iterator InsertPos); 1897330f729Sjoerg }; 1907330f729Sjoerg 1917330f729Sjoerg } // end namespace llvm 1927330f729Sjoerg 1937330f729Sjoerg #endif // LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H 194