//===----- ResourcePriorityQueue.h - A DFA-oriented priority queue -------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the ResourcePriorityQueue class, which is a // SchedulingPriorityQueue that schedules using DFA state to // reduce the length of the critical path through the basic block // on VLIW platforms. // //===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H #define LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H #include "llvm/CodeGen/ScheduleDAG.h" namespace llvm { class DFAPacketizer; class InstrItineraryData; class ResourcePriorityQueue; class SelectionDAGISel; class TargetInstrInfo; class TargetRegisterInfo; /// Sorting functions for the Available queue. struct resource_sort { ResourcePriorityQueue *PQ; explicit resource_sort(ResourcePriorityQueue *pq) : PQ(pq) {} bool operator()(const SUnit* LHS, const SUnit* RHS) const; }; class ResourcePriorityQueue : public SchedulingPriorityQueue { /// SUnits - The SUnits for the current graph. std::vector *SUnits; /// NumNodesSolelyBlocking - This vector contains, for every node in the /// Queue, the number of nodes that the node is the sole unscheduled /// predecessor for. This is used as a tie-breaker heuristic for better /// mobility. std::vector NumNodesSolelyBlocking; /// Queue - The queue. std::vector Queue; /// RegPressure - Tracking current reg pressure per register class. /// std::vector RegPressure; /// RegLimit - Tracking the number of allocatable registers per register /// class. std::vector RegLimit; resource_sort Picker; const TargetRegisterInfo *TRI; const TargetLowering *TLI; const TargetInstrInfo *TII; const InstrItineraryData* InstrItins; /// ResourcesModel - Represents VLIW state. /// Not limited to VLIW targets per say, but assumes /// definition of DFA by a target. std::unique_ptr ResourcesModel; /// Resource model - packet/bundle model. Purely /// internal at the time. std::vector Packet; /// Heuristics for estimating register pressure. unsigned ParallelLiveRanges; int HorizontalVerticalBalance; public: ResourcePriorityQueue(SelectionDAGISel *IS); bool isBottomUp() const override { return false; } void initNodes(std::vector &sunits) override; void addNode(const SUnit *SU) override { NumNodesSolelyBlocking.resize(SUnits->size(), 0); } void updateNode(const SUnit *SU) override {} void releaseState() override { SUnits = nullptr; } unsigned getLatency(unsigned NodeNum) const { assert(NodeNum < (*SUnits).size()); return (*SUnits)[NodeNum].getHeight(); } unsigned getNumSolelyBlockNodes(unsigned NodeNum) const { assert(NodeNum < NumNodesSolelyBlocking.size()); return NumNodesSolelyBlocking[NodeNum]; } /// Single cost function reflecting benefit of scheduling SU /// in the current cycle. int SUSchedulingCost (SUnit *SU); /// InitNumRegDefsLeft - Determine the # of regs defined by this node. /// void initNumRegDefsLeft(SUnit *SU); int regPressureDelta(SUnit *SU, bool RawPressure = false); int rawRegPressureDelta (SUnit *SU, unsigned RCId); bool empty() const override { return Queue.empty(); } void push(SUnit *U) override; SUnit *pop() override; void remove(SUnit *SU) override; /// scheduledNode - Main resource tracking point. void scheduledNode(SUnit *SU) override; bool isResourceAvailable(SUnit *SU); void reserveResources(SUnit *SU); private: void adjustPriorityOfUnscheduledPreds(SUnit *SU); SUnit *getSingleUnscheduledPred(SUnit *SU); unsigned numberRCValPredInSU (SUnit *SU, unsigned RCId); unsigned numberRCValSuccInSU (SUnit *SU, unsigned RCId); }; } #endif