PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/verilator-3.805/src/V3Graph.h

#
C Header | 267 lines | 163 code | 29 blank | 75 comment | 6 complexity | ea376335b67a4d4e1f30275244daa132 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. //-*- C++ -*-
  2. //*************************************************************************
  3. // DESCRIPTION: Verilator: Graph optimizations
  4. //
  5. // Code available from: http://www.veripool.org/verilator
  6. //
  7. // AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
  8. //
  9. //*************************************************************************
  10. //
  11. // Copyright 2003-2010 by Wilson Snyder. This program is free software; you can
  12. // redistribute it and/or modify it under the terms of either the GNU
  13. // Lesser General Public License Version 3 or the Perl Artistic License
  14. // Version 2.0.
  15. //
  16. // Verilator is distributed in the hope that it will be useful,
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. // GNU General Public License for more details.
  20. //
  21. //*************************************************************************
  22. #ifndef _V3GRAPH_H_
  23. #define _V3GRAPH_H_ 1
  24. #include "config_build.h"
  25. #include "verilatedos.h"
  26. #include "V3Error.h"
  27. #include "V3List.h"
  28. #include <vector>
  29. #include <algorithm>
  30. class V3Graph;
  31. class V3GraphVertex;
  32. class V3GraphEdge;
  33. class GraphAcycEdge;
  34. class OrderEitherVertex;
  35. class OrderLogicVertex;
  36. //=============================================================================
  37. // Most graph algorithms accept an arbitrary function that returns
  38. // True for those edges we should honor.
  39. typedef bool (*V3EdgeFuncP)(const V3GraphEdge* edgep);
  40. //============================================================================
  41. class V3Graph {
  42. private:
  43. // STATE
  44. V3List<V3GraphVertex*> m_vertices; // All vertices
  45. static int s_debug;
  46. protected:
  47. friend class V3GraphVertex; friend class V3GraphEdge;
  48. friend class GraphAcyc;
  49. // METHODS
  50. void acyclicDFS();
  51. void acyclicDFSIterate(V3GraphVertex *vertexp, int depth, uint32_t currentRank);
  52. void acyclicCut();
  53. void acyclicLoop(V3GraphVertex* vertexp, int depth);
  54. double orderDFSIterate(V3GraphVertex* vertexp);
  55. void dumpEdge(ostream& os, V3GraphVertex* vertexp, V3GraphEdge* edgep);
  56. void verticesUnlink() { m_vertices.reset(); }
  57. // ACCESSORS
  58. static int debug();
  59. public:
  60. V3Graph();
  61. virtual ~V3Graph();
  62. static void debug(int level) { s_debug = level; }
  63. virtual string dotRankDir() { return "TB"; } // rankdir for dot plotting
  64. // METHODS
  65. void clear(); // Empty it of all vertices/edges, as if making a new object
  66. void clearColors();
  67. V3GraphVertex* verticesBeginp() const { return m_vertices.begin(); }
  68. // METHODS - ALGORITHMS
  69. /// Assign same color to all vertices in the same weakly connected component
  70. /// Thus different color if there's no edges between the two subgraphs
  71. void weaklyConnected(V3EdgeFuncP edgeFuncp);
  72. /// Assign same color to all vertices that are strongly connected
  73. /// Thus different color if there's no directional circuit within the subgraphs.
  74. /// (I.E. all loops will occur within each color, not between them.)
  75. void stronglyConnected(V3EdgeFuncP edgeFuncp);
  76. /// Assign same color to all destination vertices that have same
  77. /// subgraph feeding into them
  78. /// (I.E. all "from" nodes are common within each color)
  79. /// See V3ClkGater if this is needed again; it got specialized
  80. /// Assign a ordering number to all vertexes in a tree.
  81. /// All nodes with no inputs will get rank 1
  82. void rank(V3EdgeFuncP edgeFuncp);
  83. void rank();
  84. /// Sort all vertices and edges using the V3GraphVertex::sortCmp() function
  85. void sortVertices();
  86. /// Sort all edges and edges using the V3GraphEdge::sortCmp() function
  87. void sortEdges();
  88. /// Order all vertices by rank and fanout, lowest first
  89. /// Sort all vertices by rank and fanout, lowest first
  90. /// Sort all edges by weight, lowest first
  91. void order();
  92. /// Make acyclical (into a tree) by breaking a minimal subset of cutable edges.
  93. void acyclic(V3EdgeFuncP edgeFuncp);
  94. /// Delete any nodes with only outputs
  95. void deleteCutableOnlyEdges();
  96. /// Any cutable edged become non-cutable
  97. void makeEdgesNonCutable(V3EdgeFuncP edgeFuncp);
  98. /// Remove any redundant edges, weights become MAX of any other weight
  99. void removeRedundantEdges(V3EdgeFuncP edgeFuncp);
  100. /// Remove any redundant edges, weights become SUM of any other weight
  101. void removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp);
  102. /// Call loopsVertexCb on any loops starting where specified
  103. void reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp);
  104. /// Debugging
  105. void dump(ostream& os=cout);
  106. void dumpDotFile(const string& filename, bool colorAsSubgraph);
  107. void dumpDotFilePrefixed(const string& nameComment, bool colorAsSubgraph=false);
  108. void userClearVertices();
  109. void userClearEdges();
  110. static void test();
  111. // CALLBACKS
  112. virtual void loopsMessageCb(V3GraphVertex* vertexp) { v3fatalSrc("Loops detected in graph: "<<vertexp); }
  113. virtual void loopsVertexCb(V3GraphVertex* vertexp);
  114. };
  115. //============================================================================
  116. class V3GraphVertex : public AstNUser {
  117. // Vertices may be a 'gate'/wire statement OR a variable
  118. protected:
  119. friend class V3Graph; friend class V3GraphEdge;
  120. friend class GraphAcyc; friend class GraphAlgRank;
  121. V3ListEnt<V3GraphVertex*> m_vertices;// All vertices, linked list
  122. V3List<V3GraphEdge*> m_outs; // Outbound edges,linked list
  123. V3List<V3GraphEdge*> m_ins; // Inbound edges, linked list
  124. double m_fanout; // Order fanout
  125. uint32_t m_color; // Color of the node
  126. uint32_t m_rank; // Rank of edge
  127. union {
  128. void* m_userp; // Marker for some algorithms
  129. uint32_t m_user; // Marker for some algorithms
  130. };
  131. // METHODS
  132. void verticesPushBack(V3Graph* graphp);
  133. // ACCESSORS
  134. void fanout(double fanout) { m_fanout = fanout; }
  135. void rank(uint32_t rank) { m_rank = rank; }
  136. void inUnlink() { m_ins.reset(); } // Low level; normally unlinkDelete is what you want
  137. void outUnlink() { m_outs.reset(); } // Low level; normally unlinkDelete is what you want
  138. public:
  139. // CONSTRUCTION
  140. V3GraphVertex(V3Graph* graphp);
  141. virtual ~V3GraphVertex() {}
  142. void unlinkEdges(V3Graph* graphp);
  143. void unlinkDelete(V3Graph* graphp);
  144. // ACCESSORS
  145. virtual string name() const { return ""; }
  146. virtual string dotColor() const { return "black"; }
  147. virtual string dotShape() const { return ""; }
  148. virtual string dotStyle() const { return ""; }
  149. virtual string dotName() const { return ""; }
  150. virtual int sortCmp(const V3GraphVertex* rhsp) const {
  151. // LHS goes first if of lower rank, or lower fanout
  152. if (m_rank < rhsp->m_rank) return -1;
  153. if (m_rank > rhsp->m_rank) return 1;
  154. if (m_fanout < rhsp->m_fanout) return -1;
  155. if (m_fanout > rhsp->m_fanout) return 1;
  156. return 0;
  157. }
  158. uint32_t color() const { return m_color; }
  159. void color(uint32_t color) { m_color = color; }
  160. uint32_t rank() const { return m_rank; }
  161. double fanout() const { return m_fanout; }
  162. void user(uint32_t user) { m_user = user; }
  163. uint32_t user() const { return m_user; }
  164. void userp(void* userp) { m_userp = userp; }
  165. void* userp() const { return m_userp; }
  166. // ITERATORS
  167. V3GraphVertex* verticesNextp() const { return m_vertices.nextp(); }
  168. V3GraphEdge* inBeginp() const { return m_ins.begin(); }
  169. bool inEmpty() const { return inBeginp()==NULL; }
  170. bool inSize1() const;
  171. uint32_t inHash() const;
  172. V3GraphEdge* outBeginp() const { return m_outs.begin(); }
  173. bool outEmpty() const { return outBeginp()==NULL; }
  174. bool outSize1() const;
  175. uint32_t outHash() const;
  176. // METHODS
  177. void rerouteEdges(V3Graph* graphp); ///< Edges are routed around this vertex to point from "from" directly to "to"
  178. };
  179. ostream& operator<<(ostream& os, V3GraphVertex* vertexp);
  180. //============================================================================
  181. class V3GraphEdge {
  182. // Wires/variables aren't edges. Edges have only a single to/from vertex
  183. protected:
  184. friend class V3Graph; friend class V3GraphVertex;
  185. friend class GraphAcyc; friend class GraphAcycEdge;
  186. V3ListEnt<V3GraphEdge*> m_outs; // Next Outbound edge for same vertex (linked list)
  187. V3ListEnt<V3GraphEdge*> m_ins; // Next Inbound edge for same vertex (linked list)
  188. //
  189. V3GraphVertex* m_fromp; // Vertices pointing to this edge
  190. V3GraphVertex* m_top; // Vertices this edge points to
  191. int m_weight; // Weight of the connection
  192. bool m_cutable; // Interconnect may be broken in order sorting
  193. union {
  194. void* m_userp; // Marker for some algorithms
  195. uint32_t m_user; // Marker for some algorithms
  196. };
  197. // METHODS
  198. void cut() { m_weight = 0; } // 0 weight is same as disconnected
  199. void outPushBack();
  200. void inPushBack();
  201. public:
  202. // ENUMS
  203. enum Cuttable { NOT_CUTABLE = false, CUTABLE = true }; // For passing to V3GraphEdge
  204. // CONSTRUCTION
  205. // Add DAG from one node to the specified node
  206. V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false);
  207. virtual ~V3GraphEdge() {}
  208. // METHODS
  209. virtual string name() const { return m_fromp->name()+"->"+m_top->name(); }
  210. virtual string dotLabel() const { return ""; }
  211. virtual string dotColor() const { return cutable()?"yellowGreen":"red"; }
  212. virtual string dotStyle() const { return cutable()?"dashed":""; }
  213. virtual int sortCmp(const V3GraphEdge* rhsp) const {
  214. if (!m_weight || !rhsp->m_weight) return 0;
  215. return top()->sortCmp(rhsp->top());
  216. }
  217. void unlinkDelete();
  218. // ACCESSORS
  219. int weight() const { return m_weight; }
  220. void weight(int weight) { m_weight=weight; }
  221. bool cutable() const { return m_cutable; }
  222. void cutable(bool cutable) { m_cutable=cutable; }
  223. void userp(void* user) { m_userp = user; }
  224. void* userp() const { return m_userp; }
  225. void user(uint32_t user) { m_user = user; }
  226. uint32_t user() const { return m_user; }
  227. V3GraphVertex* fromp() const { return m_fromp; }
  228. V3GraphVertex* top() const { return m_top; }
  229. // STATIC ACCESSORS
  230. static bool followNotCutable(const V3GraphEdge* edgep) { return !edgep->m_cutable; }
  231. static bool followAlwaysTrue(const V3GraphEdge*) { return true; }
  232. // ITERATORS
  233. V3GraphEdge* outNextp() const { return m_outs.nextp(); }
  234. V3GraphEdge* inNextp() const { return m_ins.nextp(); }
  235. };
  236. //============================================================================
  237. #endif // Guard