Ejemplo n.º 1
0
    virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
	if (m_scopep) {
	    if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block\n");
	    AstVarScope* varscp = nodep->varScopep();
	    if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
	    GateVarVertex* vvertexp = makeVarVertex(varscp);
	    UINFO(5," VARREF to "<<varscp<<endl);
	    if (m_inSenItem) vvertexp->setIsClock();
	    // For SYNCASYNCNET
	    if (m_inSenItem) varscp->user2(true);
	    else if (m_activep && m_activep->hasClocked() && !nodep->lvalue()) {
		if (varscp->user2()) {
		    if (!vvertexp->rstSyncNodep()) vvertexp->rstSyncNodep(nodep);
		} else {
		    if (!vvertexp->rstAsyncNodep()) vvertexp->rstAsyncNodep(nodep);
		}
	    }
	    // We use weight of one; if we ref the var more than once, when we simplify,
	    // the weight will increase
	    if (nodep->lvalue()) {
		new V3GraphEdge(&m_graph, m_logicVertexp, vvertexp, 1);
	    } else {
		new V3GraphEdge(&m_graph, vvertexp, m_logicVertexp, 1);
	    }
	}
    }
Ejemplo n.º 2
0
    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);
	    }
	}
    }
    // NODE STATE
    // INPUT:
    //  AstVarScope::user4p()	-> AstVarScope*, If set, replace this varscope with specified new one
    // STATE
    // VISITORS
    virtual void visit(AstVarRef* nodep, AstNUser*) {
	AstVarScope* vscp = nodep->varScopep();
	if (!vscp) nodep->v3fatalSrc("Scope not assigned");
	if (AstVarScope* newvscp = (AstVarScope*)vscp->user4p()) {
	    UINFO(9, "  Replace "<<nodep<<" to "<<newvscp<<endl);
	    AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->lvalue());
	    nodep->replaceWith(newrefp);
	    nodep->deleteTree(); nodep=NULL;
	}
    }
    virtual void visit(AstVarRef* nodep, AstNUser*) {
	// Consumption/generation of a variable,
	AstVarScope* vscp = nodep->varScopep();
	if (!vscp) nodep->v3fatalSrc("Scope not assigned");
	m_sequence++;
	if (nodep->lvalue()) {
	    // First generator
	    if (!vscp->user1()) vscp->user1(m_sequence);
	} else {
	    // Last consumer
	    vscp->user2(m_sequence);
	}
    }
Ejemplo n.º 5
0
    virtual void visit(AstVarRef* nodep) {
	// Consumption/generation of a variable,
	AstVarScope* vscp = nodep->varScopep();
	if (!vscp) nodep->v3fatalSrc("Scope not assigned");
	if (m_activep) {
	    UINFO(8,"  VarAct "<<nodep<<endl);
	    vscp->user1(true);
	}
	if (m_assignp && nodep->lvalue() && vscp->user1()) {
	    // Variable was previously used as a clock, and is now being set
	    // Thus a unordered generated clock...
	    UINFO(8,"  VarSetAct "<<nodep<<endl);
	    vscp->circular(true);
	}
    }
Ejemplo n.º 6
0
    //----
    virtual void visit(AstVarRef* nodep) {
	// Consumption/generation of a variable,
	AstVarScope* vscp = nodep->varScopep();
	if (!vscp) nodep->v3fatalSrc("Scope not assigned");
	if (m_activep && !nodep->user3()) {
	    nodep->user3(true);
	    if (vscp->isCircular()) {
		UINFO(8,"  VarActReplace "<<nodep<<endl);
		// Replace with the new variable
		AstVarScope* newvscp = genInpClk(vscp);
		AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->lvalue());
		nodep->replaceWith(newrefp);
		pushDeletep(nodep); VL_DANGLING(nodep);
	    }
	}
    }
