LLVM API Documentation
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