LLVM API Documentation

ScheduleDFS.h
Go to the documentation of this file.
00001 //===- ScheduleDAGILP.h - ILP metric for ScheduleDAGInstrs ------*- C++ -*-===//
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 // Definition of an ILP metric for machine level instruction scheduling.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_CODEGEN_SCHEDULEDFS_H
00015 #define LLVM_CODEGEN_SCHEDULEDFS_H
00016 
00017 #include "llvm/CodeGen/ScheduleDAG.h"
00018 #include "llvm/Support/DataTypes.h"
00019 #include <vector>
00020 
00021 namespace llvm {
00022 
00023 class raw_ostream;
00024 class IntEqClasses;
00025 class ScheduleDAGInstrs;
00026 class SUnit;
00027 
00028 /// \brief Represent the ILP of the subDAG rooted at a DAG node.
00029 ///
00030 /// ILPValues summarize the DAG subtree rooted at each node. ILPValues are
00031 /// valid for all nodes regardless of their subtree membership.
00032 ///
00033 /// When computed using bottom-up DFS, this metric assumes that the DAG is a
00034 /// forest of trees with roots at the bottom of the schedule branching upward.
00035 struct ILPValue {
00036   unsigned InstrCount;
00037   /// Length may either correspond to depth or height, depending on direction,
00038   /// and cycles or nodes depending on context.
00039   unsigned Length;
00040 
00041   ILPValue(unsigned count, unsigned length):
00042     InstrCount(count), Length(length) {}
00043 
00044   // Order by the ILP metric's value.
00045   bool operator<(ILPValue RHS) const {
00046     return (uint64_t)InstrCount * RHS.Length
00047       < (uint64_t)Length * RHS.InstrCount;
00048   }
00049   bool operator>(ILPValue RHS) const {
00050     return RHS < *this;
00051   }
00052   bool operator<=(ILPValue RHS) const {
00053     return (uint64_t)InstrCount * RHS.Length
00054       <= (uint64_t)Length * RHS.InstrCount;
00055   }
00056   bool operator>=(ILPValue RHS) const {
00057     return RHS <= *this;
00058   }
00059 
00060   void print(raw_ostream &OS) const;
00061 
00062   void dump() const;
00063 };
00064 
00065 /// \brief Compute the values of each DAG node for various metrics during DFS.
00066 class SchedDFSResult {
00067   friend class SchedDFSImpl;
00068 
00069   static const unsigned InvalidSubtreeID = ~0u;
00070 
00071   /// \brief Per-SUnit data computed during DFS for various metrics.
00072   ///
00073   /// A node's SubtreeID is set to itself when it is visited to indicate that it
00074   /// is the root of a subtree. Later it is set to its parent to indicate an
00075   /// interior node. Finally, it is set to a representative subtree ID during
00076   /// finalization.
00077   struct NodeData {
00078     unsigned InstrCount;
00079     unsigned SubtreeID;
00080 
00081     NodeData(): InstrCount(0), SubtreeID(InvalidSubtreeID) {}
00082   };
00083 
00084   /// \brief Per-Subtree data computed during DFS.
00085   struct TreeData {
00086     unsigned ParentTreeID;
00087     unsigned SubInstrCount;
00088 
00089     TreeData(): ParentTreeID(InvalidSubtreeID), SubInstrCount(0) {}
00090   };
00091 
00092   /// \brief Record a connection between subtrees and the connection level.
00093   struct Connection {
00094     unsigned TreeID;
00095     unsigned Level;
00096 
00097     Connection(unsigned tree, unsigned level): TreeID(tree), Level(level) {}
00098   };
00099 
00100   bool IsBottomUp;
00101   unsigned SubtreeLimit;
00102   /// DFS results for each SUnit in this DAG.
00103   std::vector<NodeData> DFSNodeData;
00104 
00105   // Store per-tree data indexed on tree ID,
00106   SmallVector<TreeData, 16> DFSTreeData;
00107 
00108   // For each subtree discovered during DFS, record its connections to other
00109   // subtrees.
00110   std::vector<SmallVector<Connection, 4> > SubtreeConnections;
00111 
00112   /// Cache the current connection level of each subtree.
00113   /// This mutable array is updated during scheduling.
00114   std::vector<unsigned> SubtreeConnectLevels;
00115 
00116 public:
00117   SchedDFSResult(bool IsBU, unsigned lim)
00118     : IsBottomUp(IsBU), SubtreeLimit(lim) {}
00119 
00120   /// \brief Get the node cutoff before subtrees are considered significant.
00121   unsigned getSubtreeLimit() const { return SubtreeLimit; }
00122 
00123   /// \brief Return true if this DFSResult is uninitialized.
00124   ///
00125   /// resize() initializes DFSResult, while compute() populates it.
00126   bool empty() const { return DFSNodeData.empty(); }
00127 
00128   /// \brief Clear the results.
00129   void clear() {
00130     DFSNodeData.clear();
00131     DFSTreeData.clear();
00132     SubtreeConnections.clear();
00133     SubtreeConnectLevels.clear();
00134   }
00135 
00136   /// \brief Initialize the result data with the size of the DAG.
00137   void resize(unsigned NumSUnits) {
00138     DFSNodeData.resize(NumSUnits);
00139   }
00140 
00141   /// \brief Compute various metrics for the DAG with given roots.
00142   void compute(ArrayRef<SUnit> SUnits);
00143 
00144   /// \brief Get the number of instructions in the given subtree and its
00145   /// children.
00146   unsigned getNumInstrs(const SUnit *SU) const {
00147     return DFSNodeData[SU->NodeNum].InstrCount;
00148   }
00149 
00150   /// \brief Get the number of instructions in the given subtree not including
00151   /// children.
00152   unsigned getNumSubInstrs(unsigned SubtreeID) const {
00153     return DFSTreeData[SubtreeID].SubInstrCount;
00154   }
00155 
00156   /// \brief Get the ILP value for a DAG node.
00157   ///
00158   /// A leaf node has an ILP of 1/1.
00159   ILPValue getILP(const SUnit *SU) const {
00160     return ILPValue(DFSNodeData[SU->NodeNum].InstrCount, 1 + SU->getDepth());
00161   }
00162 
00163   /// \brief The number of subtrees detected in this DAG.
00164   unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); }
00165 
00166   /// \brief Get the ID of the subtree the given DAG node belongs to.
00167   ///
00168   /// For convenience, if DFSResults have not been computed yet, give everything
00169   /// tree ID 0.
00170   unsigned getSubtreeID(const SUnit *SU) const {
00171     if (empty())
00172       return 0;
00173     assert(SU->NodeNum < DFSNodeData.size() &&  "New Node");
00174     return DFSNodeData[SU->NodeNum].SubtreeID;
00175   }
00176 
00177   /// \brief Get the connection level of a subtree.
00178   ///
00179   /// For bottom-up trees, the connection level is the latency depth (in cycles)
00180   /// of the deepest connection to another subtree.
00181   unsigned getSubtreeLevel(unsigned SubtreeID) const {
00182     return SubtreeConnectLevels[SubtreeID];
00183   }
00184 
00185   /// \brief Scheduler callback to update SubtreeConnectLevels when a tree is
00186   /// initially scheduled.
00187   void scheduleTree(unsigned SubtreeID);
00188 };
00189 
00190 raw_ostream &operator<<(raw_ostream &OS, const ILPValue &Val);
00191 
00192 } // namespace llvm
00193 
00194 #endif