Ejemplo n.º 7
0
    virtual void visit(AstUnpackArrayDType* nodep, AstNUser*) {
	// Note more specific dtypes above
	if (m_traVscp) {
	    if ((int)nodep->arrayUnpackedElements() > v3Global.opt.traceMaxArray()) {
		addIgnore("Wide memory > --trace-max-array ents");
	    } else if (nodep->subDTypep()->skipRefp()->castBasicDType()  // Nothing lower than this array
		       && m_traVscp->dtypep()->skipRefp() == nodep) {  // Nothing above this array
		// Simple 1-D array, use exising V3EmitC runtime loop rather than unrolling
		// This will put "(index)" at end of signal name for us
		addTraceDecl(nodep->declRange());
	    } else {
		// Unroll now, as have no other method to get right signal names
		AstNodeDType* subtypep = nodep->subDTypep()->skipRefp();
		for (int i=nodep->lsb(); i<=nodep->msb(); ++i) {
		    string oldShowname = m_traShowname;
		    AstNode* oldValuep = m_traValuep;
		    {
			m_traShowname += string("(")+cvtToStr(i)+string(")");
			m_traValuep = new AstArraySel(nodep->fileline(), m_traValuep->cloneTree(true),
						      i - nodep->lsb());

			subtypep->accept(*this);
			m_traValuep->deleteTree(); m_traValuep = NULL;
		    }
		    m_traShowname = oldShowname;
		    m_traValuep = oldValuep;
		}
	    }
	}
    }
Ejemplo n.º 8
0
    virtual void visit(AstVarRef* nodep) {
        if (!m_stmtStackps.empty()) {
            AstVarScope* vscp = nodep->varScopep();
            if (!vscp) nodep->v3fatalSrc("Not linked");
            if (!nodep->varp()->isConst()) {  // Constant lookups can be ignored
                // ---
                // NOTE: Formerly at this location we would avoid
                // splitting or reordering if the variable is public.
                //
                // However, it should be perfectly safe to split an
                // always block containing a public variable.
                // Neither operation should perturb PLI's view of
                // the variable.
                //
                // Former code:
                //
                //   if (nodep->varp()->isSigPublic()) {
                //       // Public signals shouldn't be changed,
                //       // pli code might be messing with them
                //       scoreboardPli(nodep);
                //   }
                // ---

                // 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);
                        makeRvalueEdges(vstdp);
                    }
                }
            }
        }
    }
Ejemplo n.º 9
0
    virtual AstNUser* visit(GateVarVertex *vvertexp, AstNUser*) {
	// Check that we haven't been here before
	if (vvertexp->varScp()->user2()) return NULL;
	vvertexp->varScp()->user2(true);

	AstNodeVarRef* dupVarRefp = (AstNodeVarRef*) vvertexp->iterateInEdges(*this, (AstNUser*) vvertexp);

	if (dupVarRefp && vvertexp->inSize1()) {
	    V3GraphEdge* edgep = vvertexp->inBeginp();
	    GateLogicVertex* lvertexp = (GateLogicVertex*)edgep->fromp();
	    if (!vvertexp->dedupable()) vvertexp->varScp()->v3fatalSrc("GateLogicVertex* visit should have returned NULL if consumer var vertex is not dedupable.");
	    GateOkVisitor okVisitor(lvertexp->nodep(), false, true);
	    if (okVisitor.isSimple()) {
		AstVarScope* dupVarScopep = dupVarRefp->varScopep();
		GateVarVertex* dupVvertexp = (GateVarVertex*) (dupVarScopep->user1p());
		UINFO(4,"replacing " << vvertexp << " with " << dupVvertexp << endl);
		++m_numDeduped;
		// Replace all of this varvertex's consumers with dupVarRefp
		for (V3GraphEdge* outedgep = vvertexp->outBeginp();outedgep;) {
		    GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(outedgep->top());
		    AstNode* consumerp = consumeVertexp->nodep();
		    GateElimVisitor elimVisitor(consumerp,vvertexp->varScp(),dupVarRefp);
		    outedgep = outedgep->relinkFromp(dupVvertexp);
		}

		// Propogate attributes
		dupVvertexp->propagateAttrClocksFrom(vvertexp);

		// Remove inputs links
		while (V3GraphEdge* inedgep = vvertexp->inBeginp()) {
		    inedgep->unlinkDelete(); VL_DANGLING(inedgep);
		}
		// replaceAssigns() does the deleteTree on lvertexNodep in a later step
		AstNode* lvertexNodep = lvertexp->nodep();
		lvertexNodep->unlinkFrBack();
		vvertexp->varScp()->valuep(lvertexNodep);
		lvertexNodep = NULL;
		vvertexp->user(true);
		lvertexp->user(true);
	    }
	}
	return NULL;
    }
