1*9880d681SAndroid Build Coastguard Worker //===---- ScheduleDAGSDNodes.h - SDNode Scheduling --------------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file implements the ScheduleDAGSDNodes class, which implements 11*9880d681SAndroid Build Coastguard Worker // scheduling for an SDNode-based dependency graph. 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H 16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_SELECTIONDAG_SCHEDULEDAGSDNODES_H 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineBasicBlock.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleDAG.h" 20*9880d681SAndroid Build Coastguard Worker 21*9880d681SAndroid Build Coastguard Worker namespace llvm { 22*9880d681SAndroid Build Coastguard Worker /// ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs. 23*9880d681SAndroid Build Coastguard Worker /// 24*9880d681SAndroid Build Coastguard Worker /// Edges between SUnits are initially based on edges in the SelectionDAG, 25*9880d681SAndroid Build Coastguard Worker /// and additional edges can be added by the schedulers as heuristics. 26*9880d681SAndroid Build Coastguard Worker /// SDNodes such as Constants, Registers, and a few others that are not 27*9880d681SAndroid Build Coastguard Worker /// interesting to schedulers are not allocated SUnits. 28*9880d681SAndroid Build Coastguard Worker /// 29*9880d681SAndroid Build Coastguard Worker /// SDNodes with MVT::Glue operands are grouped along with the flagged 30*9880d681SAndroid Build Coastguard Worker /// nodes into a single SUnit so that they are scheduled together. 31*9880d681SAndroid Build Coastguard Worker /// 32*9880d681SAndroid Build Coastguard Worker /// SDNode-based scheduling graphs do not use SDep::Anti or SDep::Output 33*9880d681SAndroid Build Coastguard Worker /// edges. Physical register dependence information is not carried in 34*9880d681SAndroid Build Coastguard Worker /// the DAG and must be handled explicitly by schedulers. 35*9880d681SAndroid Build Coastguard Worker /// 36*9880d681SAndroid Build Coastguard Worker class ScheduleDAGSDNodes : public ScheduleDAG { 37*9880d681SAndroid Build Coastguard Worker public: 38*9880d681SAndroid Build Coastguard Worker MachineBasicBlock *BB; 39*9880d681SAndroid Build Coastguard Worker SelectionDAG *DAG; // DAG of the current basic block 40*9880d681SAndroid Build Coastguard Worker const InstrItineraryData *InstrItins; 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker /// The schedule. Null SUnit*'s represent noop instructions. 43*9880d681SAndroid Build Coastguard Worker std::vector<SUnit*> Sequence; 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker explicit ScheduleDAGSDNodes(MachineFunction &mf); 46*9880d681SAndroid Build Coastguard Worker ~ScheduleDAGSDNodes()47*9880d681SAndroid Build Coastguard Worker ~ScheduleDAGSDNodes() override {} 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Worker /// Run - perform scheduling. 50*9880d681SAndroid Build Coastguard Worker /// 51*9880d681SAndroid Build Coastguard Worker void Run(SelectionDAG *dag, MachineBasicBlock *bb); 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard Worker /// isPassiveNode - Return true if the node is a non-scheduled leaf. 54*9880d681SAndroid Build Coastguard Worker /// isPassiveNode(SDNode * Node)55*9880d681SAndroid Build Coastguard Worker static bool isPassiveNode(SDNode *Node) { 56*9880d681SAndroid Build Coastguard Worker if (isa<ConstantSDNode>(Node)) return true; 57*9880d681SAndroid Build Coastguard Worker if (isa<ConstantFPSDNode>(Node)) return true; 58*9880d681SAndroid Build Coastguard Worker if (isa<RegisterSDNode>(Node)) return true; 59*9880d681SAndroid Build Coastguard Worker if (isa<RegisterMaskSDNode>(Node)) return true; 60*9880d681SAndroid Build Coastguard Worker if (isa<GlobalAddressSDNode>(Node)) return true; 61*9880d681SAndroid Build Coastguard Worker if (isa<BasicBlockSDNode>(Node)) return true; 62*9880d681SAndroid Build Coastguard Worker if (isa<FrameIndexSDNode>(Node)) return true; 63*9880d681SAndroid Build Coastguard Worker if (isa<ConstantPoolSDNode>(Node)) return true; 64*9880d681SAndroid Build Coastguard Worker if (isa<TargetIndexSDNode>(Node)) return true; 65*9880d681SAndroid Build Coastguard Worker if (isa<JumpTableSDNode>(Node)) return true; 66*9880d681SAndroid Build Coastguard Worker if (isa<ExternalSymbolSDNode>(Node)) return true; 67*9880d681SAndroid Build Coastguard Worker if (isa<MCSymbolSDNode>(Node)) return true; 68*9880d681SAndroid Build Coastguard Worker if (isa<BlockAddressSDNode>(Node)) return true; 69*9880d681SAndroid Build Coastguard Worker if (Node->getOpcode() == ISD::EntryToken || 70*9880d681SAndroid Build Coastguard Worker isa<MDNodeSDNode>(Node)) return true; 71*9880d681SAndroid Build Coastguard Worker return false; 72*9880d681SAndroid Build Coastguard Worker } 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker /// NewSUnit - Creates a new SUnit and return a ptr to it. 75*9880d681SAndroid Build Coastguard Worker /// 76*9880d681SAndroid Build Coastguard Worker SUnit *newSUnit(SDNode *N); 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker /// Clone - Creates a clone of the specified SUnit. It does not copy the 79*9880d681SAndroid Build Coastguard Worker /// predecessors / successors info nor the temporary scheduling states. 80*9880d681SAndroid Build Coastguard Worker /// 81*9880d681SAndroid Build Coastguard Worker SUnit *Clone(SUnit *N); 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Worker /// BuildSchedGraph - Build the SUnit graph from the selection dag that we 84*9880d681SAndroid Build Coastguard Worker /// are input. This SUnit graph is similar to the SelectionDAG, but 85*9880d681SAndroid Build Coastguard Worker /// excludes nodes that aren't interesting to scheduling, and represents 86*9880d681SAndroid Build Coastguard Worker /// flagged together nodes with a single SUnit. 87*9880d681SAndroid Build Coastguard Worker void BuildSchedGraph(AliasAnalysis *AA); 88*9880d681SAndroid Build Coastguard Worker 89*9880d681SAndroid Build Coastguard Worker /// InitNumRegDefsLeft - Determine the # of regs defined by this node. 90*9880d681SAndroid Build Coastguard Worker /// 91*9880d681SAndroid Build Coastguard Worker void InitNumRegDefsLeft(SUnit *SU); 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker /// computeLatency - Compute node latency. 94*9880d681SAndroid Build Coastguard Worker /// 95*9880d681SAndroid Build Coastguard Worker virtual void computeLatency(SUnit *SU); 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker virtual void computeOperandLatency(SDNode *Def, SDNode *Use, 98*9880d681SAndroid Build Coastguard Worker unsigned OpIdx, SDep& dep) const; 99*9880d681SAndroid Build Coastguard Worker 100*9880d681SAndroid Build Coastguard Worker /// Schedule - Order nodes according to selected style, filling 101*9880d681SAndroid Build Coastguard Worker /// in the Sequence member. 102*9880d681SAndroid Build Coastguard Worker /// 103*9880d681SAndroid Build Coastguard Worker virtual void Schedule() = 0; 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker /// VerifyScheduledSequence - Verify that all SUnits are scheduled and 106*9880d681SAndroid Build Coastguard Worker /// consistent with the Sequence of scheduled instructions. 107*9880d681SAndroid Build Coastguard Worker void VerifyScheduledSequence(bool isBottomUp); 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker /// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock 110*9880d681SAndroid Build Coastguard Worker /// according to the order specified in Sequence. 111*9880d681SAndroid Build Coastguard Worker /// 112*9880d681SAndroid Build Coastguard Worker virtual MachineBasicBlock* 113*9880d681SAndroid Build Coastguard Worker EmitSchedule(MachineBasicBlock::iterator &InsertPos); 114*9880d681SAndroid Build Coastguard Worker 115*9880d681SAndroid Build Coastguard Worker void dumpNode(const SUnit *SU) const override; 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Worker void dumpSchedule() const; 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker std::string getGraphNodeLabel(const SUnit *SU) const override; 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker std::string getDAGName() const override; 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker virtual void getCustomGraphFeatures(GraphWriter<ScheduleDAG*> &GW) const; 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Worker /// RegDefIter - In place iteration over the values defined by an 126*9880d681SAndroid Build Coastguard Worker /// SUnit. This does not need copies of the iterator or any other STLisms. 127*9880d681SAndroid Build Coastguard Worker /// The iterator creates itself, rather than being provided by the SchedDAG. 128*9880d681SAndroid Build Coastguard Worker class RegDefIter { 129*9880d681SAndroid Build Coastguard Worker const ScheduleDAGSDNodes *SchedDAG; 130*9880d681SAndroid Build Coastguard Worker const SDNode *Node; 131*9880d681SAndroid Build Coastguard Worker unsigned DefIdx; 132*9880d681SAndroid Build Coastguard Worker unsigned NodeNumDefs; 133*9880d681SAndroid Build Coastguard Worker MVT ValueType; 134*9880d681SAndroid Build Coastguard Worker public: 135*9880d681SAndroid Build Coastguard Worker RegDefIter(const SUnit *SU, const ScheduleDAGSDNodes *SD); 136*9880d681SAndroid Build Coastguard Worker IsValid()137*9880d681SAndroid Build Coastguard Worker bool IsValid() const { return Node != nullptr; } 138*9880d681SAndroid Build Coastguard Worker GetValue()139*9880d681SAndroid Build Coastguard Worker MVT GetValue() const { 140*9880d681SAndroid Build Coastguard Worker assert(IsValid() && "bad iterator"); 141*9880d681SAndroid Build Coastguard Worker return ValueType; 142*9880d681SAndroid Build Coastguard Worker } 143*9880d681SAndroid Build Coastguard Worker GetNode()144*9880d681SAndroid Build Coastguard Worker const SDNode *GetNode() const { 145*9880d681SAndroid Build Coastguard Worker return Node; 146*9880d681SAndroid Build Coastguard Worker } 147*9880d681SAndroid Build Coastguard Worker GetIdx()148*9880d681SAndroid Build Coastguard Worker unsigned GetIdx() const { 149*9880d681SAndroid Build Coastguard Worker return DefIdx-1; 150*9880d681SAndroid Build Coastguard Worker } 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker void Advance(); 153*9880d681SAndroid Build Coastguard Worker private: 154*9880d681SAndroid Build Coastguard Worker void InitNodeNumDefs(); 155*9880d681SAndroid Build Coastguard Worker }; 156*9880d681SAndroid Build Coastguard Worker 157*9880d681SAndroid Build Coastguard Worker protected: 158*9880d681SAndroid Build Coastguard Worker /// ForceUnitLatencies - Return true if all scheduling edges should be given 159*9880d681SAndroid Build Coastguard Worker /// a latency value of one. The default is to return false; schedulers may 160*9880d681SAndroid Build Coastguard Worker /// override this as needed. forceUnitLatencies()161*9880d681SAndroid Build Coastguard Worker virtual bool forceUnitLatencies() const { return false; } 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Worker private: 164*9880d681SAndroid Build Coastguard Worker /// ClusterNeighboringLoads - Cluster loads from "near" addresses into 165*9880d681SAndroid Build Coastguard Worker /// combined SUnits. 166*9880d681SAndroid Build Coastguard Worker void ClusterNeighboringLoads(SDNode *Node); 167*9880d681SAndroid Build Coastguard Worker /// ClusterNodes - Cluster certain nodes which should be scheduled together. 168*9880d681SAndroid Build Coastguard Worker /// 169*9880d681SAndroid Build Coastguard Worker void ClusterNodes(); 170*9880d681SAndroid Build Coastguard Worker 171*9880d681SAndroid Build Coastguard Worker /// BuildSchedUnits, AddSchedEdges - Helper functions for BuildSchedGraph. 172*9880d681SAndroid Build Coastguard Worker void BuildSchedUnits(); 173*9880d681SAndroid Build Coastguard Worker void AddSchedEdges(); 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap, 176*9880d681SAndroid Build Coastguard Worker MachineBasicBlock::iterator InsertPos); 177*9880d681SAndroid Build Coastguard Worker }; 178*9880d681SAndroid Build Coastguard Worker } 179*9880d681SAndroid Build Coastguard Worker 180*9880d681SAndroid Build Coastguard Worker #endif 181