virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->lvalue()) { AstVarScope* vscp = nodep->varScopep(); if (nodep->varp()->isSigPublic()) { // Public signals shouldn't be changed, pli code might be messing with them scoreboardPli(nodep); } // If another lvalue in this node, give up optimizing. // We could just not optimize this variable, but we've already marked the // other variable as optimizable, so we can instead pretend it's a PLI node. if (m_stmtVscp) { UINFO(5, " Multiple lvalues in one statement: "<<nodep<<endl); scoreboardPli(nodep); // This will set m_stmtInPli } m_stmtVscp = vscp; // Find, or make new Vertex GaterVarVertex* vertexp = (GaterVarVertex*)(vscp->user1p()); if (!vertexp) { vertexp = new GaterVarVertex(&m_graph, vscp); vscp->user1p(vertexp); } new GaterEdge(&m_graph, m_aboveVertexp, vertexp, m_aboveTrue); if (m_stmtInPli) { new GaterEdge(&m_graph, m_pliVertexp, vertexp, VU_PLI); } } }
inline void iterateChildrenAlw(AstNode* nodep, bool under) { // **** USE THIS INSTEAD OF iterateChildren! // Note If visitor doesn't call here; does it its own way bool lastdua = m_directlyUnderAlw; AstVarScope* lastvscp = m_stmtVscp; bool lastpli = m_stmtInPli; m_directlyUnderAlw = under; if (nodep->castNodeStmt()) { // Restored below UINFO(9," Stmt: "<<nodep<<endl); m_stmtVscp = NULL; m_stmtInPli = false; } if (!nodep->isPure() || nodep->isBrancher()) { // May also be a new statement (above if); if so we mark it immediately UINFO(9," NotPure "<<nodep<<endl); scoreboardPli(nodep); } { nodep->iterateChildren(*this); } m_directlyUnderAlw = lastdua; if (nodep->castNodeStmt()) { // Reset what set above; else propagate up to above statement m_stmtVscp = lastvscp; m_stmtInPli = lastpli; } }
//-------------------- // Default virtual void visit(AstNode* nodep) { // **** SPECIAL default type that sets PLI_ORDERING if (!m_stmtStackps.empty() && !nodep->isPure()) { UINFO(9," NotSplittable "<<nodep<<endl); scoreboardPli(nodep); } iterateChildren(nodep); }
virtual void visit(AstVarRef* nodep, AstNUser*) { if (!m_stmtStackps.empty()) { AstVarScope* vscp = nodep->varScopep(); if (!vscp) nodep->v3fatalSrc("Not linked"); if (!nodep->varp()->isConst()) { // Constant lookups can be ignored if (nodep->varp()->isSigPublic()) { // Public signals shouldn't be changed, pli code might be messing with them scoreboardPli(); } // Create vertexes for variable if (!vscp->user1p()) { SplitVarStdVertex* vstdp = new SplitVarStdVertex(&m_graph, vscp); vscp->user1p(vstdp); } SplitVarStdVertex* vstdp = (SplitVarStdVertex*) vscp->user1p(); // SPEEDUP: We add duplicate edges, that should be fixed if (m_inDly && nodep->lvalue()) { UINFO(4," VARREFDLY: "<<nodep<<endl); // Delayed variable is different from non-delayed variable if (!vscp->user2p()) { SplitVarPostVertex* vpostp = new SplitVarPostVertex(&m_graph, vscp); vscp->user2p(vpostp); new SplitPostEdge(&m_graph, vstdp, vpostp); } SplitVarPostVertex* vpostp = (SplitVarPostVertex*)vscp->user2p(); // Add edges for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitLVEdge(&m_graph, vpostp, *it); } } else { // Nondelayed assignment if (nodep->lvalue()) { // Non-delay; need to maintain existing ordering with all consumers of the signal UINFO(4," VARREFLV: "<<nodep<<endl); for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitLVEdge(&m_graph, vstdp, *it); } } else { UINFO(4," VARREF: "<<nodep<<endl); for (VStack::iterator it = m_stmtStackps.begin(); it != m_stmtStackps.end(); ++it) { new SplitRVEdge(&m_graph, *it, vstdp); } } } } } }