Ejemplo n.º 10
0
    void addTraceDecl(const VNumRange& arrayRange) {
	VNumRange bitRange;
	AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp();
	if (bdtypep) bitRange = bdtypep->nrange();
	AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traValuep,
					       bitRange, arrayRange);

	if (m_initSubStmts && v3Global.opt.outputSplitCTrace()
	    && m_initSubStmts > v3Global.opt.outputSplitCTrace()) {
	    m_initSubFuncp = newCFuncSub(m_initFuncp);
	    m_initSubStmts = 0;
	}

	m_initSubFuncp->addStmtsp(declp);
	m_initSubStmts += EmitCBaseCounterVisitor(declp).count();

	m_chgFuncp->addStmtsp(new AstTraceInc(m_traVscp->fileline(), declp, m_traValuep->cloneTree(true)));
	// The full version will get constructed in V3Trace
    }
Ejemplo n.º 11
0
void GateVisitor::warnSignals() {
    AstNode::user2ClearTree();
    for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
	if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
	    AstVarScope* vscp = vvertexp->varScp();
	    AstNode* sp = vvertexp->rstSyncNodep();
	    AstNode* ap = vvertexp->rstAsyncNodep();
	    if (ap && sp && !vscp->varp()->user2()) {
		// This is somewhat wrong, as marking one flop as ok for sync
		// may mean a different flop now fails.  However it's a pain to
		// then report a warning in a new place - we should report them all at once.
		// Instead we'll disable if any disabled
		if (!vscp->fileline()->warnIsOff(V3ErrorCode::SYNCASYNCNET)
		    && !ap->fileline()->warnIsOff(V3ErrorCode::SYNCASYNCNET)
		    && !sp->fileline()->warnIsOff(V3ErrorCode::SYNCASYNCNET)
		    ) {
		    vscp->varp()->user2(true);  // Warn only once per signal
		    vscp->v3warn(SYNCASYNCNET,"Signal flopped as both synchronous and async: "<<vscp->prettyName()<<endl
				 <<ap->warnMore()<<"... Location of async usage"<<endl
				 <<sp->warnMore()<<"... Location of sync usage"<<endl);
		}
	    }
	}
    }
}
Ejemplo n.º 12
0
    void deadCheckVar() {
	// Delete any unused varscopes
	for (vector<AstVarScope*>::iterator it = m_vscsp.begin(); it!=m_vscsp.end(); ++it) {
	    AstVarScope* vscp = *it;
	    if (vscp->user1() == 0) {
		UINFO(4,"  Dead "<<vscp<<endl);
		pair <AssignMap::iterator,AssignMap::iterator> eqrange = m_assignMap.equal_range(vscp);
		for (AssignMap::iterator it = eqrange.first; it != eqrange.second; ++it) {
		    AstNodeAssign* assp = it->second;
		    UINFO(4,"    Dead assign "<<assp<<endl);
		    assp->unlinkFrBack()->deleteTree(); VL_DANGLING(assp);
		}
		vscp->unlinkFrBack()->deleteTree(); VL_DANGLING(vscp);
	    }
	}
	for (vector<AstNode*>::iterator it = m_varEtcsp.begin(); it!=m_varEtcsp.end(); ++it) {
	    if ((*it)->user1() == 0) {
		UINFO(4,"  Dead "<<(*it)<<endl);
		(*it)->unlinkFrBack()->deleteTree(); (*it)=NULL;
	    }
	}
    }
