LatencyPriorityQueue.h revision 198892
131921Sbrian//===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===//
231921Sbrian//
331921Sbrian//                     The LLVM Compiler Infrastructure
431921Sbrian//
531921Sbrian// This file is distributed under the University of Illinois Open Source
631921Sbrian// License. See LICENSE.TXT for details.
731921Sbrian//
831921Sbrian//===----------------------------------------------------------------------===//
931921Sbrian//
1031921Sbrian// This file declares the LatencyPriorityQueue class, which is a
1131921Sbrian// SchedulingPriorityQueue that schedules using latency information to
1231921Sbrian// reduce the length of the critical path through the basic block.
1331921Sbrian//
1431921Sbrian//===----------------------------------------------------------------------===//
1531921Sbrian
1631921Sbrian#ifndef LATENCY_PRIORITY_QUEUE_H
1731921Sbrian#define LATENCY_PRIORITY_QUEUE_H
1831921Sbrian
1931921Sbrian#include "llvm/CodeGen/ScheduleDAG.h"
2031921Sbrian#include "llvm/ADT/PriorityQueue.h"
2131921Sbrian
2231921Sbriannamespace llvm {
2331921Sbrian  class LatencyPriorityQueue;
2431921Sbrian
2531921Sbrian  /// Sorting functions for the Available queue.
2636465Sbrian  struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
2730715Sbrian    LatencyPriorityQueue *PQ;
2830715Sbrian    explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
2931196Sbrian
3030715Sbrian    bool operator()(const SUnit* left, const SUnit* right) const;
3131121Sbrian  };
3236285Sbrian
3334539Sbrian  class LatencyPriorityQueue : public SchedulingPriorityQueue {
3431196Sbrian    // SUnits - The SUnits for the current graph.
3530715Sbrian    std::vector<SUnit> *SUnits;
3630715Sbrian
3730715Sbrian    /// NumNodesSolelyBlocking - This vector contains, for every node in the
3830715Sbrian    /// Queue, the number of nodes that the node is the sole unscheduled
3930715Sbrian    /// predecessor for.  This is used as a tie-breaker heuristic for better
4030715Sbrian    /// mobility.
4136453Sbrian    std::vector<unsigned> NumNodesSolelyBlocking;
4230715Sbrian
4330715Sbrian    /// IgnoreAntiDep - Ignore anti-dependencies
4430715Sbrian    bool IgnoreAntiDep;
4530715Sbrian
4630715Sbrian    /// Queue - The queue.
4730715Sbrian    PriorityQueue<SUnit*, std::vector<SUnit*>, latency_sort> Queue;
4831343Sbrian
4936285Sbrianpublic:
5031343Sbrian  LatencyPriorityQueue() : IgnoreAntiDep(false), Queue(latency_sort(this)) {
5130715Sbrian    }
5231196Sbrian
5336285Sbrian    void setIgnoreAntiDep(bool ignore) {
5436285Sbrian      IgnoreAntiDep = ignore;
5536285Sbrian    }
5636285Sbrian
5731196Sbrian    void initNodes(std::vector<SUnit> &sunits) {
5836285Sbrian      SUnits = &sunits;
5936285Sbrian      NumNodesSolelyBlocking.resize(SUnits->size(), 0);
6036285Sbrian    }
6136285Sbrian
6236285Sbrian    void addNode(const SUnit *SU) {
6336285Sbrian      NumNodesSolelyBlocking.resize(SUnits->size(), 0);
6436285Sbrian    }
6536285Sbrian
6636285Sbrian    void updateNode(const SUnit *SU) {
6736285Sbrian    }
6836285Sbrian
6936285Sbrian    void releaseState() {
7036285Sbrian      SUnits = 0;
7136285Sbrian    }
7236285Sbrian
7336285Sbrian    unsigned getLatency(unsigned NodeNum) const {
7436285Sbrian      assert(NodeNum < (*SUnits).size());
7536465Sbrian      return (*SUnits)[NodeNum].getHeight(IgnoreAntiDep);
7636465Sbrian    }
7736285Sbrian
7836285Sbrian    unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
7936465Sbrian      assert(NodeNum < NumNodesSolelyBlocking.size());
8036465Sbrian      return NumNodesSolelyBlocking[NodeNum];
8136285Sbrian    }
8236285Sbrian
8336285Sbrian    unsigned size() const { return Queue.size(); }
8436285Sbrian
8536285Sbrian    bool empty() const { return Queue.empty(); }
8636285Sbrian
8731196Sbrian    virtual void push(SUnit *U) {
8836285Sbrian      push_impl(U);
8931196Sbrian    }
9036285Sbrian    void push_impl(SUnit *U);
9136285Sbrian
9236285Sbrian    void push_all(const std::vector<SUnit *> &Nodes) {
9331196Sbrian      for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
9436285Sbrian        push_impl(Nodes[i]);
9531196Sbrian    }
9631203Sbrian
9736285Sbrian    SUnit *pop() {
9836285Sbrian      if (empty()) return NULL;
9931203Sbrian      SUnit *V = Queue.top();
10036285Sbrian      Queue.pop();
10131203Sbrian      return V;
10236285Sbrian    }
10336285Sbrian
10436285Sbrian    void remove(SUnit *SU) {
10536285Sbrian      assert(!Queue.empty() && "Not in queue!");
10636285Sbrian      Queue.erase_one(SU);
10736285Sbrian    }
10836285Sbrian
10936285Sbrian    // ScheduledNode - As nodes are scheduled, we look to see if there are any
11036285Sbrian    // successor nodes that have a single unscheduled predecessor.  If so, that
11136285Sbrian    // single predecessor has a higher priority, since scheduling it will make
11236285Sbrian    // the node available.
11336285Sbrian    void ScheduledNode(SUnit *Node);
11431203Sbrian
115private:
116    void AdjustPriorityOfUnscheduledPreds(SUnit *SU);
117    SUnit *getSingleUnscheduledPred(SUnit *SU);
118  };
119}
120
121#endif
122