virtual void visit(AstCCall* nodep, AstNUser*) { //UINFO(4," CCALL "<<nodep<<endl); allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_fast) { // Enter the function and trace it nodep->funcp()->accept(*this); } }
virtual void visit(AstVarScope* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_counting) { if (nodep->varp()->dtypeSkipRefp()->castBasicDType()) { m_statVarScpBytes += nodep->varp()->dtypeSkipRefp()->widthTotalBytes(); } } }
virtual void visit(AstVar* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_counting && nodep->dtypep()) { if (nodep->isUsedClock()) ++m_statVarClock; if (nodep->dtypeSkipRefp()->castUnpackArrayDType()) ++m_statVarArray; else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes(); if (int(m_statVarWidths.size()) <= nodep->width()) { m_statVarWidths.resize(nodep->width()+5); } ++ m_statVarWidths.at(nodep->width()); } }
virtual void visit(AstNodeIf* nodep, AstNUser*) { UINFO(4," IF "<<nodep<<endl); allNodes(nodep); // Condition is part of PREVIOUS block nodep->condp()->iterateAndNextConst(*this); // Track prediction if (m_counting) { ++m_statPred[nodep->branchPred()]; } if (!m_fast) { nodep->iterateChildrenConst(*this); } else { // See which path we want to take bool takeElse = false; if (!nodep->elsesp() || (nodep->branchPred()==AstBranchPred::BP_LIKELY)) { // Always take the if } else if (!nodep->ifsp() || (nodep->branchPred()==AstBranchPred::BP_UNLIKELY)) { // Always take the else } else { // Take the longer path bool prevCounting = m_counting; double prevInstr = m_instrs; m_counting = false; // Check if m_instrs = 0; nodep->ifsp()->iterateAndNextConst(*this); double instrIf = m_instrs; // Check else m_instrs = 0; nodep->elsesp()->iterateAndNextConst(*this); double instrElse = m_instrs; // Max of if or else condition takeElse = (instrElse > instrIf); // Restore m_counting = prevCounting; m_instrs = prevInstr + (takeElse?instrElse:instrIf); } // Count the block if (m_counting) { if (takeElse) { nodep->elsesp()->iterateAndNextConst(*this); } else { nodep->ifsp()->iterateAndNextConst(*this); } } } }
// VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { allNodes(nodep); if (!m_fast) { nodep->iterateChildrenConst(*this); } else { for (AstNode* searchp = nodep->stmtsp(); searchp; searchp=searchp->nextp()) { if (AstCFunc* funcp = searchp->castCFunc()) { if (funcp->name() == "_eval") { m_instrs=0; m_counting = true; funcp->iterateChildrenConst(*this); m_counting = false; } } } } }
static void setupIdRenamingHash(const ModelNode &modelNode, QHash<QString, QString> &idRenamingHash, AbstractView *view) { QList<ModelNode> allNodes(modelNode.allSubModelNodes()); allNodes.append(modelNode); foreach (const ModelNode &node, allNodes) { if (!node.id().isEmpty()) { QString newId = node.id(); QString baseId; int number = 1; splitIdInBaseNameAndNumber(newId, &baseId, &number); while (view->hasId(newId) || idRenamingHash.values().contains(newId)) { newId = baseId + QString::number(number); number++; } idRenamingHash.insert(node.id(), newId); } } }
virtual void visit(AstVar* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildrenConst(*this); if (m_counting && nodep->dtypep()) { if (nodep->isUsedClock()) ++m_statVarClock; if (nodep->dtypeSkipRefp()->castUnpackArrayDType()) ++m_statVarArray; else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes(); if (int(m_statVarWidths.size()) <= nodep->width()) { m_statVarWidths.resize(nodep->width()+5); if (v3Global.opt.statsVars()) m_statVarWidthNames.resize(nodep->width()+5); } ++ m_statVarWidths.at(nodep->width()); string pn = nodep->prettyName(); if (v3Global.opt.statsVars()) { NameMap& nameMapr = m_statVarWidthNames.at(nodep->width()); if (nameMapr.find(pn) != nameMapr.end()) { nameMapr[pn]++; } else { nameMapr[pn]=1; } } } }
virtual void visit(AstNode* nodep, AstNUser*) { allNodes(nodep); nodep->iterateChildrenConst(*this); }
virtual void visit(AstCFunc* nodep, AstNUser*) { m_cfuncp = nodep; allNodes(nodep); nodep->iterateChildrenConst(*this); m_cfuncp = NULL; }