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