LLVM API Documentation

LatencyPriorityQueue.h
Go to the documentation of this file.
00001 //===---- LatencyPriorityQueue.h - A latency-oriented priority queue ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file declares the LatencyPriorityQueue class, which is a
00011 // SchedulingPriorityQueue that schedules using latency information to
00012 // reduce the length of the critical path through the basic block.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #ifndef LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H
00017 #define LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H
00018 
00019 #include "llvm/CodeGen/ScheduleDAG.h"
00020 
00021 namespace llvm {
00022   class LatencyPriorityQueue;
00023 
00024   /// Sorting functions for the Available queue.
00025   struct latency_sort : public std::binary_function<SUnit*, SUnit*, bool> {
00026     LatencyPriorityQueue *PQ;
00027     explicit latency_sort(LatencyPriorityQueue *pq) : PQ(pq) {}
00028 
00029     bool operator()(const SUnit* left, const SUnit* right) const;
00030   };
00031 
00032   class LatencyPriorityQueue : public SchedulingPriorityQueue {
00033     // SUnits - The SUnits for the current graph.
00034     std::vector<SUnit> *SUnits;
00035 
00036     /// NumNodesSolelyBlocking - This vector contains, for every node in the
00037     /// Queue, the number of nodes that the node is the sole unscheduled
00038     /// predecessor for.  This is used as a tie-breaker heuristic for better
00039     /// mobility.
00040     std::vector<unsigned> NumNodesSolelyBlocking;
00041 
00042     /// Queue - The queue.
00043     std::vector<SUnit*> Queue;
00044     latency_sort Picker;
00045 
00046   public:
00047     LatencyPriorityQueue() : Picker(this) {
00048     }
00049 
00050     bool isBottomUp() const override { return false; }
00051 
00052     void initNodes(std::vector<SUnit> &sunits) override {
00053       SUnits = &sunits;
00054       NumNodesSolelyBlocking.resize(SUnits->size(), 0);
00055     }
00056 
00057     void addNode(const SUnit *SU) override {
00058       NumNodesSolelyBlocking.resize(SUnits->size(), 0);
00059     }
00060 
00061     void updateNode(const SUnit *SU) override {
00062     }
00063 
00064     void releaseState() override {
00065       SUnits = nullptr;
00066     }
00067 
00068     unsigned getLatency(unsigned NodeNum) const {
00069       assert(NodeNum < (*SUnits).size());
00070       return (*SUnits)[NodeNum].getHeight();
00071     }
00072 
00073     unsigned getNumSolelyBlockNodes(unsigned NodeNum) const {
00074       assert(NodeNum < NumNodesSolelyBlocking.size());
00075       return NumNodesSolelyBlocking[NodeNum];
00076     }
00077 
00078     bool empty() const override { return Queue.empty(); }
00079 
00080     void push(SUnit *U) override;
00081 
00082     SUnit *pop() override;
00083 
00084     void remove(SUnit *SU) override;
00085 
00086     void dump(ScheduleDAG* DAG) const override;
00087 
00088     // scheduledNode - As nodes are scheduled, we look to see if there are any
00089     // successor nodes that have a single unscheduled predecessor.  If so, that
00090     // single predecessor has a higher priority, since scheduling it will make
00091     // the node available.
00092     void scheduledNode(SUnit *Node) override;
00093 
00094 private:
00095     void AdjustPriorityOfUnscheduledPreds(SUnit *SU);
00096     SUnit *getSingleUnscheduledPred(SUnit *SU);
00097   };
00098 }
00099 
00100 #endif