diff --git a/src/V3Graph.cpp b/src/V3Graph.cpp index eb66cd934..5496b112b 100644 --- a/src/V3Graph.cpp +++ b/src/V3Graph.cpp @@ -39,9 +39,14 @@ int V3Graph::debug() { return max(V3Error::debugDefault(), s_debug); } //###################################################################### // Vertices +V3GraphVertex::V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old) + : m_fanout(old.m_fanout), m_color(old.m_color), m_rank(old.m_rank) { + m_userp = NULL; + verticesPushBack(graphp); +} + V3GraphVertex::V3GraphVertex(V3Graph* graphp) - : m_fanout(0), m_color(0), m_rank(0) -{ + : m_fanout(0), m_color(0), m_rank(0) { m_userp = NULL; verticesPushBack(graphp); } @@ -125,9 +130,9 @@ ostream& operator<<(ostream& os, V3GraphVertex* vertexp) { //###################################################################### // Edges -V3GraphEdge::V3GraphEdge(V3Graph* graphp, - V3GraphVertex* fromp, V3GraphVertex* top, int weight, - bool cutable) { +void V3GraphEdge::init(V3Graph* graphp, + V3GraphVertex* fromp, V3GraphVertex* top, int weight, + bool cutable) { UASSERT(fromp, "Null from pointer\n"); UASSERT(top, "Null to pointer\n"); m_fromp = fromp; diff --git a/src/V3Graph.h b/src/V3Graph.h index b307c5c58..4fbd93866 100644 --- a/src/V3Graph.h +++ b/src/V3Graph.h @@ -159,9 +159,14 @@ protected: void rank(uint32_t rank) { m_rank = rank; } void inUnlink() { m_ins.reset(); } // Low level; normally unlinkDelete is what you want void outUnlink() { m_outs.reset(); } // Low level; normally unlinkDelete is what you want +protected: + // CONSTRUCTORS + V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old); public: - // CONSTRUCTION V3GraphVertex(V3Graph* graphp); + //! Clone copy constructor. Doesn't copy edges or user/userp. + virtual V3GraphVertex* clone(V3Graph* graphp) const { + return new V3GraphVertex(graphp, *this); } virtual ~V3GraphVertex() {} void unlinkEdges(V3Graph* graphp); void unlinkDelete(V3Graph* graphp); @@ -207,6 +212,9 @@ ostream& operator<<(ostream& os, V3GraphVertex* vertexp); class V3GraphEdge { // Wires/variables aren't edges. Edges have only a single to/from vertex +public: + // ENUMS + enum Cuttable { NOT_CUTABLE = false, CUTABLE = true }; // For passing to V3GraphEdge protected: friend class V3Graph; friend class V3GraphVertex; friend class GraphAcyc; friend class GraphAcycEdge; @@ -222,15 +230,23 @@ protected: uint32_t m_user; // Marker for some algorithms }; // METHODS + void init(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false); void cut() { m_weight = 0; } // 0 weight is same as disconnected void outPushBack(); void inPushBack(); + // CONSTRUCTORS +protected: + V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const V3GraphEdge& old) { + init(graphp, fromp, top, old.m_weight, old.m_cutable); + } public: - // ENUMS - enum Cuttable { NOT_CUTABLE = false, CUTABLE = true }; // For passing to V3GraphEdge - // CONSTRUCTION - // Add DAG from one node to the specified node - V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false); + //! Add DAG from one node to the specified node + V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false) { + init(graphp, fromp, top, weight, cutable); + } + //! Clone copy constructor. Doesn't copy existing vertices or user/userp. + virtual V3GraphEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { + return new V3GraphEdge(graphp, fromp, top, *this); } virtual ~V3GraphEdge() {} // METHODS virtual string name() const { return m_fromp->name()+"->"+m_top->name(); } diff --git a/src/V3OrderGraph.h b/src/V3OrderGraph.h index 42d39f49d..b0bf3e5e2 100644 --- a/src/V3OrderGraph.h +++ b/src/V3OrderGraph.h @@ -131,12 +131,16 @@ class OrderEitherVertex : public V3GraphVertex { AstSenTree* m_domainp; // Clock domain (NULL = to be computed as we iterate) OrderLoopId m_inLoop; // Loop number vertex is in bool m_isFromInput; // From input, or derrived therefrom (conservatively false) +protected: + OrderEitherVertex(V3Graph* graphp, const OrderEitherVertex& old) + : V3GraphVertex(graphp, old), m_scopep(old.m_scopep), m_domainp(old.m_domainp) + , m_inLoop(old.m_inLoop), m_isFromInput(old.m_isFromInput) {} public: OrderEitherVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp) : V3GraphVertex(graphp), m_scopep(scopep), m_domainp(domainp) - , m_inLoop(LOOPID_UNKNOWN), m_isFromInput(false) { - } + , m_inLoop(LOOPID_UNKNOWN), m_isFromInput(false) {} virtual ~OrderEitherVertex() {} + virtual OrderEitherVertex* clone(V3Graph* graphp) const = 0; // Methods virtual OrderVEdgeType type() const = 0; virtual bool domainMatters() = 0; // Must be in same domain when cross edge to this vertex @@ -152,12 +156,16 @@ public: }; class OrderInputsVertex : public OrderEitherVertex { + OrderInputsVertex(V3Graph* graphp, const OrderInputsVertex& old) + : OrderEitherVertex(graphp, old) {} public: OrderInputsVertex(V3Graph* graphp, AstSenTree* domainp) : OrderEitherVertex(graphp, NULL, domainp) { isFromInput(true); // By definition } virtual ~OrderInputsVertex() {} + virtual OrderInputsVertex* clone(V3Graph* graphp) const { + return new OrderInputsVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_INPUTS; } virtual string name() const { return "*INPUTS*"; } virtual string dotColor() const { return "green"; } @@ -166,10 +174,14 @@ public: }; class OrderSettleVertex : public OrderEitherVertex { + OrderSettleVertex(V3Graph* graphp, const OrderSettleVertex& old) + : OrderEitherVertex(graphp, old) {} public: OrderSettleVertex(V3Graph* graphp, AstSenTree* domainp) : OrderEitherVertex(graphp, NULL, domainp) {} virtual ~OrderSettleVertex() {} + virtual OrderSettleVertex* clone(V3Graph* graphp) const { + return new OrderSettleVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_SETTLE; } virtual string name() const { return "*SETTLE*"; } virtual string dotColor() const { return "green"; } @@ -180,10 +192,15 @@ public: class OrderLogicVertex : public OrderEitherVertex { AstNode* m_nodep; OrderMoveVertex* m_moveVxp; +protected: + OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old) + : OrderEitherVertex(graphp, old), m_nodep(old.m_nodep), m_moveVxp(old.m_moveVxp) {} public: OrderLogicVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstNode* nodep) : OrderEitherVertex(graphp, scopep, domainp), m_nodep(nodep), m_moveVxp(NULL) {} virtual ~OrderLogicVertex() {} + virtual OrderLogicVertex* clone(V3Graph* graphp) const { + return new OrderLogicVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOGIC; } virtual bool domainMatters() { return true; } // Accessors @@ -198,11 +215,14 @@ class OrderVarVertex : public OrderEitherVertex { AstVarScope* m_varScp; OrderVarVertex* m_pilNewVertexp; // for processInsLoopNewVar bool m_isClock; // Used as clock +protected: + OrderVarVertex(V3Graph* graphp, const OrderVarVertex& old) + : OrderEitherVertex(graphp, old) + , m_varScp(old.m_varScp), m_pilNewVertexp(old.m_pilNewVertexp), m_isClock(old.m_isClock) {} public: OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp) - , m_pilNewVertexp(NULL), m_isClock(false) - {} + , m_pilNewVertexp(NULL), m_isClock(false) {} virtual ~OrderVarVertex() {} virtual OrderVarVertex* clone (V3Graph* graphp) const = 0; virtual OrderVEdgeType type() const = 0; @@ -215,66 +235,71 @@ public: }; class OrderVarStdVertex : public OrderVarVertex { + OrderVarStdVertex(V3Graph* graphp, const OrderVarStdVertex& old) + : OrderVarVertex(graphp, old) {} public: OrderVarStdVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) - : OrderVarVertex(graphp, scopep,varScp) {} + : OrderVarVertex(graphp, scopep, varScp) {} virtual ~OrderVarStdVertex() {} + virtual OrderVarStdVertex* clone(V3Graph* graphp) const { + return new OrderVarStdVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSTD; } - virtual OrderVarVertex* clone (V3Graph* graphp) const { - return new OrderVarStdVertex(graphp, scopep(), varScp()); - } virtual string name() const { return (cvtToStr((void*)varScp())+"\\n "+varScp()->name());} virtual string dotColor() const { return "skyblue"; } virtual bool domainMatters() { return true; } }; class OrderVarPreVertex : public OrderVarVertex { + OrderVarPreVertex(V3Graph* graphp, const OrderVarPreVertex& old) + : OrderVarVertex(graphp, old) {} public: OrderVarPreVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarPreVertex() {} + virtual OrderVarPreVertex* clone(V3Graph* graphp) const { + return new OrderVarPreVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPRE; } - virtual OrderVarVertex* clone (V3Graph* graphp) const { - return new OrderVarPreVertex(graphp, scopep(), varScp()); - } virtual string name() const { return (cvtToStr((void*)varScp())+" PRE\\n "+varScp()->name());} virtual string dotColor() const { return "lightblue"; } virtual bool domainMatters() { return false; } }; class OrderVarPostVertex : public OrderVarVertex { + OrderVarPostVertex(V3Graph* graphp, const OrderVarPostVertex& old) + : OrderVarVertex(graphp, old) {} public: OrderVarPostVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} + virtual OrderVarPostVertex* clone(V3Graph* graphp) const { + return new OrderVarPostVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPOST; } virtual ~OrderVarPostVertex() {} - virtual OrderVarVertex* clone (V3Graph* graphp) const { - return new OrderVarPostVertex(graphp, scopep(), varScp()); - } virtual string name() const { return (cvtToStr((void*)varScp())+" POST\\n "+varScp()->name());} virtual string dotColor() const { return "CadetBlue"; } virtual bool domainMatters() { return false; } }; class OrderVarPordVertex : public OrderVarVertex { + OrderVarPordVertex(V3Graph* graphp, const OrderVarPordVertex& old) + : OrderVarVertex(graphp, old) {} public: OrderVarPordVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} - virtual OrderVarVertex* clone (V3Graph* graphp) const { - return new OrderVarPordVertex(graphp, scopep(), varScp()); - } virtual ~OrderVarPordVertex() {} + virtual OrderVarPordVertex* clone(V3Graph* graphp) const { + return new OrderVarPordVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPORD; } virtual string name() const { return (cvtToStr((void*)varScp())+" PORD\\n "+varScp()->name());} virtual string dotColor() const { return "NavyBlue"; } virtual bool domainMatters() { return false; } }; class OrderVarSettleVertex : public OrderVarVertex { + OrderVarSettleVertex(V3Graph* graphp, const OrderVarSettleVertex& old) + : OrderVarVertex(graphp, old) {} public: OrderVarSettleVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp) : OrderVarVertex(graphp, scopep,varScp) {} virtual ~OrderVarSettleVertex() {} + virtual OrderVarSettleVertex* clone(V3Graph* graphp) const { + return new OrderVarSettleVertex(graphp, *this); } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSETTLE; } - virtual OrderVarVertex* clone (V3Graph* graphp) const { - return new OrderVarSettleVertex(graphp, scopep(), varScp()); - } virtual string name() const { return (cvtToStr((void*)varScp())+" STL\\n "+varScp()->name());} virtual string dotColor() const { return "PowderBlue"; } virtual bool domainMatters() { return false; } @@ -288,13 +313,18 @@ class OrderLoopBeginVertex : public OrderLogicVertex { // However, a LoopBeginVertex is not "under" the loop per se, and it may be under another loop. OrderLoopId m_loopId; // Arbitrary # to ID this loop uint32_t m_loopColor; // Color # of loop (for debug) + OrderLoopBeginVertex(V3Graph* graphp, const OrderLoopBeginVertex& old) + : OrderLogicVertex(graphp, *this) + , m_loopId(old.m_loopId), m_loopColor(old.m_loopColor) {} public: OrderLoopBeginVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstUntilStable* nodep, OrderLoopId loopId, uint32_t loopColor) : OrderLogicVertex(graphp, scopep, domainp, nodep) - , m_loopId(loopId), m_loopColor(loopColor) { - } + , m_loopId(loopId), m_loopColor(loopColor) {} virtual ~OrderLoopBeginVertex() {} + virtual OrderLoopBeginVertex* clone(V3Graph* graphp) const { + return new OrderLoopBeginVertex(graphp, *this); + } // Methods virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOOPBEGIN; } virtual string name() const { return "LoopBegin_"+cvtToStr(loopId())+"_c"+cvtToStr(loopColor()); } @@ -310,13 +340,18 @@ class OrderLoopEndVertex : public OrderLogicVertex { // as we need it to be a logic vertex for moving, but don't need a permanent node. // We won't add to the output graph though, so it shouldn't matter. OrderLoopBeginVertex* m_beginVertexp; // Corresponding loop begin + OrderLoopEndVertex(V3Graph* graphp, const OrderLoopEndVertex& old) + : OrderLogicVertex(graphp, old), m_beginVertexp(old.m_beginVertexp) {} public: OrderLoopEndVertex(V3Graph* graphp, OrderLoopBeginVertex* beginVertexp) - : OrderLogicVertex(graphp, beginVertexp->scopep(), beginVertexp->domainp(), beginVertexp->nodep()) + : OrderLogicVertex(graphp, beginVertexp->scopep(), + beginVertexp->domainp(), beginVertexp->nodep()) , m_beginVertexp(beginVertexp) { inLoop(beginVertexp->loopId()); } virtual ~OrderLoopEndVertex() {} + virtual OrderLoopEndVertex* clone(V3Graph* graphp) const { + return new OrderLoopEndVertex(graphp, *this); } // Methods virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOOPEND; } virtual string name() const { return "LoopEnd_"+cvtToStr(inLoop())+"_c"+cvtToStr(loopColor()); } @@ -342,10 +377,17 @@ protected: // for the head of the list, see the same var name under OrderVisitor V3ListEnt m_pomWaitingE; // List of nodes needing inputs to become ready V3ListEnt m_readyVerticesE;// List of ready under domain/scope + // CONSTRUCTORS + OrderMoveVertex(V3Graph* graphp, const OrderMoveVertex& old) + : V3GraphVertex(graphp, old), m_logicp(old.m_logicp), m_state(old.m_state) + , m_domScopep(old.m_domScopep) {} public: OrderMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp) : V3GraphVertex(graphp), m_logicp(logicp), m_state(POM_WAIT), m_domScopep(NULL) {} virtual ~OrderMoveVertex() {} + virtual OrderMoveVertex* clone(V3Graph* graphp) const { + return new OrderMoveVertex(graphp, *this); + } virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_MOVE; } virtual string dotColor() const { return logicp()->dotColor(); } virtual string name() const { @@ -376,18 +418,22 @@ public: // Edge types class OrderEdge : public V3GraphEdge { +protected: + OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, + const OrderEdge& old) + : V3GraphEdge(graphp, fromp, top, old) {} public: OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cutable=false) : V3GraphEdge(graphp, fromp, top, weight, cutable) {} virtual ~OrderEdge() {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_STD; } + virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { + return new OrderEdge(graphp, fromp, top, *this); + } // When ordering combo blocks with stronglyConnected, follow edges not involving pre/pos variables virtual bool followComboConnected() const { return true; } virtual bool followSequentConnected() const { return true; } - virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { - return new OrderEdge(graphp, fromp, top, weight(), cutable()); - } static bool followComboConnected(const V3GraphEdge* edgep) { const OrderEdge* oedgep = dynamic_cast(edgep); if (!oedgep) v3fatalSrc("Following edge of non-OrderEdge type"); @@ -403,14 +449,17 @@ public: class OrderChangeDetEdge : public OrderEdge { // Edge created from variable to OrderLoopEndVertex // Indicates a change detect will be required for this loop construct + OrderChangeDetEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, + const OrderChangeDetEdge& old) + : OrderEdge(graphp, fromp, top, old) {} public: OrderChangeDetEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_MEDIUM, false) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_CHANGEDET; } - virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { - return new OrderChangeDetEdge(graphp, fromp, top); - } virtual ~OrderChangeDetEdge() {} + virtual OrderChangeDetEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { + return new OrderChangeDetEdge(graphp, fromp, top, *this); + } virtual string dotColor() const { return "blue"; } }; @@ -418,14 +467,17 @@ class OrderComboCutEdge : public OrderEdge { // Edge created from output of combo logic // Breakable if the output var is also a input, // in which case we'll need a change detect loop around this var. + OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, + const OrderComboCutEdge& old) + : OrderEdge(graphp, fromp, top, old) {} public: OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_COMBOCUT; } - virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { - return new OrderComboCutEdge(graphp, fromp, top); - } virtual ~OrderComboCutEdge() {} + virtual OrderComboCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { + return new OrderComboCutEdge(graphp, fromp, top, *this); + } virtual string dotColor() const { return "yellowGreen"; } virtual bool followComboConnected() const { return true; } virtual bool followSequentConnected() const { return true; } @@ -435,14 +487,17 @@ class OrderPostCutEdge : public OrderEdge { // Edge created from output of post assignment // Breakable if the output var feeds back to input combo logic or another clock pin // in which case we'll need a change detect loop around this var. + OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, + const OrderPostCutEdge& old) + : OrderEdge(graphp, fromp, top, old) {} public: OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_POSTCUT; } - virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { - return new OrderPostCutEdge(graphp, fromp, top); - } virtual ~OrderPostCutEdge() {} + virtual OrderPostCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { + return new OrderPostCutEdge(graphp, fromp, top, *this); + } virtual string dotColor() const { return "PaleGreen"; } virtual bool followComboConnected() const { return false; } virtual bool followSequentConnected() const { return true; } @@ -452,16 +507,18 @@ class OrderPreCutEdge : public OrderEdge { // Edge created from var_PREVAR->consuming logic vertex // Always breakable, just results in performance loss // in which case we can't optimize away the pre/post delayed assignments + OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, + const OrderPreCutEdge& old) + : OrderEdge(graphp, fromp, top, old) {} public: OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) : OrderEdge(graphp, fromp, top, WEIGHT_PRE, CUTABLE) {} virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_PRECUT; } - virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { - return new OrderPreCutEdge(graphp, fromp, top); + virtual OrderPreCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const { + return new OrderPreCutEdge(graphp, fromp, top, *this); } virtual ~OrderPreCutEdge() {} virtual string dotColor() const { return "khaki"; } virtual bool followComboConnected() const { return false; } virtual bool followSequentConnected() const { return false; } }; -