Internals: Cleanup cppcheck warnings (#6317)

`make cppcheck-4` is now clean.
This commit is contained in:
Geza Lore 2025-08-20 18:21:24 +01:00 committed by GitHub
parent 3d3462b209
commit 67da797816
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 195 additions and 141 deletions

View File

@ -97,6 +97,7 @@ protected:
result = vertexp->user();
break;
case LatchDetectGraphVertex::VT_BLOCK: // (OR of potentially many siblings)
// cppcheck-suppress constVariableReference
for (V3GraphEdge& edge : vertexp->outEdges()) {
if (latchCheckInternal(castVertexp(edge.top()))) {
result = true;
@ -128,6 +129,7 @@ public:
}
// Clear out userp field of referenced outputs on destruction
// (occurs at the end of each combinational always block)
// cppcheck-suppress duplInheritedMember
void clear() {
m_outputs.clear();
// Calling base class clear will unlink & delete all edges & vertices

View File

@ -114,6 +114,7 @@ private:
const V3TaskConnects tconnects = V3Task::taskConnects(funcrefp, propp->stmtsp());
for (const auto& tconnect : tconnects) {
const AstVar* const portp = tconnect.first;
// cppcheck-suppress constVariablePointer // 'exprp' unlinked below
AstArg* const argp = tconnect.second;
AstNode* const pinp = argp->exprp()->unlinkFrBack();
replaceVarRefsWithExprRecurse(propExprp, portp, pinp);

View File

@ -87,6 +87,7 @@ bool AstNodeFTaskRef::isPure() {
}
bool AstNodeFTaskRef::getPurityRecurse() const {
// cppcheck-suppress shadowFunction
AstNodeFTask* const taskp = this->taskp();
// Unlinked yet, so treat as impure
if (!taskp) return false;
@ -1098,6 +1099,7 @@ std::pair<uint32_t, uint32_t> AstNodeDType::dimensions(bool includeBasic) const
int AstNodeDType::widthPow2() const {
// I.e. width 30 returns 32, width 32 returns 32.
// cppcheck-suppress shadowFunction
const uint32_t width = this->width();
for (int p2 = 30; p2 >= 0; p2--) {
if (width > (1UL << p2)) return (1UL << (p2 + 1));
@ -1374,6 +1376,7 @@ AstBasicDType* AstTypeTable::findLogicBitDType(FileLine* fl, VBasicDTypeKwd kwd,
return newp;
}
// cppcheck-suppress duplInheritedMember
AstBasicDType* AstTypeTable::findInsertSameDType(AstBasicDType* nodep) {
const VBasicTypeKey key{nodep->width(), nodep->widthMin(), nodep->numeric(), nodep->keyword(),
nodep->nrange()};
@ -1462,7 +1465,7 @@ AstVarScope* AstConstPool::findTable(AstInitArray* initp) {
UASSERT_OBJ(VN_IS(valuep, Const), valuep, "Const pool table entry must be Const");
}
// Try to find an existing table with the same content
// cppcheck-has-bug-suppress unreadVariable
// cppcheck-suppress unreadVariable
const V3Hash hash = V3Hasher::uncachedHash(initp);
const auto& er = m_tables.equal_range(hash.value());
for (auto it = er.first; it != er.second; ++it) {
@ -1492,7 +1495,7 @@ static bool sameInit(const AstConst* ap, const AstConst* bp) {
AstVarScope* AstConstPool::findConst(AstConst* initp, bool mergeDType) {
// Try to find an existing constant with the same value
// cppcheck-has-bug-suppress unreadVariable
// cppcheck-suppress unreadVariable
const V3Hash hash = initp->num().toHash();
const auto& er = m_consts.equal_range(hash.value());
for (auto it = er.first; it != er.second; ++it) {

View File

@ -85,6 +85,7 @@ class CastVisitor final : public VNVisitor {
if (!nodep->isNull()) insertCast(nodep, castSize(nodep->backp()));
}
}
// cppcheck-suppress constParameterPointer // lhsp might be changed
void ensureLower32Cast(AstCCast* nodep) {
// If we have uint64 = CAST(uint64(x)) then the upcasting
// really needs to be CAST(uint64(CAST(uint32(x))).

View File

@ -150,6 +150,7 @@ class CombineVisitor final : VNVisitor {
return replaced;
}
// cppcheck-suppress constParameterPointer
void process(AstNetlist* netlistp) {
// First, remove empty functions. We need to do this separately, because removing
// calls can change the hashes of the callers.

View File

@ -1058,7 +1058,7 @@ class ConstVisitor final : public VNVisitor {
// Someday we'll sort the biops completely and this can be simplified
// This often results from our simplified clock generation:
// if (rst) ... else if (enable)... -> OR(rst,AND(!rst,enable))
AstNodeExpr* ap;
const AstNodeExpr* ap;
AstNodeBiop* andp;
if (VN_IS(nodep->lhsp(), And)) {
andp = VN_AS(nodep->lhsp(), And);
@ -1080,7 +1080,7 @@ class ConstVisitor final : public VNVisitor {
} else {
return false;
}
AstNodeExpr* const bp = notp->lhsp();
const AstNodeExpr* const bp = notp->lhsp();
if (!operandsSame(ap, bp)) return false;
// Do it
cp->unlinkFrBack();
@ -1099,6 +1099,7 @@ class ConstVisitor final : public VNVisitor {
// (otherwise we'd be trading one operation for two operations)
// V3Clean often makes this pattern, as it postpones the AND until
// as high as possible, which is usually the right choice, except for this.
// cppcheck-suppress constVariablePointer // children unlinked below
AstCond* const condp = VN_CAST(nodep->rhsp(), Cond);
if (!condp) return false;
if (!VN_IS(condp->thenp(), Const) && !VN_IS(condp->elsep(), Const)) return false;
@ -1322,6 +1323,7 @@ class ConstVisitor final : public VNVisitor {
// A pattern created by []'s after offsets have been removed
// SEL(EXTEND(any,width,...),(width-1),0) -> ...
// Since select's return unsigned, this is always an extend
// cppcheck-suppress constVariablePointer // children unlinked below
AstExtend* const extendp = VN_CAST(nodep->fromp(), Extend);
if (!(m_doV && extendp && VN_IS(nodep->lsbp(), Const) && nodep->lsbConst() == 0
&& static_cast<int>(nodep->widthConst()) == extendp->lhsp()->width()))
@ -1347,7 +1349,7 @@ class ConstVisitor final : public VNVisitor {
// AND({a}, SHIFTR({b}, {c})) is often shorthand in C for Verilog {b}[{c} :+ {a}]
// becomes thought other optimizations
// SEL(SHIFTR({a},{b}),{lsb},{width}) -> SEL({a},{lsb+b},{width})
AstShiftR* const shiftp = VN_CAST(nodep->fromp(), ShiftR);
const AstShiftR* const shiftp = VN_CAST(nodep->fromp(), ShiftR);
if (!(m_doV && shiftp && VN_IS(shiftp->rhsp(), Const) && VN_IS(nodep->lsbp(), Const))) {
return false;
}
@ -2005,21 +2007,22 @@ class ConstVisitor final : public VNVisitor {
// Skip if we're not const'ing an entire module (IE doing only one assign, etc)
if (!m_modp) return false;
// cppcheck-suppress constVariablePointer // children unlinked below
AstSel* const sel1p = VN_CAST(nodep->lhsp(), Sel);
if (!sel1p) return false;
AstNodeAssign* const nextp = VN_CAST(nodep->nextp(), NodeAssign);
if (!nextp) return false;
if (nodep->type() != nextp->type()) return false;
AstSel* const sel2p = VN_CAST(nextp->lhsp(), Sel);
const AstSel* const sel2p = VN_CAST(nextp->lhsp(), Sel);
if (!sel2p) return false;
AstVarRef* const varref1p = VN_CAST(sel1p->fromp(), VarRef);
if (!varref1p) return false;
AstVarRef* const varref2p = VN_CAST(sel2p->fromp(), VarRef);
const AstVarRef* const varref2p = VN_CAST(sel2p->fromp(), VarRef);
if (!varref2p) return false;
if (!varref1p->sameGateTree(varref2p)) return false;
AstConst* const con1p = VN_CAST(sel1p->lsbp(), Const);
const AstConst* const con1p = VN_CAST(sel1p->lsbp(), Const);
if (!con1p) return false;
AstConst* const con2p = VN_CAST(sel2p->lsbp(), Const);
const AstConst* const con2p = VN_CAST(sel2p->lsbp(), Const);
if (!con2p) return false;
// We need to make sure there's no self-references involved in either
// assignment. For speed, we only look 3 deep, then give up.
@ -2600,6 +2603,7 @@ class ConstVisitor final : public VNVisitor {
void replaceSelSel(AstSel* nodep) {
// SEL(SEL({x},a,b),c,d) => SEL({x},a+c,d)
// cppcheck-suppress constVariablePointer // children unlinked below
AstSel* const belowp = VN_AS(nodep->fromp(), Sel);
AstNodeExpr* const fromp = belowp->fromp()->unlinkFrBack();
AstNodeExpr* const lsb1p = nodep->lsbp()->unlinkFrBack();
@ -2667,9 +2671,10 @@ class ConstVisitor final : public VNVisitor {
bool operandSelReplicate(AstSel* nodep) {
// SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long
// as SEL's width <= b's width
// cppcheck-suppress constVariablePointer // children unlinked below
AstReplicate* const repp = VN_AS(nodep->fromp(), Replicate);
AstNodeExpr* const fromp = repp->srcp();
AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const);
const AstConst* const lsbp = VN_CAST(nodep->lsbp(), Const);
if (!lsbp) return false;
UASSERT_OBJ(fromp->width(), nodep, "Not widthed");
if ((lsbp->toUInt() / fromp->width())
@ -2687,6 +2692,7 @@ class ConstVisitor final : public VNVisitor {
}
bool operandRepRep(AstReplicate* nodep) {
// REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2))
// cppcheck-suppress constVariablePointer // children unlinked below
AstReplicate* const rep2p = VN_AS(nodep->srcp(), Replicate);
AstNodeExpr* const from2p = rep2p->srcp();
AstConst* const cnt1p = VN_CAST(nodep->countp(), Const);
@ -2713,13 +2719,13 @@ class ConstVisitor final : public VNVisitor {
AstNodeExpr* from2p = nodep->rhsp();
uint32_t cnt2 = 1;
if (VN_IS(from1p, Replicate)) {
AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->countp(), Const);
const AstConst* const cnt1p = VN_CAST(VN_CAST(from1p, Replicate)->countp(), Const);
if (!cnt1p) return false;
from1p = VN_AS(from1p, Replicate)->srcp();
cnt1 = cnt1p->toUInt();
}
if (VN_IS(from2p, Replicate)) {
AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->countp(), Const);
const AstConst* const cnt2p = VN_CAST(VN_CAST(from2p, Replicate)->countp(), Const);
if (!cnt2p) return false;
from2p = VN_AS(from2p, Replicate)->srcp();
cnt2 = cnt2p->toUInt();
@ -2826,9 +2832,9 @@ class ConstVisitor final : public VNVisitor {
VL_DO_DANGLING(replaceNum(nodep, num), nodep);
did = true;
} else if (m_selp && VN_IS(valuep, InitArray)) {
AstInitArray* const initarp = VN_AS(valuep, InitArray);
const AstInitArray* const initarp = VN_AS(valuep, InitArray);
const uint32_t bit = m_selp->bitConst();
AstNode* const itemp = initarp->getIndexDefaultedValuep(bit);
const AstNode* const itemp = initarp->getIndexDefaultedValuep(bit);
if (VN_IS(itemp, Const)) {
const V3Number& num = VN_AS(itemp, Const)->num();
// UINFO(2, "constVisit " << cvtToHex(valuep) << " " << num);
@ -3060,8 +3066,8 @@ class ConstVisitor final : public VNVisitor {
if (!nextp) break;
AstSenItem* const lItemp = senp;
AstSenItem* const rItemp = nextp;
AstNodeExpr* const lSenp = lItemp->sensp();
AstNodeExpr* const rSenp = rItemp->sensp();
const AstNodeExpr* const lSenp = lItemp->sensp();
const AstNodeExpr* const rSenp = rItemp->sensp();
if (!lSenp || !rSenp) continue;
if (lSenp->sameGateTree(rSenp)) {
@ -3085,8 +3091,8 @@ class ConstVisitor final : public VNVisitor {
// Not identical terms, check if they can be combined
if (lSenp->width() != rSenp->width()) continue;
if (AstAnd* const lAndp = VN_CAST(lSenp, And)) {
if (AstAnd* const rAndp = VN_CAST(rSenp, And)) {
if (const AstAnd* const lAndp = VN_CAST(lSenp, And)) {
if (const AstAnd* const rAndp = VN_CAST(rSenp, And)) {
if (AstConst* const lConstp = VN_CAST(lAndp->lhsp(), Const)) {
if (AstConst* const rConstp = VN_CAST(rAndp->lhsp(), Const)) {
if (lAndp->rhsp()->sameTree(rAndp->rhsp())) {
@ -3204,6 +3210,7 @@ class ConstVisitor final : public VNVisitor {
}
}
void visit(AstRelease* nodep) override {
// cppcheck-suppress constVariablePointer // children unlinked below
if (AstConcat* const concatp = VN_CAST(nodep->lhsp(), Concat)) {
FileLine* const flp = nodep->fileline();
AstRelease* const newLp = new AstRelease{flp, concatp->lhsp()->unlinkFrBack()};
@ -3282,6 +3289,7 @@ class ConstVisitor final : public VNVisitor {
UINFO(4,
"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})");
AstNodeAssign* const thensp = VN_AS(nodep->thensp(), NodeAssign);
// cppcheck-suppress constVariablePointer // children unlinked below
AstNodeAssign* const elsesp = VN_AS(nodep->elsesp(), NodeAssign);
thensp->unlinkFrBack();
AstNodeExpr* const condp = nodep->condp()->unlinkFrBack();
@ -3330,6 +3338,7 @@ class ConstVisitor final : public VNVisitor {
if (!prevp->fmtp() || prevp->fmtp()->nextp() || !nodep->fmtp() || nodep->fmtp()->nextp())
return false;
AstSFormatF* const pformatp = prevp->fmtp();
// cppcheck-suppress constVariablePointer // children unlinked below
AstSFormatF* const nformatp = nodep->fmtp();
// We don't merge scopeNames as can have only one and might be different scopes (late in
// process) Also rare for real code to print %m multiple times in same message
@ -3979,6 +3988,7 @@ void V3Const::constifyParamsEdit(AstNode* nodep) {
// Make sure we've sized everything first
nodep = V3Width::widthParamsEdit(nodep);
ConstVisitor visitor{ConstVisitor::PROC_PARAMS, /* globalPass: */ false};
// cppcheck-suppress constVariablePointer // edited below
if (AstVar* const varp = VN_CAST(nodep, Var)) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the
@ -4000,6 +4010,7 @@ void V3Const::constifyParamsNoWarnEdit(AstNode* nodep) {
// Make sure we've sized everything first
nodep = V3Width::widthParamsEdit(nodep);
ConstVisitor visitor{ConstVisitor::PROC_PARAMS_NOWARN, /* globalPass: */ false};
// cppcheck-suppress constVariablePointer // edited below
if (AstVar* const varp = VN_CAST(nodep, Var)) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the
@ -4029,6 +4040,7 @@ AstNode* V3Const::constifyGenerateParamsEdit(AstNode* nodep) {
// Make sure we've sized everything first
nodep = V3Width::widthGenerateParamsEdit(nodep);
ConstVisitor visitor{ConstVisitor::PROC_GENERATE, /* globalPass: */ false};
// cppcheck-suppress constVariablePointer // edited below
if (AstVar* const varp = VN_CAST(nodep, Var)) {
// If a var wants to be constified, it's really a param, and
// we want the value to be constant. We aren't passed just the

View File

@ -85,6 +85,7 @@ class DeadVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
}
// cppcheck-suppress constParameterPointer
void checkAll(AstNode* nodep) {
if (AstNode* const subnodep = nodep->dtypep()) {
if (nodep != subnodep // Not NodeDTypes reference themselves
@ -473,7 +474,9 @@ class DeadVisitor final : public VNVisitor {
}
}
// cppcheck-suppress constParameterPointer
void preserveTopIfaces(AstNetlist* rootp) {
// cppcheck-suppress constVariablePointer
for (AstNodeModule* modp = rootp->modulesp(); modp && modp->level() <= 2;
modp = VN_AS(modp->nextp(), NodeModule)) {
for (AstNode* subnodep = modp->stmtsp(); subnodep; subnodep = subnodep->nextp()) {

View File

@ -220,6 +220,7 @@ class DelayedVisitor final : public VNVisitor {
// Remove duplicates
V3Const::constifyExpensiveEdit(m_senTreep);
}
// cppcheck-suppress constParameterPointer
void addSensitivity(AstSenTree* nodep) { addSensitivity(nodep->sensesp()); }
};
@ -1126,7 +1127,7 @@ class DelayedVisitor final : public VNVisitor {
// First gather all senItems
AstSenItem* senItemp = nullptr;
for (AstSenTree* const domainp : m_timingDomains) {
for (const AstSenTree* const domainp : m_timingDomains) {
if (domainp->sensesp())
senItemp = AstNode::addNext(senItemp, domainp->sensesp()->cloneTree(true));
}
@ -1216,6 +1217,7 @@ class DelayedVisitor final : public VNVisitor {
VL_RESTORER(m_currNbaLhsRefp);
UASSERT_OBJ(!m_currNbaLhsRefp, nodep, "NBAs should not nest");
nodep->lhsp()->foreach([&](AstNode* currp) {
// cppcheck-suppress constVariablePointer
if (AstExprStmt* const exprp = VN_CAST(currp, ExprStmt)) {
// Move statements before the NBA
nodep->addHereThisAsNext(exprp->stmtsp()->unlinkFrBackWithNext());

View File

@ -134,7 +134,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
// Hook up inputs of cloned variables
for (const DfgVertexVar& vtx : m_varVertices) {
// All variable vertices are unary
if (DfgVertex* const srcp = vtx.srcp()) {
if (const DfgVertex* const srcp = vtx.srcp()) {
vtxp2clonep.at(&vtx)->as<DfgVertexVar>()->srcp(vtxp2clonep.at(srcp));
}
}
@ -146,7 +146,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
const DfgSpliceArray* const vp = vtx.as<DfgSpliceArray>();
DfgSpliceArray* const cp = vtxp2clonep.at(vp)->as<DfgSpliceArray>();
vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) {
if (DfgVertex* const srcp = edge.sourcep()) {
if (const DfgVertex* const srcp = edge.sourcep()) {
cp->addDriver(vp->driverFileLine(i), //
vp->driverLo(i), //
vtxp2clonep.at(srcp));
@ -158,7 +158,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
const DfgSplicePacked* const vp = vtx.as<DfgSplicePacked>();
DfgSplicePacked* const cp = vtxp2clonep.at(vp)->as<DfgSplicePacked>();
vp->forEachSourceEdge([&](const DfgEdge& edge, size_t i) {
if (DfgVertex* const srcVp = edge.sourcep()) {
if (const DfgVertex* const srcVp = edge.sourcep()) {
DfgVertex* const srcCp = vtxp2clonep.at(srcVp);
UASSERT_OBJ(!srcCp->is<DfgLogic>(), srcCp, "Cannot clone DfgLogic");
if (srcVp == vp->defaultp()) {
@ -183,7 +183,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
UASSERT_OBJ(oSourceEdges.second == cSourceEdges.second, &vtx,
"Mismatched source count");
for (size_t i = 0; i < oSourceEdges.second; ++i) {
if (DfgVertex* const srcp = oSourceEdges.first[i].sourcep()) {
if (const DfgVertex* const srcp = oSourceEdges.first[i].sourcep()) {
cSourceEdges.first[i].relinkSource(vtxp2clonep.at(srcp));
}
}
@ -244,11 +244,11 @@ std::string DfgGraph::makeUniqueName(const std::string& prefix, size_t n) {
// Construct the tmpNameStub if we have not done so yet
if (m_tmpNameStub.empty()) {
// Use the hash of the graph name (avoid long names and non-identifiers)
const std::string name = V3Hash{m_name}.toString();
const std::string hash = V3Hash{m_name}.toString();
// We need to keep every variable globally unique, and graph hashed
// names might not be, so keep a static table to track multiplicity
static std::unordered_map<std::string, uint32_t> s_multiplicity;
m_tmpNameStub += '_' + name + '_' + std::to_string(s_multiplicity[name]++) + '_';
m_tmpNameStub += '_' + hash + '_' + std::to_string(s_multiplicity[hash]++) + '_';
}
// Assemble the globally unique name
return "__Vdfg" + prefix + m_tmpNameStub + std::to_string(n);
@ -287,12 +287,12 @@ static const std::string toDotId(const DfgVertex& vtx) { return '"' + cvtToHex(&
static void dumpDotVertex(std::ostream& os, const DfgVertex& vtx) {
if (const DfgVarPacked* const varVtxp = vtx.cast<DfgVarPacked>()) {
AstNode* const nodep = varVtxp->nodep();
AstVar* const varp = varVtxp->varp();
const AstNode* const nodep = varVtxp->nodep();
const AstVar* const varp = varVtxp->varp();
os << toDotId(vtx);
os << " [label=\"" << nodep->prettyName() << '\n';
os << cvtToHex(varVtxp) << '\n';
if (AstNode* const tmpForp = varVtxp->tmpForp()) {
if (const AstNode* const tmpForp = varVtxp->tmpForp()) {
os << "temporary for: " << tmpForp->prettyName() << "\n";
}
varVtxp->dtypep()->dumpSmall(os);
@ -320,12 +320,12 @@ static void dumpDotVertex(std::ostream& os, const DfgVertex& vtx) {
}
if (const DfgVarArray* const arrVtxp = vtx.cast<DfgVarArray>()) {
AstNode* const nodep = arrVtxp->nodep();
AstVar* const varp = arrVtxp->varp();
const AstNode* const nodep = arrVtxp->nodep();
const AstVar* const varp = arrVtxp->varp();
os << toDotId(vtx);
os << " [label=\"" << nodep->prettyName() << '\n';
os << cvtToHex(arrVtxp) << '\n';
if (AstNode* const tmpForp = arrVtxp->tmpForp()) {
if (const AstNode* const tmpForp = arrVtxp->tmpForp()) {
os << "temporary for: " << tmpForp->prettyName() << "\n";
}
arrVtxp->dtypep()->dumpSmall(os);
@ -512,11 +512,12 @@ void DfgGraph::dumpDotFilePrefixed(const std::string& label,
template <bool T_SinksNotSources>
static std::unique_ptr<std::unordered_set<const DfgVertex*>>
dfgGraphCollectCone(const std::vector<const DfgVertex*> vtxps) {
dfgGraphCollectCone(const std::vector<const DfgVertex*>& vtxps) {
// Work queue for traversal starting from all the seed vertices
std::vector<const DfgVertex*> queue = vtxps;
// Set of already visited vertices
std::unordered_set<const DfgVertex*>* const resp = new std::unordered_set<const DfgVertex*>{};
std::unique_ptr<std::unordered_set<const DfgVertex*>> resp{
new std::unordered_set<const DfgVertex*>{}};
// Depth first traversal
while (!queue.empty()) {
// Pop next work item
@ -532,16 +533,16 @@ dfgGraphCollectCone(const std::vector<const DfgVertex*> vtxps) {
}
}
// Done
return std::unique_ptr<std::unordered_set<const DfgVertex*>>{resp};
return resp;
}
std::unique_ptr<std::unordered_set<const DfgVertex*>>
DfgGraph::sourceCone(const std::vector<const DfgVertex*> vtxps) const {
DfgGraph::sourceCone(const std::vector<const DfgVertex*>& vtxps) const {
return dfgGraphCollectCone<false>(vtxps);
}
std::unique_ptr<std::unordered_set<const DfgVertex*>>
DfgGraph::sinkCone(const std::vector<const DfgVertex*> vtxps) const {
DfgGraph::sinkCone(const std::vector<const DfgVertex*>& vtxps) const {
return dfgGraphCollectCone<true>(vtxps);
}
@ -578,12 +579,12 @@ void DfgEdge::unlinkSource() {
if (!m_sourcep) return;
#ifdef VL_DEBUG
{
DfgEdge* sinkp = m_sourcep->m_sinksp;
while (sinkp) {
if (sinkp == this) break;
sinkp = sinkp->m_nextp;
DfgEdge* currp = m_sourcep->m_sinksp;
while (currp) {
if (currp == this) break;
currp = currp->m_nextp;
}
UASSERT(sinkp, "'m_sourcep' does not have this edge as sink");
UASSERT(currp, "'m_sourcep' does not have this edge as sink");
}
#endif
// Relink pointers of predecessor and successor
@ -677,7 +678,7 @@ V3Hash DfgVertex::hash() {
// variables, which we rely on.
if (!is<DfgVertexVar>()) {
hash += m_type;
if (AstUnpackArrayDType* const adtypep = VN_CAST(dtypep(), UnpackArrayDType)) {
if (const AstUnpackArrayDType* const adtypep = VN_CAST(dtypep(), UnpackArrayDType)) {
hash += adtypep->elementsConst();
// TODO: maybe include sub-dtype, but not hugely important at the moment
} else {
@ -685,9 +686,9 @@ V3Hash DfgVertex::hash() {
}
const auto pair = sourceEdges();
const DfgEdge* const edgesp = pair.first;
const size_t arity = pair.second;
const size_t nEdges = pair.second;
// Sources must always be connected in well-formed graphs
for (size_t i = 0; i < arity; ++i) hash += edgesp[i].m_sourcep->hash();
for (size_t i = 0; i < nEdges; ++i) hash += edgesp[i].m_sourcep->hash();
}
result = hash;
}
@ -758,11 +759,15 @@ DfgVertexVar* DfgVertex::getResultVar() {
AstScope* DfgVertex::scopep(ScopeCache& cache, bool tryResultVar) VL_MT_DISABLED {
// If this is a variable, we are done
if (DfgVertexVar* const varp = this->cast<DfgVertexVar>()) return varp->varScopep()->scopep();
if (const DfgVertexVar* const varp = this->cast<DfgVertexVar>()) {
return varp->varScopep()->scopep();
}
// Try the result var first if instructed (usully only in the recursive case)
if (tryResultVar) {
if (DfgVertexVar* const varp = this->getResultVar()) return varp->varScopep()->scopep();
if (const DfgVertexVar* const varp = this->getResultVar()) {
return varp->varScopep()->scopep();
}
}
// Note: the recursive invocation can cause a re-hash but that will not invalidate references
@ -775,7 +780,7 @@ AstScope* DfgVertex::scopep(ScopeCache& cache, bool tryResultVar) VL_MT_DISABLED
AstScope* foundp = rootp;
const auto edges = sourceEdges();
for (size_t i = 0; i < edges.second; ++i) {
DfgEdge& edge = edges.first[i];
const DfgEdge& edge = edges.first[i];
foundp = edge.sourcep()->scopep(cache, true);
if (foundp != rootp) break;
}

View File

@ -705,7 +705,8 @@ public:
// Split this graph into individual components (unique sub-graphs with no edges between them).
// Also removes any vertices that are not weakly connected to any variable.
// Leaves 'this' graph empty.
std::vector<std::unique_ptr<DfgGraph>> splitIntoComponents(std::string label) VL_MT_DISABLED;
std::vector<std::unique_ptr<DfgGraph>>
splitIntoComponents(const std::string& label) VL_MT_DISABLED;
// Extract cyclic sub-graphs from 'this' graph. Cyclic sub-graphs are those that contain at
// least one strongly connected component (SCC) plus any other vertices that feed or sink from
@ -716,7 +717,7 @@ public:
// to be a DAG (acyclic). 'this' will not necessarily be a connected graph at the end, even if
// it was originally connected.
std::vector<std::unique_ptr<DfgGraph>>
extractCyclicComponents(std::string label) VL_MT_DISABLED;
extractCyclicComponents(const std::string& label) VL_MT_DISABLED;
//-----------------------------------------------------------------------
// Debug dumping
@ -742,10 +743,10 @@ public:
// Returns the set of vertices in the upstream cones of the given vertices
std::unique_ptr<std::unordered_set<const DfgVertex*>>
sourceCone(const std::vector<const DfgVertex*>) const VL_MT_DISABLED;
sourceCone(const std::vector<const DfgVertex*>&) const VL_MT_DISABLED;
// Returns the set of vertices in the downstream cones of the given vertices
std::unique_ptr<std::unordered_set<const DfgVertex*>>
sinkCone(const std::vector<const DfgVertex*>) const VL_MT_DISABLED;
sinkCone(const std::vector<const DfgVertex*>&) const VL_MT_DISABLED;
//-----------------------------------------------------------------------
// Static methods for data types
@ -824,9 +825,7 @@ T& DfgVertex::user() {
UDEBUGONLY(UASSERT_OBJ(userCurrent, this, "DfgVertex user data used without reserving"););
if (m_userCnt != userCurrent) {
m_userCnt = userCurrent;
// cppcheck-has-bug-suppress uninitvar
VL_ATTR_UNUSED T* const resultp = new (storagep) T{};
UDEBUGONLY(UASSERT_OBJ(resultp == storagep, this, "Something is odd"););
new (storagep) T{};
}
return *storagep;
}
@ -864,8 +863,8 @@ void DfgVertex::setUser(T value) {
void DfgVertex::forEachSource(std::function<void(DfgVertex&)> f) {
const auto pair = sourceEdges();
const DfgEdge* const edgesp = pair.first;
const size_t arity = pair.second;
for (size_t i = 0; i < arity; ++i) {
const size_t nEdges = pair.second;
for (size_t i = 0; i < nEdges; ++i) {
if (DfgVertex* const sourcep = edgesp[i].m_sourcep) f(*sourcep);
}
}
@ -873,8 +872,8 @@ void DfgVertex::forEachSource(std::function<void(DfgVertex&)> f) {
void DfgVertex::forEachSource(std::function<void(const DfgVertex&)> f) const {
const auto pair = sourceEdges();
const DfgEdge* const edgesp = pair.first;
const size_t arity = pair.second;
for (size_t i = 0; i < arity; ++i) {
const size_t nEdges = pair.second;
for (size_t i = 0; i < nEdges; ++i) {
if (DfgVertex* const sourcep = edgesp[i].m_sourcep) f(*sourcep);
}
}
@ -893,15 +892,15 @@ void DfgVertex::forEachSink(std::function<void(const DfgVertex&)> f) const {
void DfgVertex::forEachSourceEdge(std::function<void(DfgEdge&, size_t)> f) {
const auto pair = sourceEdges();
DfgEdge* const edgesp = pair.first;
const size_t arity = pair.second;
for (size_t i = 0; i < arity; ++i) f(edgesp[i], i);
const size_t nEdges = pair.second;
for (size_t i = 0; i < nEdges; ++i) f(edgesp[i], i);
}
void DfgVertex::forEachSourceEdge(std::function<void(const DfgEdge&, size_t)> f) const {
const auto pair = sourceEdges();
const DfgEdge* const edgesp = pair.first;
const size_t arity = pair.second;
for (size_t i = 0; i < arity; ++i) f(edgesp[i], i);
const size_t nEdges = pair.second;
for (size_t i = 0; i < nEdges; ++i) f(edgesp[i], i);
}
void DfgVertex::forEachSinkEdge(std::function<void(DfgEdge&)> f) {
@ -921,8 +920,8 @@ void DfgVertex::forEachSinkEdge(std::function<void(const DfgEdge&)> f) const {
const DfgEdge* DfgVertex::findSourceEdge(std::function<bool(const DfgEdge&, size_t)> p) const {
const auto pair = sourceEdges();
const DfgEdge* const edgesp = pair.first;
const size_t arity = pair.second;
for (size_t i = 0; i < arity; ++i) {
const size_t nEdges = pair.second;
for (size_t i = 0; i < nEdges; ++i) {
const DfgEdge& edge = edgesp[i];
if (p(edge, i)) return &edge;
}
@ -979,8 +978,8 @@ DfgVertex* DfgVertexSplice::wholep() const {
if (driverLo(0) != 0) return nullptr;
DfgVertex* const srcp = DfgVertexVariadic::source(1);
if (srcp->size() != size()) return nullptr;
if (DfgUnitArray* const uap = srcp->cast<DfgUnitArray>()) {
if (DfgVertexSplice* sp = uap->srcp()->cast<DfgVertexSplice>()) {
if (const DfgUnitArray* const uap = srcp->cast<DfgUnitArray>()) {
if (const DfgVertexSplice* sp = uap->srcp()->cast<DfgVertexSplice>()) {
if (!sp->wholep()) return nullptr;
}
}
@ -1014,6 +1013,7 @@ DfgVertexVar::DfgVertexVar(DfgGraph& dfg, VDfgType type, AstVarScope* vscp)
DfgVertexVar::~DfgVertexVar() {
// Decrement reference count
// cppcheck-suppress shadowFunction
AstNode* const nodep = this->nodep();
nodep->user1(nodep->user1() - 0x10);
UASSERT_OBJ((nodep->user1() >> 4) >= 0, nodep, "Reference count underflow");

View File

@ -46,7 +46,8 @@ class TraceDriver final : public DfgVisitor {
struct Hash final {
size_t operator()(const Visited& item) const {
V3Hash hash{reinterpret_cast<uintptr_t>(item.m_vtxp)};
// cppcheck-suppress unreadVariable
V3Hash hash{item.m_vtxp};
hash += item.m_lsb;
hash += item.m_msb;
return hash.value();
@ -244,7 +245,7 @@ class TraceDriver final : public DfgVisitor {
// Somewhat rudimentary but sufficient for current purposes.
static bool knownToBeZeroAtAndAbove(const DfgVertex* vtxp, uint32_t idx) {
if (const DfgConcat* const catp = vtxp->cast<DfgConcat>()) {
DfgConst* const lConstp = catp->lhsp()->cast<DfgConst>();
const DfgConst* const lConstp = catp->lhsp()->cast<DfgConst>();
return lConstp && idx >= catp->rhsp()->width() && lConstp->isZero();
}
if (const DfgExtend* const extp = vtxp->cast<DfgExtend>()) {
@ -256,7 +257,7 @@ class TraceDriver final : public DfgVisitor {
// Like knownToBeZeroAtAndAbove, but checks vtxp[idx:0]
static bool knownToBeZeroAtAndBelow(const DfgVertex* vtxp, uint32_t idx) {
if (const DfgConcat* const catp = vtxp->cast<DfgConcat>()) {
DfgConst* const rConstp = catp->rhsp()->cast<DfgConst>();
const DfgConst* const rConstp = catp->rhsp()->cast<DfgConst>();
return rConstp && idx < rConstp->width() && rConstp->isZero();
}
return false;
@ -381,10 +382,10 @@ class TraceDriver final : public DfgVisitor {
void visit(DfgArraySel* vtxp) override {
// Only constant select
DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>();
const DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>();
if (!idxp) return;
// From a variable
DfgVarArray* varp = vtxp->fromp()->cast<DfgVarArray>();
const DfgVarArray* varp = vtxp->fromp()->cast<DfgVarArray>();
if (!varp) return;
// Skip through intermediate variables
while (varp->srcp() && varp->srcp()->is<DfgVarArray>()) {
@ -394,10 +395,10 @@ class TraceDriver final : public DfgVisitor {
if (!varp->srcp()) return;
// Driver might be a splice
if (DfgSpliceArray* const splicep = varp->srcp()->cast<DfgSpliceArray>()) {
DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT());
if (const DfgSpliceArray* const splicep = varp->srcp()->cast<DfgSpliceArray>()) {
const DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT());
if (!driverp) return;
DfgUnitArray* const uap = driverp->cast<DfgUnitArray>();
const DfgUnitArray* const uap = driverp->cast<DfgUnitArray>();
if (!uap) return;
// Trace the driver
SET_RESULT(trace(uap->srcp(), m_msb, m_lsb));
@ -405,7 +406,7 @@ class TraceDriver final : public DfgVisitor {
}
// Or a unit array
DfgUnitArray* const uap = varp->srcp()->cast<DfgUnitArray>();
const DfgUnitArray* const uap = varp->srcp()->cast<DfgUnitArray>();
if (!uap) return;
// Trace the driver
UASSERT_OBJ(idxp->toSizeT() == 0, vtxp, "Array Index out of range");
@ -523,7 +524,7 @@ class TraceDriver final : public DfgVisitor {
void visit(DfgShiftR* vtxp) override {
DfgVertex* const lhsp = vtxp->lhsp();
if (DfgConst* const rConstp = vtxp->rhsp()->cast<DfgConst>()) {
if (const DfgConst* const rConstp = vtxp->rhsp()->cast<DfgConst>()) {
const uint32_t shiftAmnt = rConstp->toU32();
// Width of lower half of result
const uint32_t lowerWidth = shiftAmnt > vtxp->width() ? 0 : vtxp->width() - shiftAmnt;
@ -558,7 +559,7 @@ class TraceDriver final : public DfgVisitor {
void visit(DfgShiftL* vtxp) override {
DfgVertex* const lhsp = vtxp->lhsp();
if (DfgConst* const rConstp = vtxp->rhsp()->cast<DfgConst>()) {
if (const DfgConst* const rConstp = vtxp->rhsp()->cast<DfgConst>()) {
const uint32_t shiftAmnt = rConstp->toU32();
// Width of lower half of result
const uint32_t lowerWidth = shiftAmnt > vtxp->width() ? vtxp->width() : shiftAmnt;
@ -642,13 +643,13 @@ public:
// partial trace succeded, but an eventual one falied). Because new
// vertices should be created depth first, it is enough to do a single
// reverse pass over the collectoin
for (DfgVertex* const vtxp : vlstd::reverse_view(traceDriver.m_newVtxps)) {
for (DfgVertex* const newp : vlstd::reverse_view(traceDriver.m_newVtxps)) {
// Keep the actual result!
if (vtxp == resultp) continue;
if (newp == resultp) continue;
// Keep used ones!
if (vtxp->hasSinks()) continue;
if (newp->hasSinks()) continue;
// Delete it
VL_DO_DANGLING(vtxp->unlinkDelete(dfg), vtxp);
VL_DO_DANGLING(newp->unlinkDelete(dfg), newp);
}
// Return the result
return resultp;
@ -733,10 +734,10 @@ class IndependentBits final : public DfgVisitor {
void visit(DfgArraySel* vtxp) override {
// Only constant select
DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>();
const DfgConst* const idxp = vtxp->bitp()->cast<DfgConst>();
if (!idxp) return;
// From a variable
DfgVarArray* varp = vtxp->fromp()->cast<DfgVarArray>();
const DfgVarArray* varp = vtxp->fromp()->cast<DfgVarArray>();
if (!varp) return;
// Skip through intermediate variables
while (varp->srcp() && varp->srcp()->is<DfgVarArray>()) {
@ -744,11 +745,11 @@ class IndependentBits final : public DfgVisitor {
}
// Find driver
if (!varp->srcp()) return;
DfgSpliceArray* const splicep = varp->srcp()->cast<DfgSpliceArray>();
const DfgSpliceArray* const splicep = varp->srcp()->cast<DfgSpliceArray>();
if (!splicep) return;
DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT());
const DfgVertex* const driverp = splicep->driverAt(idxp->toSizeT());
if (!driverp) return;
DfgUnitArray* const uap = driverp->cast<DfgUnitArray>();
const DfgUnitArray* const uap = driverp->cast<DfgUnitArray>();
if (!uap) return;
// Update mask
MASK(vtxp) = MASK(uap->srcp());
@ -1046,7 +1047,7 @@ class FixUpIndependentRanges final {
V3Number result{vtxp->fileline(), static_cast<int>(vtxp->width()), 0};
vtxp->forEachSink([&result](DfgVertex& sink) {
// If used via a Sel, mark the selected bits used
if (DfgSel* const selp = sink.cast<DfgSel>()) {
if (const DfgSel* const selp = sink.cast<DfgSel>()) {
uint32_t lsb = selp->lsb();
uint32_t msb = lsb + selp->width() - 1;
for (uint32_t i = lsb; i <= msb; ++i) result.setBit(i, '1');
@ -1058,12 +1059,12 @@ class FixUpIndependentRanges final {
return result;
}
static std::string debugStr(DfgVertex* vtxp) {
if (DfgArraySel* const aselp = vtxp->cast<DfgArraySel>()) {
static std::string debugStr(const DfgVertex* vtxp) {
if (const DfgArraySel* const aselp = vtxp->cast<DfgArraySel>()) {
const size_t i = aselp->bitp()->as<DfgConst>()->toSizeT();
return debugStr(aselp->fromp()) + "[" + std::to_string(i) + "]";
}
if (DfgVertexVar* const varp = vtxp->cast<DfgVertexVar>()) {
if (const DfgVertexVar* const varp = vtxp->cast<DfgVertexVar>()) {
return varp->nodep()->name();
}
vtxp->v3fatalSrc("Unhandled node type"); // LCOV_EXCL_LINE
@ -1165,7 +1166,7 @@ class FixUpIndependentRanges final {
// If no imporovement was possible, delete the terms we just created
if (!nImprovements) {
for (DfgVertex* const vtxp : termps) VL_DO_DANGLING(vtxp->unlinkDelete(dfg), vtxp);
for (DfgVertex* const termp : termps) VL_DO_DANGLING(termp->unlinkDelete(dfg), termp);
termps.clear();
return 0;
}

View File

@ -282,22 +282,22 @@ inline void cache(CacheTernary& cache, DfgVertexTernary* vtxp) {
}
// These remove an existing vertex from the cache, if it is the cached vertex
inline void invalidateByValue(CacheSel& cache, DfgSel* vtxp) {
inline void invalidateByValue(CacheSel& cache, const DfgSel* vtxp) {
const auto it = find(cache, vtxp->dtypep(), vtxp->fromp(), vtxp->lsb());
if (it != cache.end() && it->second == vtxp) cache.erase(it);
}
inline void invalidateByValue(CacheUnary& cache, DfgVertexUnary* vtxp) {
inline void invalidateByValue(CacheUnary& cache, const DfgVertexUnary* vtxp) {
const auto it = find(cache, vtxp->dtypep(), vtxp->source<0>());
if (it != cache.end() && it->second == vtxp) cache.erase(it);
}
inline void invalidateByValue(CacheBinary& cache, DfgVertexBinary* vtxp) {
inline void invalidateByValue(CacheBinary& cache, const DfgVertexBinary* vtxp) {
const auto it = find(cache, vtxp->dtypep(), vtxp->source<0>(), vtxp->source<1>());
if (it != cache.end() && it->second == vtxp) cache.erase(it);
}
inline void invalidateByValue(CacheTernary& cache, DfgVertexTernary* vtxp) {
inline void invalidateByValue(CacheTernary& cache, const DfgVertexTernary* vtxp) {
const auto it
= find(cache, vtxp->dtypep(), vtxp->source<0>(), vtxp->source<1>(), vtxp->source<2>());
if (it != cache.end() && it->second == vtxp) cache.erase(it);

View File

@ -126,7 +126,7 @@ class ColorStronglyConnectedComponents final {
}
}
ColorStronglyConnectedComponents(DfgGraph& dfg)
explicit ColorStronglyConnectedComponents(DfgGraph& dfg)
: m_dfg{dfg} {
UASSERT(dfg.size() < UNASSIGNED, "Graph too big " << dfg.name());
// Yet another implementation of Pearce's algorithm.

View File

@ -352,8 +352,8 @@ public:
, m_prefix{VString::removeWhitespace(label) + "-"} {}
~V3DfgContext() {
const string prefix = "Optimizations, DFG " + label() + " General, ";
V3Stats::addStat(prefix + "modules", m_modules);
const string front = "Optimizations, DFG " + label() + " General, ";
V3Stats::addStat(front + "modules", m_modules);
// Print the collected patterns
if (v3Global.opt.stats()) {

View File

@ -113,7 +113,7 @@ public:
}
};
std::vector<std::unique_ptr<DfgGraph>> DfgGraph::splitIntoComponents(std::string label) {
std::vector<std::unique_ptr<DfgGraph>> DfgGraph::splitIntoComponents(const std::string& label) {
return SplitIntoComponents::apply(*this, label);
}
@ -125,7 +125,7 @@ class ExtractCyclicComponents final {
uint64_t& m_userr;
public:
VertexState(DfgVertex& vtx)
explicit VertexState(DfgVertex& vtx)
: m_userr{vtx.getUser<uint64_t>()} {}
bool merged() const { return m_userr >> 63; }
void setMerged() { m_userr |= 1ULL << 63; }
@ -266,11 +266,11 @@ class ExtractCyclicComponents final {
dfg.forEachVertex([&](const DfgVertex& vtx) { vertices.insert(&vtx); });
// Check that each edge connects to a vertex that is within the same graph
dfg.forEachVertex([&](DfgVertex& vtx) {
vtx.forEachSource([&](DfgVertex& src) {
dfg.forEachVertex([&](const DfgVertex& vtx) {
vtx.forEachSource([&](const DfgVertex& src) {
UASSERT_OBJ(vertices.count(&src), &vtx, "Source vertex not in graph");
});
vtx.forEachSink([&](DfgVertex& snk) {
vtx.forEachSink([&](const DfgVertex& snk) {
UASSERT_OBJ(vertices.count(&snk), &snk, "Sink vertex not in graph");
});
});
@ -287,7 +287,7 @@ class ExtractCyclicComponents final {
// earlier merging of components ensured crossing in fact only happen at variable
// boundaries). Note that fixing up the edges can create clones of variables. Clones do
// not need fixing up, so we do not need to iterate them.
DfgVertex* const lastp = m_dfg.varVertices().backp();
const DfgVertex* const lastp = m_dfg.varVertices().backp();
for (DfgVertexVar& vtx : m_dfg.varVertices()) {
// Fix up the edges crossing components
fixEdges(vtx);
@ -337,6 +337,7 @@ public:
}
};
std::vector<std::unique_ptr<DfgGraph>> DfgGraph::extractCyclicComponents(std::string label) {
std::vector<std::unique_ptr<DfgGraph>>
DfgGraph::extractCyclicComponents(const std::string& label) {
return ExtractCyclicComponents::apply(*this, label);
}

View File

@ -194,7 +194,7 @@ class DfgToAstVisitor final : DfgVisitor {
AstConst* const idxp = new AstConst{dflp, sArrayp->driverLo(i)};
AstArraySel* const nLhsp = new AstArraySel{dflp, lhsp->cloneTreePure(false), idxp};
// Convert source
if (DfgUnitArray* const uap = driverp->cast<DfgUnitArray>()) {
if (const DfgUnitArray* const uap = driverp->cast<DfgUnitArray>()) {
convertDriver(assignments, dflp, nLhsp, uap->srcp());
} else {
convertDriver(assignments, dflp, nLhsp, driverp);
@ -205,7 +205,7 @@ class DfgToAstVisitor final : DfgVisitor {
return;
}
if (DfgUnitArray* const uap = driverp->cast<DfgUnitArray>()) {
if (const DfgUnitArray* const uap = driverp->cast<DfgUnitArray>()) {
// Single element array being assigned a unit array. Needs an ArraySel.
AstConst* const idxp = new AstConst{flp, 0};
AstArraySel* const nLhsp = new AstArraySel{flp, lhsp->cloneTreePure(false), idxp};

View File

@ -164,7 +164,9 @@ class DataflowExtractVisitor final : public VNVisitor {
void visit(AstAssignW* nodep) override {
// Mark LHS variable as combinationally driven
if (AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef)) vrefp->varp()->user4(true);
if (const AstVarRef* const vrefp = VN_CAST(nodep->lhsp(), VarRef)) {
vrefp->varp()->user4(true);
}
//
iterateChildrenConst(nodep);
}

View File

@ -312,7 +312,7 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) {
v3Global.rootp()->typeTablep()->addTypesp(tabDTypep);
// The index variable
DfgVarPacked* const idxVtxp = [&]() {
AstVar* const idxVarp = [&]() {
// If there is an existing result variable, use that, otherwise create a new variable
DfgVarPacked* varp = nullptr;
if (DfgVertexVar* const vp = srcp->getResultVar()) {
@ -324,7 +324,7 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) {
varp->srcp(srcp);
}
varp->setHasModRdRefs();
return varp;
return varp->varp();
}();
// The previous index variable - we don't need a vertex for this
AstVar* const preVarp = [&]() {
@ -381,13 +381,13 @@ void V3DfgPasses::binToOneHot(DfgGraph& dfg, V3DfgBinToOneHotContext& ctx) {
logicp->addStmtsp(new AstAssign{
flp, //
new AstArraySel{flp, new AstVarRef{flp, tabVtxp->varp(), VAccess::WRITE},
new AstVarRef{flp, idxVtxp->varp(), VAccess::READ}}, //
new AstVarRef{flp, idxVarp, VAccess::READ}}, //
new AstConst{flp, AstConst::BitTrue{}}});
}
{ // pre = idx
logicp->addStmtsp(new AstAssign{flp, //
new AstVarRef{flp, preVarp, VAccess::WRITE}, //
new AstVarRef{flp, idxVtxp->varp(), VAccess::READ}});
new AstVarRef{flp, idxVarp, VAccess::READ}});
}
// Replace terms with ArraySels
@ -500,7 +500,7 @@ void V3DfgPasses::eliminateVars(DfgGraph& dfg, V3DfgEliminateVarsContext& ctx) {
++ctx.m_varsRemoved;
varp->replaceWith(varp->srcp());
ctx.m_deleteps.push_back(varp->nodep()); // Delete variable at the end
} else if (DfgVarPacked* const driverp = varp->srcp()->cast<DfgVarPacked>()) {
} else if (const DfgVarPacked* const driverp = varp->srcp()->cast<DfgVarPacked>()) {
// If it's driven from another variable, it can be replaced by that.
// Mark it for replacement
++ctx.m_varsReplaced;

View File

@ -232,7 +232,7 @@ class V3DfgPeephole final : public DfgVisitor {
// Same as above, but 'flp' and 'dtypep' are taken from the given example vertex
template <typename Vertex, typename... Operands>
Vertex* make(DfgVertex* examplep, Operands... operands) {
Vertex* make(const DfgVertex* examplep, Operands... operands) {
return make<Vertex>(examplep->fileline(), examplep->dtypep(), operands...);
}
@ -408,8 +408,8 @@ class V3DfgPeephole final : public DfgVisitor {
// If both sides are variable references, order the side in some defined way. This
// allows CSE to later merge 'a op b' with 'b op a'.
if (lhsp->is<DfgVertexVar>() && rhsp->is<DfgVertexVar>()) {
AstNode* const lVarp = lhsp->as<DfgVertexVar>()->nodep();
AstNode* const rVarp = rhsp->as<DfgVertexVar>()->nodep();
const AstNode* const lVarp = lhsp->as<DfgVertexVar>()->nodep();
const AstNode* const rVarp = rhsp->as<DfgVertexVar>()->nodep();
if (lVarp->name() > rVarp->name()) {
APPLYING(SWAP_VAR_IN_COMMUTATIVE_BINARY) {
Vertex* const replacementp = make<Vertex>(vtxp, rhsp, lhsp);

View File

@ -153,7 +153,7 @@ class AstToDfgConverter final : public VNVisitor {
}
// Get (or create a new) temporary for this variable
DfgVertexVar* const vtxp = [&]() -> DfgVertexVar* {
const DfgVertexVar* const vtxp = [&]() -> DfgVertexVar* {
// The variable being assigned
Variable* const tgtp = getTarget(vrefp);
@ -240,7 +240,9 @@ class AstToDfgConverter final : public VNVisitor {
// Return the splice driver
DfgVertex* driverp = splicep->driverAt(index);
if (DfgUnitArray* const uap = driverp->cast<DfgUnitArray>()) driverp = uap->srcp();
if (const DfgUnitArray* const uap = driverp->cast<DfgUnitArray>()) {
driverp = uap->srcp();
}
return {driverp->as<DfgVertexSplice>(), 0};
}
@ -1319,6 +1321,7 @@ class AstToDfgSynthesize final {
const bool missing = m_logicp->findSink<DfgVertex>([&](const DfgVertex& sink) -> bool {
const DfgUnresolved* const unresolvedp = sink.as<DfgUnresolved>();
AstNode* const tgtp = unresolvedp->singleSink()->as<DfgVertexVar>()->nodep();
// cppcheck-suppress constVariablePointer
Variable* const varp = reinterpret_cast<Variable*>(tgtp);
return !oSymTab.count(varp);
});
@ -1331,6 +1334,7 @@ class AstToDfgSynthesize final {
m_logicp->forEachSink([&](DfgVertex& sink) {
DfgUnresolved* const unresolvedp = sink.as<DfgUnresolved>();
AstNode* const tgtp = unresolvedp->singleSink()->as<DfgVertexVar>()->nodep();
// cppcheck-suppress constVariablePointer
Variable* const varp = reinterpret_cast<Variable*>(tgtp);
DfgVertexVar* const resp = oSymTab.at(varp);
UASSERT_OBJ(resp->srcp(), resp, "Undriven result");
@ -1489,7 +1493,7 @@ class AstToDfgSynthesize final {
//-------------------------------------------------------------------
UINFO(5, "Step 2: Revert drivers of variables with unsynthesizeable drivers");
// We do this as the variables might be multi-driven, we just can't know at this point
for (DfgVertexVar& var : m_dfg.varVertices()) {
for (const DfgVertexVar& var : m_dfg.varVertices()) {
if (!var.srcp()) continue;
DfgUnresolved* const unresolvedp = var.srcp()->cast<DfgUnresolved>();
if (!unresolvedp) break; // Stop when reached the synthesized temporaries
@ -1509,7 +1513,7 @@ class AstToDfgSynthesize final {
// List of multi-driven variables
std::vector<DfgVertexVar*> multidrivenps;
// Map from variable to its resolved driver
std::unordered_map<DfgVertexVar*, DfgVertexSplice*> resolvedDrivers;
std::unordered_map<const DfgVertexVar*, DfgVertexSplice*> resolvedDrivers;
// Compute resolved drivers of all variablees
for (DfgVertexVar& var : m_dfg.varVertices()) {
if (!var.srcp()) continue;
@ -1536,7 +1540,7 @@ class AstToDfgSynthesize final {
UASSERT_OBJ(newEntry, &var, "Dupliacte driver");
}
// Revert and remove drivers of multi-driven variables
for (DfgVertexVar* const vtxp : multidrivenps) {
for (const DfgVertexVar* const vtxp : multidrivenps) {
// Mark as multidriven for future DFG runs - here, so we get all warning before
vtxp->varp()->setDfgMultidriven();
// Might not have a driver if transitively removed on an earlier iteration
@ -1546,7 +1550,7 @@ class AstToDfgSynthesize final {
revertTransivelyAndRemove(unresolvedp, m_ctx.m_synt.revertMultidrive);
}
// Replace all DfgUnresolved with the resolved drivers
for (DfgVertexVar& var : m_dfg.varVertices()) {
for (const DfgVertexVar& var : m_dfg.varVertices()) {
if (!var.srcp()) continue;
DfgUnresolved* const srcp = var.srcp()->cast<DfgUnresolved>();
if (!srcp) break; // Stop when reached the synthesized temporaries

View File

@ -185,6 +185,7 @@ public:
// the actual driver this DfgVertexSplice can be replaced with.
inline DfgVertex* wholep() const;
// cppcheck-suppress duplInheritedMember
void resetSources() {
m_driverData.clear();
// Unlink default driver
@ -375,7 +376,7 @@ class DfgUnresolved final : public DfgVertexVariadic {
// Represents a collection of unresolved variable drivers before synthesis
public:
DfgUnresolved(DfgGraph& dfg, DfgVertexVar* vtxp)
DfgUnresolved(DfgGraph& dfg, const DfgVertexVar* vtxp)
: DfgVertexVariadic{dfg, dfgType(), vtxp->fileline(), vtxp->dtypep(), 1u} {}
ASTGEN_MEMBERS_DfgUnresolved;
@ -383,6 +384,7 @@ public:
void addDriver(DfgLogic* vtxp) { addSource()->relinkSource(vtxp); }
void addDriver(DfgVertexSplice* vtxp) { addSource()->relinkSource(vtxp); }
// cppcheck-suppress duplInheritedMember
void clearSources() { DfgVertexVariadic::clearSources(); }
DfgVertex* singleSource() const { return arity() == 1 ? source(0) : nullptr; }

View File

@ -649,18 +649,19 @@ void v3errorEndFatal(std::ostringstream& sstr)
/// Based on debug level, call UINFO then dumpTree on nodep, using given message prefix
/// If uinfo_msg = "", suppress the first UINFO
/// If dt_msg = "", use the uinfo_msg; note any uinfo_msg side effects will happen twice.
#define UINFOTREE(level, nodep, uinfo_msg, dt_msg) \
/// If dumptree_msg = "", use the uinfo_msg; note any uinfo_msg side effects will happen twice.
#define UINFOTREE(level, nodep, uinfo_msg, dumptree_msg) \
do { \
if (VL_UNCOVERABLE(debug() >= (level))) { \
std::ostringstream us; \
us << uinfo_msg; \
if (!us.str().empty()) UINFO(level, us.str()); \
std::ostringstream ss; \
ss << dt_msg; \
if (ss.str().empty()) ss << uinfo_msg; \
if (nodep) \
nodep->dumpTree("- "s + V3Error::lineStr(__FILE__, __LINE__) + ss.str() + " - "); \
if (nodep) { \
std::ostringstream ss; \
ss << dumptree_msg; \
if (ss.str().empty()) ss << uinfo_msg; \
nodep->dumpTree("- " + V3Error::lineStr(__FILE__, __LINE__) + ss.str() + " - "); \
} \
} \
} while (false)
@ -722,6 +723,8 @@ void v3errorEndFatal(std::ostringstream& sstr)
// Takes an optional "name" (as __VA_ARGS__)
#define VL_DEFINE_DEBUG(...) \
VL_ATTR_UNUSED static int debug##__VA_ARGS__() VL_MT_SAFE { \
/* Don't complain this function is unused */ \
(void)&debug##__VA_ARGS__; \
static int level = -1; \
if (VL_UNLIKELY(level < 0)) { \
std::string tag{VL_STRINGIFY(__VA_ARGS__)}; \
@ -739,6 +742,8 @@ void v3errorEndFatal(std::ostringstream& sstr)
// Takes an optional "name" (as __VA_ARGS__)
#define VL_DEFINE_DUMP(func, tag) \
VL_ATTR_UNUSED static int dump##func() VL_MT_SAFE { \
/* Don't complain this function is unused */ \
(void)&dump##func; \
static int level = -1; \
if (VL_UNLIKELY(level < 0)) { \
const unsigned dumpTag = v3Global.opt.dumpLevel(tag); \
@ -762,6 +767,7 @@ void v3errorEndFatal(std::ostringstream& sstr)
VL_DEFINE_DUMP(TreeJsonLevel, \
"tree-json"); /* Define 'int dumpTreeJsonLevel()' for dumpi-tree-json */ \
VL_ATTR_UNUSED static int dumpTreeEitherLevel() { \
/* Don't complain this function is unused */ (void)&dumpTreeEitherLevel; \
return dumpTreeJsonLevel() >= dumpTreeLevel() ? dumpTreeJsonLevel() : dumpTreeLevel(); \
} \
static_assert(true, "")

View File

@ -302,7 +302,9 @@ public:
puts("\n");
}
virtual void putsHeader() {}
// cppcheck-suppress duplInheritedMember
void puts(const char* strg) { putsNoTracking(strg); }
// cppcheck-suppress duplInheritedMember
void puts(const string& strg) { putsNoTracking(strg); }
// METHODS
@ -388,7 +390,9 @@ public:
~V3OutMkFile() override = default;
virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); }
// No automatic indentation yet.
// cppcheck-suppress duplInheritedMember
void puts(const char* strg) { putsNoTracking(strg); }
// cppcheck-suppress duplInheritedMember
void puts(const string& strg) { putsNoTracking(strg); }
// Put VARIABLE = VALUE
void putSet(const string& var, const string& value) {

View File

@ -38,14 +38,17 @@ public:
: m_value{0} {}
explicit V3Hash(uint32_t val)
: m_value{val} {}
explicit V3Hash(int32_t val)
: m_value{static_cast<uint32_t>(val)} {}
explicit V3Hash(uint64_t val)
: m_value{combine(static_cast<uint32_t>(val), static_cast<uint32_t>(val >> 32))} {}
explicit V3Hash(int64_t val)
: m_value{combine(static_cast<uint32_t>(val), static_cast<uint32_t>(val >> 32))} {}
explicit V3Hash(const std::string& val);
explicit V3Hash(int32_t val)
: V3Hash{static_cast<uint32_t>(val)} {}
explicit V3Hash(int64_t val)
: V3Hash{static_cast<uint64_t>(val)} {}
explicit V3Hash(void* val)
: V3Hash{reinterpret_cast<uintptr_t>(val)} {}
// METHODS
uint32_t value() const VL_MT_SAFE { return m_value; }
std::string toString() const VL_MT_SAFE;

View File

@ -93,7 +93,7 @@ public:
Link m_next; // Next in list of sibling heaps
Link m_kids; // Head of list of child heaps
Node** m_ownerpp = nullptr; // Pointer to the Link pointer pointing to this heap
T_Key m_key; // The key in the heap
T_Key m_key{}; // The key in the heap
// CONSTRUCTOR
explicit Node() = default;

View File

@ -168,7 +168,7 @@ private:
V3Number fieldNum{nump, width};
fieldNum.opSel(*nump, msb, lsb);
out << itemp->name() << ": ";
if (AstNodeDType* const childTypep = itemp->subDTypep()) {
if (const AstNodeDType* const childTypep = itemp->subDTypep()) {
out << prettyNumber(&fieldNum, childTypep);
} else {
out << fieldNum;
@ -179,7 +179,7 @@ private:
return out.str();
}
} else if (const AstPackArrayDType* const arrayp = VN_CAST(dtypep, PackArrayDType)) {
if (AstNodeDType* const childTypep = arrayp->subDTypep()) {
if (const AstNodeDType* const childTypep = arrayp->subDTypep()) {
std::ostringstream out;
out << "[";
const int arrayElements = arrayp->elementsConst();
@ -226,7 +226,7 @@ public:
conIt != tconnects->end(); ++conIt) {
const AstVar* const portp = conIt->first;
AstNodeExpr* const pinp = conIt->second->exprp();
AstNodeDType* const dtypep = pinp->dtypep();
const AstNodeDType* const dtypep = pinp->dtypep();
if (AstConst* const valp = fetchConstNull(pinp)) {
stack << "\n " << portp->prettyName() << " = "
<< prettyNumber(&valp->num(), dtypep);
@ -876,7 +876,7 @@ private:
void visit(AstArraySel* nodep) override {
checkNodeInfo(nodep);
iterateChildrenConst(nodep);
if (AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) {
if (const AstInitArray* const initp = VN_CAST(fetchValueNull(nodep->fromp()), InitArray)) {
const AstConst* const indexp = fetchConst(nodep->bitp());
const uint32_t offset = indexp->num().toUInt();
AstNodeExpr* const itemp = initp->getIndexDefaultedValuep(offset);

View File

@ -27,7 +27,8 @@ duplInheritedMember:src/V3AstNode*.h
duplInheritedMember:src/obj_*/V3Ast__gen_impl.h
// We intentionally redefine DfgVertex methods to match Ast
duplInheritedMember:src/obj_*/V3Dfg__gen_auto_classes.h
// TODO: fix - maybe?
duplInheritedMember:src/V3File*.h
// They are used after astgen expansion
unusedPrivateFunction:src/V3Const.cpp
// These are all inappropriate
constVariablePointer:src/V3DfgPeephole.cpp
constParameterPointer:src/V3DfgPeephole.cpp