Ejemplo n.º 13
0
    // VISITORS
    virtual void visit(AstVarRef* nodep, AstNUser*) {
	if (nodep->lvalue()) {
	    AstVarScope* vscp = nodep->varScopep();
	    if (vscp->user2p()->castNode() == m_exprp) {
		// This variable's block needs to move to the new always
		if (m_original) {
		    UINFO(9,"  VARREF delete in old: "<<nodep<<endl);
		    m_state |= STATE_DELETE;
		} else {
		    UINFO(9,"  VARREF stays in new:  "<<nodep<<endl);
		    m_state |= STATE_KEEP;
		}
	    } else {
		if (m_original) {
		    UINFO(9,"  VARREF other stays in old\n");
		    m_state |= STATE_KEEP;
		} else {
		    UINFO(9,"  VARREF other delete in new\n");
		    m_state |= STATE_DELETE;
		}
	    }
	}
    }
Ejemplo n.º 14
0
    void dualBranch(LifeBlock* life1p, LifeBlock* life2p) {
	// Find any common sets on both branches of IF and propagate upwards
	//life1p->lifeDump();
	//life2p->lifeDump();
	AstNode::user1ClearTree();	// user1p() used on entire tree
	for (LifeMap::iterator it = life1p->m_map.begin(); it!=life1p->m_map.end(); ++it) {
	    // When the if branch sets a var before it's used, mark that variable
	    if (it->second.setBeforeUse()) it->first->user1(1);
	}
	for (LifeMap::iterator it = life2p->m_map.begin(); it!=life2p->m_map.end(); ++it) {
	    // When the else branch sets a var before it's used
	    AstVarScope* nodep = it->first;
	    if (it->second.setBeforeUse() && nodep->user1()) {
		// Both branches set the var, we can remove the assignment before the IF.
		UINFO(4,"DUALBRANCH "<<nodep<<endl);
		LifeMap::iterator itab = m_map.find(nodep);
		if (itab != m_map.end()) {
		    checkRemoveAssign(itab);
		}
	    }
	}
	//this->lifeDump();
    }
Ejemplo n.º 15
0
    void scoreboardPli(AstNode* nodep) {
	// Order all PLI statements with other PLI statements
	// This insures $display's and such remain in proper order
	// We don't prevent splitting out other non-pli statements, however,
	// because it is common to have $uasserts sprinkled about.
	if (!m_pliVertexp) {
	    m_pliVertexp = new GaterPliVertex(&m_graph);
	}
	if (m_stmtVscp) {  // Already saw a variable, be sure to mark it!
	    GaterVarVertex* varVtxp = (GaterVarVertex*)(m_stmtVscp->user1p());
	    new GaterEdge(&m_graph, m_pliVertexp, varVtxp, VU_PLI);
	}
	m_stmtInPli = true;  // Mark all followon variables too
    }
Ejemplo n.º 16
0
    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);
			}
		    }
		}
	    }
	}
    }
