1168404Spjd//===----- ResourcePriorityQueue.h - A DFA-oriented priority queue -------===// 2168404Spjd// 3168404Spjd// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4168404Spjd// See https://llvm.org/LICENSE.txt for license information. 5168404Spjd// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6168404Spjd// 7168404Spjd//===----------------------------------------------------------------------===// 8168404Spjd// 9168404Spjd// This file implements the ResourcePriorityQueue class, which is a 10168404Spjd// SchedulingPriorityQueue that schedules using DFA state to 11168404Spjd// reduce the length of the critical path through the basic block 12168404Spjd// on VLIW platforms. 13168404Spjd// 14168404Spjd//===----------------------------------------------------------------------===// 15168404Spjd 16168404Spjd#ifndef LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H 17168404Spjd#define LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H 18168404Spjd 19168404Spjd#include "llvm/CodeGen/ScheduleDAG.h" 20168404Spjd 21236884Smmnamespace llvm { 22168404Spjd class DFAPacketizer; 23219089Spjd class InstrItineraryData; 24290765Smav class ResourcePriorityQueue; 25168404Spjd class SelectionDAGISel; 26168404Spjd class TargetInstrInfo; 27168404Spjd class TargetRegisterInfo; 28168404Spjd 29168404Spjd /// Sorting functions for the Available queue. 30168404Spjd struct resource_sort { 31168404Spjd ResourcePriorityQueue *PQ; 32168404Spjd explicit resource_sort(ResourcePriorityQueue *pq) : PQ(pq) {} 33168404Spjd 34168404Spjd bool operator()(const SUnit* LHS, const SUnit* RHS) const; 35168404Spjd }; 36168404Spjd 37168404Spjd class ResourcePriorityQueue : public SchedulingPriorityQueue { 38168404Spjd /// SUnits - The SUnits for the current graph. 39168404Spjd std::vector<SUnit> *SUnits; 40168404Spjd 41168404Spjd /// NumNodesSolelyBlocking - This vector contains, for every node in the 42168404Spjd /// Queue, the number of nodes that the node is the sole unscheduled 43168404Spjd /// predecessor for. This is used as a tie-breaker heuristic for better 44168404Spjd /// mobility. 45168404Spjd std::vector<unsigned> NumNodesSolelyBlocking; 46168404Spjd 47168404Spjd /// Queue - The queue. 48168404Spjd std::vector<SUnit*> Queue; 49168404Spjd 50168404Spjd /// RegPressure - Tracking current reg pressure per register class. 51168404Spjd /// 52168404Spjd std::vector<unsigned> RegPressure; 53168404Spjd 54168404Spjd /// RegLimit - Tracking the number of allocatable registers per register 55168404Spjd /// class. 56168404Spjd std::vector<unsigned> RegLimit; 57168404Spjd 58168404Spjd resource_sort Picker; 59168404Spjd const TargetRegisterInfo *TRI; 60168404Spjd const TargetLowering *TLI; 61168404Spjd const TargetInstrInfo *TII; 62168404Spjd const InstrItineraryData* InstrItins; 63168404Spjd /// ResourcesModel - Represents VLIW state. 64185029Spjd /// Not limited to VLIW targets per say, but assumes 65168404Spjd /// definition of DFA by a target. 66168404Spjd std::unique_ptr<DFAPacketizer> ResourcesModel; 67168404Spjd 68168404Spjd /// Resource model - packet/bundle model. Purely 69168404Spjd /// internal at the time. 70168404Spjd std::vector<SUnit*> Packet; 71168404Spjd 72168404Spjd /// Heuristics for estimating register pressure. 73168404Spjd unsigned ParallelLiveRanges; 74168404Spjd int HorizontalVerticalBalance; 75168404Spjd 76168404Spjd public: 77168404Spjd ResourcePriorityQueue(SelectionDAGISel *IS); 78168404Spjd 79168404Spjd bool isBottomUp() const override { return false; } 80168404Spjd 81168404Spjd void initNodes(std::vector<SUnit> &sunits) override; 82168404Spjd 83168404Spjd void addNode(const SUnit *SU) override { 84168404Spjd NumNodesSolelyBlocking.resize(SUnits->size(), 0); 85168404Spjd } 86168404Spjd 87168404Spjd void updateNode(const SUnit *SU) override {} 88168404Spjd 89168404Spjd void releaseState() override { 90168404Spjd SUnits = nullptr; 91168404Spjd } 92168404Spjd 93168404Spjd unsigned getLatency(unsigned NodeNum) const { 94168404Spjd assert(NodeNum < (*SUnits).size()); 95168404Spjd return (*SUnits)[NodeNum].getHeight(); 96168404Spjd } 97168404Spjd 98168404Spjd unsigned getNumSolelyBlockNodes(unsigned NodeNum) const { 99168404Spjd assert(NodeNum < NumNodesSolelyBlocking.size()); 100168404Spjd return NumNodesSolelyBlocking[NodeNum]; 101168404Spjd } 102168404Spjd 103168404Spjd /// Single cost function reflecting benefit of scheduling SU 104168404Spjd /// in the current cycle. 105168404Spjd int SUSchedulingCost (SUnit *SU); 106168404Spjd 107168404Spjd /// InitNumRegDefsLeft - Determine the # of regs defined by this node. 108168404Spjd /// 109168404Spjd void initNumRegDefsLeft(SUnit *SU); 110168404Spjd int regPressureDelta(SUnit *SU, bool RawPressure = false); 111168404Spjd int rawRegPressureDelta (SUnit *SU, unsigned RCId); 112168404Spjd 113168404Spjd bool empty() const override { return Queue.empty(); } 114168404Spjd 115168404Spjd void push(SUnit *U) override; 116168404Spjd 117168404Spjd SUnit *pop() override; 118168404Spjd 119168404Spjd void remove(SUnit *SU) override; 120168404Spjd 121168404Spjd /// scheduledNode - Main resource tracking point. 122168404Spjd void scheduledNode(SUnit *SU) override; 123168404Spjd bool isResourceAvailable(SUnit *SU); 124168404Spjd void reserveResources(SUnit *SU); 125168404Spjd 126236884Smmprivate: 127236884Smm void adjustPriorityOfUnscheduledPreds(SUnit *SU); 128168404Spjd SUnit *getSingleUnscheduledPred(SUnit *SU); 129168404Spjd unsigned numberRCValPredInSU (SUnit *SU, unsigned RCId); 130168404Spjd unsigned numberRCValSuccInSU (SUnit *SU, unsigned RCId); 131168404Spjd }; 132168404Spjd} 133168404Spjd 134168404Spjd#endif 135168404Spjd