//===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file declares the LatencyPriorityQueue class, which is a // SchedulingPriorityQueue that schedules using latency information to // reduce the length of the critical path through the basic block. // //===----------------------------------------------------------------------===// #ifndef LATENCY_PRIORITY_QUEUE_H #define LATENCY_PRIORITY_QUEUE_H #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/ADT/PriorityQueue.h" namespace llvm { class LatencyPriorityQueue; /// Sorting functions for the Available queue. struct latency_sort : public std::binary_function { LatencyPriorityQueue *PQ; explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {} bool operator()(const SUnit* left, const SUnit* right) const; }; class LatencyPriorityQueue : public SchedulingPriorityQueue { // SUnits - The SUnits for the current graph. std::vector *SUnits; // Latencies - The latency (max of latency from this node to the bb exit) // for each node. std::vector Latencies; /// 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; PriorityQueue, latency_sort> Queue; public: LatencyPriorityQueue() : Queue(latency_sort(this)) { } void initNodes(std::vector &sunits) { SUnits = &sunits; // Calculate node priorities. CalculatePriorities(); } void addNode(const SUnit *SU) { Latencies.resize(SUnits->size(), -1); NumNodesSolelyBlocking.resize(SUnits->size(), 0); CalcLatency(*SU); } void updateNode(const SUnit *SU) { Latencies[SU->NodeNum] = -1; CalcLatency(*SU); } void releaseState() { SUnits = 0; Latencies.clear(); } unsigned getLatency(unsigned NodeNum) const { assert(NodeNum < Latencies.size()); return Latencies[NodeNum]; } unsigned getNumSolelyBlockNodes(unsigned NodeNum) const { assert(NodeNum < NumNodesSolelyBlocking.size()); return NumNodesSolelyBlocking[NodeNum]; } unsigned size() const { return Queue.size(); } bool empty() const { return Queue.empty(); } virtual void push(SUnit *U) { push_impl(U); } void push_impl(SUnit *U); void push_all(const std::vector &Nodes) { for (unsigned i = 0, e = Nodes.size(); i != e; ++i) push_impl(Nodes[i]); } SUnit *pop() { if (empty()) return NULL; SUnit *V = Queue.top(); Queue.pop(); return V; } void remove(SUnit *SU) { assert(!Queue.empty() && "Not in queue!"); Queue.erase_one(SU); } // ScheduledNode - As nodes are scheduled, we look to see if there are any // successor nodes that have a single unscheduled predecessor. If so, that // single predecessor has a higher priority, since scheduling it will make // the node available. void ScheduledNode(SUnit *Node); private: void CalculatePriorities(); void CalcLatency(const SUnit &SU); void AdjustPriorityOfUnscheduledPreds(SUnit *SU); SUnit *getSingleUnscheduledPred(SUnit *SU); }; } #endif