Ejemplo n.º 17
0
    virtual void visit(AstVarRef* nodep, AstNUser*) {
	if (!nodep->user2Inc()) {  // Not done yet
	    if (m_inDly && nodep->lvalue()) {
		UINFO(4,"AssignDlyVar: "<<nodep<<endl);
		markVarUsage(nodep->varScopep(), VU_DLY);
		if (!m_activep) nodep->v3fatalSrc("<= not under sensitivity block");
		if (!m_activep->hasClocked()) nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active");
		AstVarScope* oldvscp = nodep->varScopep();
		if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
		AstVarScope* dlyvscp = oldvscp->user1p()->castNode()->castVarScope();
		if (dlyvscp) {  // Multiple use of delayed variable
		    AstActive* oldactivep = dlyvscp->user2p()->castNode()->castActive();
		    checkActivePost(nodep, oldactivep);
		}
		if (!dlyvscp) {  // First use of this delayed variable
		    string newvarname = (string("__Vdly__")+nodep->varp()->shortName());
		    dlyvscp = createVarSc(oldvscp, newvarname, 0);
		    AstNodeAssign* prep
			= new AstAssignPre (nodep->fileline(),
					    new AstVarRef(nodep->fileline(), dlyvscp, true),
					    new AstVarRef(nodep->fileline(), oldvscp, false));
		    AstNodeAssign* postp
			= new AstAssignPost (nodep->fileline(),
					     new AstVarRef(nodep->fileline(), oldvscp, true),
					     new AstVarRef(nodep->fileline(), dlyvscp, false));
		    postp->lhsp()->user2(true);	// Don't detect this assignment
		    oldvscp->user1p(dlyvscp);  // So we can find it later
		    // Make new ACTIVE with identical sensitivity tree
		    AstActive* newactp = createActivePost(nodep);
		    dlyvscp->user2p(newactp);
		    newactp->addStmtsp(prep);	// Add to FRONT of statements
		    newactp->addStmtsp(postp);
		}
		AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true);
		newrefp->user2(true);  // No reason to do it again
		nodep->replaceWith(newrefp); nodep->deleteTree(); nodep=NULL;
	    }
	    else if (!m_inDly && nodep->lvalue()) {
		//UINFO(9,"NBA "<<nodep<<endl);
		if (!m_inInitial) {
		    UINFO(4,"AssignNDlyVar: "<<nodep<<endl);
		    markVarUsage(nodep->varScopep(), VU_NONDLY);
		}
	    }
	}
    }
    virtual void visit(AstAlways* nodep, AstNUser*) {
	// Are there any lvalue references below this?
	// There could be more than one.  So, we process the first one found first.
	AstVarScope* lastSplitVscp = NULL;
	while (!nodep->user1()) {
	    // Find any splittable variables
	    SplitAsFindVisitor visitor (nodep);
	    m_splitVscp = visitor.splitVscp();
	    if (m_splitVscp && m_splitVscp == lastSplitVscp) {
		// We did this last time!  Something's stuck!
		nodep->v3fatalSrc("Infinite loop in isolate_assignments removal for: "<<m_splitVscp->prettyName())
		m_splitVscp = NULL;
	    }
	    lastSplitVscp = m_splitVscp;
	    // Now isolate the always
	    if (m_splitVscp) {
		splitAlways(nodep);
		++m_statSplits;
	    } else {
		nodep->user1(true);
	    }
	}
    }
Ejemplo n.º 19
0
void GateVisitor::replaceAssigns() {
    for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
	if (GateVarVertex* vvertexp = dynamic_cast<GateVarVertex*>(itp)) {
	    // Take the Comments/assigns that were moved to the VarScope and change them to a
	    // simple value assignment
	    AstVarScope* vscp = vvertexp->varScp();
	    if (vscp->valuep() && !vscp->valuep()->castNodeMath()) {
		//if (debug()>9) vscp->dumpTree(cout, "-vscPre:  ");
		while (AstNode* delp=vscp->valuep()->castComment()) {
		    delp->unlinkFrBack()->deleteTree(); VL_DANGLING(delp);
		}
		if (AstInitial* delp=vscp->valuep()->castInitial()) {
		    AstNode* bodyp=delp->bodysp();
		    bodyp->unlinkFrBackWithNext();
		    delp->replaceWith(bodyp);
		    delp->deleteTree(); VL_DANGLING(delp);
		}
		if (AstAlways* delp=vscp->valuep()->castAlways()) {
		    AstNode* bodyp=delp->bodysp();
		    bodyp->unlinkFrBackWithNext();
		    delp->replaceWith(bodyp);
		    delp->deleteTree(); VL_DANGLING(delp);
		}
		if (AstNodeAssign* delp=vscp->valuep()->castNodeAssign()) {
		    AstNode* rhsp=delp->rhsp();
		    rhsp->unlinkFrBack();
		    delp->replaceWith(rhsp);
		    delp->deleteTree(); VL_DANGLING(delp);
		}
		//if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<<endl;}
		if (!vscp->valuep()->castNodeMath()
		    || vscp->valuep()->nextp()) {
		    vscp->dumpTree(cerr, "vscStrange: ");
		    vscp->v3fatalSrc("Value of varscope not mathematical\n");
		}
	    }
	}
    }
}
Ejemplo n.º 20
0
    void addIgnore(const char* why) {
	++m_statIgnSigs;
	m_initSubFuncp->addStmtsp(
	    new AstComment(m_traVscp->fileline(), "Tracing: "+m_traShowname+" // Ignored: "+why));
    }