Internals: Improve astgen type enums to be switch statement friendly (#6362)
- Remove _ENUM_END, so -Wswitch does not demand it's covered. Use the new NUM_TYPES constexpr member instead. - Remove 'at' prefix. This seems historical and is not particularly useful. - Fix some cppcheck warts while at it
This commit is contained in:
parent
8bf2240d40
commit
5161cea8cd
|
|
@ -52,7 +52,7 @@ int AstNodeDType::s_uniqueNum = 0;
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// VNType
|
// VNType
|
||||||
|
|
||||||
const VNTypeInfo VNType::typeInfoTable[] = {
|
const VNTypeInfo VNType::s_typeInfoTable[VNType::NUM_TYPES()] = {
|
||||||
#include "V3Ast__gen_type_info.h" // From ./astgen
|
#include "V3Ast__gen_type_info.h" // From ./astgen
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1162,8 +1162,7 @@ bool AstNode::sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ig
|
||||||
void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
|
void AstNode::checkTreeIter(const AstNode* prevBackp) const VL_MT_STABLE {
|
||||||
// private: Check a tree and children
|
// private: Check a tree and children
|
||||||
UASSERT_OBJ(prevBackp == this->backp(), this, "Back node inconsistent");
|
UASSERT_OBJ(prevBackp == this->backp(), this, "Back node inconsistent");
|
||||||
// cppcheck-suppress danglingTempReference
|
const VNTypeInfo& typeInfo = VNType::typeInfo(this->type());
|
||||||
const VNTypeInfo& typeInfo = *type().typeInfo();
|
|
||||||
for (int i = 1; i <= 4; i++) {
|
for (int i = 1; i <= 4; i++) {
|
||||||
AstNode* nodep = nullptr;
|
AstNode* nodep = nullptr;
|
||||||
switch (i) {
|
switch (i) {
|
||||||
|
|
|
||||||
16
src/V3Ast.h
16
src/V3Ast.h
|
|
@ -109,22 +109,20 @@ struct VNTypeInfo final {
|
||||||
};
|
};
|
||||||
|
|
||||||
class VNType final {
|
class VNType final {
|
||||||
static const VNTypeInfo typeInfoTable[];
|
static const VNTypeInfo s_typeInfoTable[];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#include "V3Ast__gen_type_enum.h" // From ./astgen
|
#include "V3Ast__gen_type_enum.h" // From ./astgen
|
||||||
// Above include has:
|
const en m_e;
|
||||||
// enum en {...};
|
|
||||||
// const char* ascii() const {...};
|
|
||||||
const enum en m_e;
|
|
||||||
VNType() = delete;
|
VNType() = delete;
|
||||||
|
|
||||||
|
// VNType is interconvetible with VNType::en
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
constexpr VNType(en _e) VL_MT_SAFE : m_e{_e} {}
|
constexpr VNType(en _e) VL_MT_SAFE : m_e{_e} {}
|
||||||
explicit VNType(int _e)
|
|
||||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
|
||||||
// cppcheck-suppress danglingTempReference
|
|
||||||
const VNTypeInfo* typeInfo() const VL_MT_SAFE { return &typeInfoTable[m_e]; }
|
|
||||||
constexpr operator en() const VL_MT_SAFE { return m_e; }
|
constexpr operator en() const VL_MT_SAFE { return m_e; }
|
||||||
|
|
||||||
|
// Retrieve VNTypeInfo for the given type
|
||||||
|
static const VNTypeInfo& typeInfo(VNType t) VL_MT_SAFE { return s_typeInfoTable[t.m_e]; }
|
||||||
};
|
};
|
||||||
constexpr bool operator==(const VNType& lhs, const VNType& rhs) VL_PURE {
|
constexpr bool operator==(const VNType& lhs, const VNType& rhs) VL_PURE {
|
||||||
return lhs.m_e == rhs.m_e;
|
return lhs.m_e == rhs.m_e;
|
||||||
|
|
|
||||||
|
|
@ -387,9 +387,9 @@ static AstNode* createForeachLoop(AstNodeForeach* nodep, AstNode* bodysp, AstVar
|
||||||
AstNodeExpr* condp;
|
AstNodeExpr* condp;
|
||||||
bool inc = true;
|
bool inc = true;
|
||||||
switch (nodeType) {
|
switch (nodeType) {
|
||||||
case VNType::atLteS: condp = new AstLteS{fl, varRefp, rightp}; break;
|
case VNType::LteS: condp = new AstLteS{fl, varRefp, rightp}; break;
|
||||||
case VNType::atLt: condp = new AstLt{fl, varRefp, rightp}; break;
|
case VNType::Lt: condp = new AstLt{fl, varRefp, rightp}; break;
|
||||||
case VNType::atGteS:
|
case VNType::GteS:
|
||||||
condp = new AstGteS{fl, varRefp, rightp};
|
condp = new AstGteS{fl, varRefp, rightp};
|
||||||
inc = false;
|
inc = false;
|
||||||
break;
|
break;
|
||||||
|
|
@ -419,8 +419,7 @@ static AstNode* createForeachLoopRanged(AstNodeForeach* nodep, AstNode* bodysp,
|
||||||
AstNodeExpr* const leftp = new AstConst{fl, left};
|
AstNodeExpr* const leftp = new AstConst{fl, left};
|
||||||
AstNodeExpr* const rightp = new AstConst{fl, right};
|
AstNodeExpr* const rightp = new AstConst{fl, right};
|
||||||
return createForeachLoop(nodep, bodysp, varp, leftp, rightp,
|
return createForeachLoop(nodep, bodysp, varp, leftp, rightp,
|
||||||
declRange.left() <= declRange.right() ? VNType::atLteS
|
declRange.left() <= declRange.right() ? VNType::LteS : VNType::GteS);
|
||||||
: VNType::atGteS);
|
|
||||||
}
|
}
|
||||||
AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
|
AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
|
||||||
// UINFOTREE(1, nodep, "", "foreach-old");
|
// UINFOTREE(1, nodep, "", "foreach-old");
|
||||||
|
|
@ -459,8 +458,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
|
||||||
if (adtypep->isString()) {
|
if (adtypep->isString()) {
|
||||||
AstConst* const leftp = new AstConst{fl, 0};
|
AstConst* const leftp = new AstConst{fl, 0};
|
||||||
AstNodeExpr* const rightp = new AstLenN{fl, fromp->cloneTreePure(false)};
|
AstNodeExpr* const rightp = new AstLenN{fl, fromp->cloneTreePure(false)};
|
||||||
loopp
|
loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::Lt);
|
||||||
= createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::atLt);
|
|
||||||
} else {
|
} else {
|
||||||
UASSERT_OBJ(adtypep->isRanged(), varp, "foreach on basic " << adtypep);
|
UASSERT_OBJ(adtypep->isRanged(), varp, "foreach on basic " << adtypep);
|
||||||
loopp = createForeachLoopRanged(nodep, bodyPointp, varp, adtypep->declRange());
|
loopp = createForeachLoopRanged(nodep, bodyPointp, varp, adtypep->declRange());
|
||||||
|
|
@ -479,7 +477,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) {
|
||||||
subfromp->dtypep(fromDtp);
|
subfromp->dtypep(fromDtp);
|
||||||
rightp->dtypeSetSigned32();
|
rightp->dtypeSetSigned32();
|
||||||
rightp->protect(false);
|
rightp->protect(false);
|
||||||
loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::atLt);
|
loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, rightp, VNType::Lt);
|
||||||
} else if (VN_IS(fromDtp, AssocArrayDType)) {
|
} else if (VN_IS(fromDtp, AssocArrayDType)) {
|
||||||
// Make this: var KEY_TYPE index;
|
// Make this: var KEY_TYPE index;
|
||||||
// bit index__Vfirst;
|
// bit index__Vfirst;
|
||||||
|
|
|
||||||
|
|
@ -177,7 +177,7 @@ class CCtorsVisitor final : public VNVisitor {
|
||||||
// If can be referred to by base pointer, need virtual delete
|
// If can be referred to by base pointer, need virtual delete
|
||||||
funcp->isVirtual(classp->isExtended());
|
funcp->isVirtual(classp->isExtended());
|
||||||
funcp->slow(false);
|
funcp->slow(false);
|
||||||
insertSc(funcp, classp, VNType::atScDtor);
|
insertSc(funcp, classp, VNType::ScDtor);
|
||||||
classp->addStmtsp(funcp);
|
classp->addStmtsp(funcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +188,7 @@ class CCtorsVisitor final : public VNVisitor {
|
||||||
m_varResetp = nullptr;
|
m_varResetp = nullptr;
|
||||||
m_cfuncp = nodep;
|
m_cfuncp = nodep;
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
if (nodep->name() == "new") insertSc(nodep, m_modp, VNType::atScCtor);
|
if (nodep->name() == "new") insertSc(nodep, m_modp, VNType::ScCtor);
|
||||||
}
|
}
|
||||||
void visit(AstVar* nodep) override {
|
void visit(AstVar* nodep) override {
|
||||||
if (nodep->needsCReset()) {
|
if (nodep->needsCReset()) {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
|
||||||
DfgVertexVar* cp = nullptr;
|
DfgVertexVar* cp = nullptr;
|
||||||
|
|
||||||
switch (vtx.type()) {
|
switch (vtx.type()) {
|
||||||
case VDfgType::atVarArray: {
|
case VDfgType::VarArray: {
|
||||||
if (scoped) {
|
if (scoped) {
|
||||||
cp = new DfgVarArray{*clonep, vp->varScopep()};
|
cp = new DfgVarArray{*clonep, vp->varScopep()};
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -90,7 +90,7 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
|
||||||
vtxp2clonep.emplace(&vtx, cp);
|
vtxp2clonep.emplace(&vtx, cp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VDfgType::atVarPacked: {
|
case VDfgType::VarPacked: {
|
||||||
if (scoped) {
|
if (scoped) {
|
||||||
cp = new DfgVarPacked{*clonep, vp->varScopep()};
|
cp = new DfgVarPacked{*clonep, vp->varScopep()};
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -112,38 +112,38 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
|
||||||
for (const DfgVertex& vtx : m_opVertices) {
|
for (const DfgVertex& vtx : m_opVertices) {
|
||||||
switch (vtx.type()) {
|
switch (vtx.type()) {
|
||||||
#include "V3Dfg__gen_clone_cases.h" // From ./astgen
|
#include "V3Dfg__gen_clone_cases.h" // From ./astgen
|
||||||
case VDfgType::atSel: {
|
case VDfgType::Sel: {
|
||||||
DfgSel* const cp = new DfgSel{*clonep, vtx.fileline(), vtx.dtypep()};
|
DfgSel* const cp = new DfgSel{*clonep, vtx.fileline(), vtx.dtypep()};
|
||||||
cp->lsb(vtx.as<DfgSel>()->lsb());
|
cp->lsb(vtx.as<DfgSel>()->lsb());
|
||||||
vtxp2clonep.emplace(&vtx, cp);
|
vtxp2clonep.emplace(&vtx, cp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VDfgType::atUnitArray: {
|
case VDfgType::UnitArray: {
|
||||||
DfgUnitArray* const cp = new DfgUnitArray{*clonep, vtx.fileline(), vtx.dtypep()};
|
DfgUnitArray* const cp = new DfgUnitArray{*clonep, vtx.fileline(), vtx.dtypep()};
|
||||||
vtxp2clonep.emplace(&vtx, cp);
|
vtxp2clonep.emplace(&vtx, cp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VDfgType::atMux: {
|
case VDfgType::Mux: {
|
||||||
DfgMux* const cp = new DfgMux{*clonep, vtx.fileline(), vtx.dtypep()};
|
DfgMux* const cp = new DfgMux{*clonep, vtx.fileline(), vtx.dtypep()};
|
||||||
vtxp2clonep.emplace(&vtx, cp);
|
vtxp2clonep.emplace(&vtx, cp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VDfgType::atSpliceArray: {
|
case VDfgType::SpliceArray: {
|
||||||
DfgSpliceArray* const cp = new DfgSpliceArray{*clonep, vtx.fileline(), vtx.dtypep()};
|
DfgSpliceArray* const cp = new DfgSpliceArray{*clonep, vtx.fileline(), vtx.dtypep()};
|
||||||
vtxp2clonep.emplace(&vtx, cp);
|
vtxp2clonep.emplace(&vtx, cp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VDfgType::atSplicePacked: {
|
case VDfgType::SplicePacked: {
|
||||||
DfgSplicePacked* const cp = new DfgSplicePacked{*clonep, vtx.fileline(), vtx.dtypep()};
|
DfgSplicePacked* const cp = new DfgSplicePacked{*clonep, vtx.fileline(), vtx.dtypep()};
|
||||||
vtxp2clonep.emplace(&vtx, cp);
|
vtxp2clonep.emplace(&vtx, cp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VDfgType::atLogic: {
|
case VDfgType::Logic: {
|
||||||
vtx.v3fatalSrc("DfgLogic cannot be cloned");
|
vtx.v3fatalSrc("DfgLogic cannot be cloned");
|
||||||
VL_UNREACHABLE;
|
VL_UNREACHABLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VDfgType::atUnresolved: {
|
case VDfgType::Unresolved: {
|
||||||
vtx.v3fatalSrc("DfgUnresolved cannot be cloned");
|
vtx.v3fatalSrc("DfgUnresolved cannot be cloned");
|
||||||
VL_UNREACHABLE;
|
VL_UNREACHABLE;
|
||||||
break;
|
break;
|
||||||
|
|
@ -168,8 +168,8 @@ std::unique_ptr<DfgGraph> DfgGraph::clone() const {
|
||||||
for (const DfgVertex& vtx : m_opVertices) {
|
for (const DfgVertex& vtx : m_opVertices) {
|
||||||
if (vtx.is<DfgVertexVariadic>()) {
|
if (vtx.is<DfgVertexVariadic>()) {
|
||||||
switch (vtx.type()) {
|
switch (vtx.type()) {
|
||||||
case VDfgType::atSpliceArray:
|
case VDfgType::SpliceArray:
|
||||||
case VDfgType::atSplicePacked: {
|
case VDfgType::SplicePacked: {
|
||||||
const DfgVertexSplice* const vp = vtx.as<DfgVertexSplice>();
|
const DfgVertexSplice* const vp = vtx.as<DfgVertexSplice>();
|
||||||
DfgVertexSplice* const cp = vtxp2clonep.at(vp)->as<DfgVertexSplice>();
|
DfgVertexSplice* const cp = vtxp2clonep.at(vp)->as<DfgVertexSplice>();
|
||||||
vp->foreachDriver([&](const DfgVertex& src, uint32_t lo, FileLine* flp) {
|
vp->foreachDriver([&](const DfgVertex& src, uint32_t lo, FileLine* flp) {
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,10 @@ inline AstNodeDType* toDfgDType(const AstNodeDType* dtypep) {
|
||||||
class VDfgType final {
|
class VDfgType final {
|
||||||
public:
|
public:
|
||||||
#include "V3Dfg__gen_type_enum.h" // From ./astgen
|
#include "V3Dfg__gen_type_enum.h" // From ./astgen
|
||||||
const enum en m_e;
|
const en m_e;
|
||||||
VDfgType() = delete;
|
VDfgType() = delete;
|
||||||
|
|
||||||
|
// VDfgType is interconvetible with VDfgType::en
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
constexpr VDfgType(en _e)
|
constexpr VDfgType(en _e)
|
||||||
: m_e{_e} {}
|
: m_e{_e} {}
|
||||||
|
|
|
||||||
|
|
@ -564,7 +564,7 @@ class EmitCHeader final : public EmitCConstInit {
|
||||||
puts("\nclass " + EmitCUtil::symClassName() + ";\n");
|
puts("\nclass " + EmitCUtil::symClassName() + ";\n");
|
||||||
|
|
||||||
// From `systemc_header
|
// From `systemc_header
|
||||||
emitTextSection(modp, VNType::atScHdr);
|
emitTextSection(modp, VNType::ScHdr);
|
||||||
|
|
||||||
emitStructs(modp);
|
emitStructs(modp);
|
||||||
|
|
||||||
|
|
@ -607,7 +607,7 @@ class EmitCHeader final : public EmitCConstInit {
|
||||||
emitFuncDecls(modp, /* inClassBody: */ true);
|
emitFuncDecls(modp, /* inClassBody: */ true);
|
||||||
|
|
||||||
// From `systemc_interface
|
// From `systemc_interface
|
||||||
emitTextSection(modp, VNType::atScInt);
|
emitTextSection(modp, VNType::ScInt);
|
||||||
|
|
||||||
// Close class body
|
// Close class body
|
||||||
puts("};\n");
|
puts("};\n");
|
||||||
|
|
@ -616,7 +616,7 @@ class EmitCHeader final : public EmitCConstInit {
|
||||||
// Emit out of class function declarations
|
// Emit out of class function declarations
|
||||||
puts("\n");
|
puts("\n");
|
||||||
emitFuncDecls(modp, /* inClassBody: */ false);
|
emitFuncDecls(modp, /* inClassBody: */ false);
|
||||||
emitTextSection(modp, VNType::atScHdrPost);
|
emitTextSection(modp, VNType::ScHdrPost);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit EmitCHeader(const AstNodeModule* modp) {
|
explicit EmitCHeader(const AstNodeModule* modp) {
|
||||||
|
|
|
||||||
|
|
@ -200,7 +200,7 @@ class EmitCImp final : EmitCFunc {
|
||||||
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
|
puts("#include \"" + EmitCUtil::pchClassName() + ".h\"\n");
|
||||||
for (const string& name : headers) puts("#include \"" + name + ".h\"\n");
|
for (const string& name : headers) puts("#include \"" + name + ".h\"\n");
|
||||||
|
|
||||||
emitTextSection(m_modp, VNType::atScImpHdr);
|
emitTextSection(m_modp, VNType::ScImpHdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitStaticVarDefns(const AstNodeModule* modp) {
|
void emitStaticVarDefns(const AstNodeModule* modp) {
|
||||||
|
|
@ -286,7 +286,7 @@ class EmitCImp final : EmitCFunc {
|
||||||
|
|
||||||
putsDecoration(modp, "// Reset structure values\n");
|
putsDecoration(modp, "// Reset structure values\n");
|
||||||
puts(modName + "__" + protect("_ctor_var_reset") + "(this);\n");
|
puts(modName + "__" + protect("_ctor_var_reset") + "(this);\n");
|
||||||
emitTextSection(modp, VNType::atScCtor);
|
emitTextSection(modp, VNType::ScCtor);
|
||||||
|
|
||||||
puts("}\n");
|
puts("}\n");
|
||||||
}
|
}
|
||||||
|
|
@ -393,7 +393,7 @@ class EmitCImp final : EmitCFunc {
|
||||||
puts("\n");
|
puts("\n");
|
||||||
putns(modp, EmitCUtil::prefixNameProtect(modp) + "::~" + EmitCUtil::prefixNameProtect(modp)
|
putns(modp, EmitCUtil::prefixNameProtect(modp) + "::~" + EmitCUtil::prefixNameProtect(modp)
|
||||||
+ "() {\n");
|
+ "() {\n");
|
||||||
emitTextSection(modp, VNType::atScDtor);
|
emitTextSection(modp, VNType::ScDtor);
|
||||||
puts("}\n");
|
puts("}\n");
|
||||||
splitSizeInc(10);
|
splitSizeInc(10);
|
||||||
}
|
}
|
||||||
|
|
@ -507,7 +507,7 @@ class EmitCImp final : EmitCFunc {
|
||||||
emitSavableImp(modp);
|
emitSavableImp(modp);
|
||||||
} else {
|
} else {
|
||||||
// From `systemc_implementation
|
// From `systemc_implementation
|
||||||
emitTextSection(modp, VNType::atScImp);
|
emitTextSection(modp, VNType::ScImp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void emitCommonImp(const AstNodeModule* modp) {
|
void emitCommonImp(const AstNodeModule* modp) {
|
||||||
|
|
|
||||||
|
|
@ -350,12 +350,12 @@ class SliceVisitor final : public VNVisitor {
|
||||||
logp = clonep;
|
logp = clonep;
|
||||||
} else {
|
} else {
|
||||||
switch (nodep->type()) {
|
switch (nodep->type()) {
|
||||||
case VNType::atEq: // FALLTHRU
|
case VNType::Eq: // FALLTHRU
|
||||||
case VNType::atEqCase:
|
case VNType::EqCase:
|
||||||
logp = new AstLogAnd{nodep->fileline(), logp, clonep};
|
logp = new AstLogAnd{nodep->fileline(), logp, clonep};
|
||||||
break;
|
break;
|
||||||
case VNType::atNeq: // FALLTHRU
|
case VNType::Neq: // FALLTHRU
|
||||||
case VNType::atNeqCase:
|
case VNType::NeqCase:
|
||||||
logp = new AstLogOr{nodep->fileline(), logp, clonep};
|
logp = new AstLogOr{nodep->fileline(), logp, clonep};
|
||||||
break;
|
break;
|
||||||
default: nodep->v3fatalSrc("Unknown node type processing array slice"); break;
|
default: nodep->v3fatalSrc("Unknown node type processing array slice"); break;
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,11 @@ V3Mutex V3Stats::s_mutex;
|
||||||
class StatsVisitor final : public VNVisitorConst {
|
class StatsVisitor final : public VNVisitorConst {
|
||||||
struct Counters final {
|
struct Counters final {
|
||||||
// Nodes of given type
|
// Nodes of given type
|
||||||
std::array<uint64_t, VNType::_ENUM_END> m_statTypeCount = {};
|
std::array<uint64_t, VNType::NUM_TYPES()> m_statTypeCount{};
|
||||||
// Nodes of given type with given type immediate child
|
// Nodes of given type with given type immediate child
|
||||||
std::array<std::array<uint64_t, VNType::_ENUM_END>, VNType::_ENUM_END> m_statAbove = {};
|
std::array<std::array<uint64_t, VNType::NUM_TYPES()>, VNType::NUM_TYPES()> m_statAbove{};
|
||||||
// Prediction of given type
|
// Prediction of given type
|
||||||
std::array<uint64_t, VBranchPred::_ENUM_END> m_statPred = {};
|
std::array<uint64_t, VBranchPred::_ENUM_END> m_statPred{};
|
||||||
};
|
};
|
||||||
|
|
||||||
// STATE
|
// STATE
|
||||||
|
|
@ -127,10 +127,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node types (also total memory usage)
|
// Node types (also total memory usage)
|
||||||
const auto typeName = [](int type) { return std::string{VNType{type}.ascii()}; };
|
const auto typeName
|
||||||
const auto typeSize = [](int type) { return VNType{type}.typeInfo()->m_sizeof; };
|
= [](size_t t) { return std::string{VNType{static_cast<VNType::en>(t)}.ascii()}; };
|
||||||
|
const auto typeSize
|
||||||
|
= [](size_t t) { return VNType::typeInfo(static_cast<VNType::en>(t)).m_sizeof; };
|
||||||
size_t totalNodeMemoryUsage = 0;
|
size_t totalNodeMemoryUsage = 0;
|
||||||
for (int t = 0; t < VNType::_ENUM_END; ++t) {
|
for (size_t t = 0; t < VNType::NUM_TYPES(); ++t) {
|
||||||
if (const uint64_t count = m_counters.m_statTypeCount[t]) {
|
if (const uint64_t count = m_counters.m_statTypeCount[t]) {
|
||||||
totalNodeMemoryUsage += count * typeSize(t);
|
totalNodeMemoryUsage += count * typeSize(t);
|
||||||
addStat("Node count, " + typeName(t), count);
|
addStat("Node count, " + typeName(t), count);
|
||||||
|
|
@ -139,7 +141,7 @@ public:
|
||||||
addStat("Node memory TOTAL (MiB)", totalNodeMemoryUsage >> 20);
|
addStat("Node memory TOTAL (MiB)", totalNodeMemoryUsage >> 20);
|
||||||
|
|
||||||
// Node Memory usage
|
// Node Memory usage
|
||||||
for (int t = 0; t < VNType::_ENUM_END; ++t) {
|
for (size_t t = 0; t < VNType::NUM_TYPES(); ++t) {
|
||||||
if (const uint64_t count = m_counters.m_statTypeCount[t]) {
|
if (const uint64_t count = m_counters.m_statTypeCount[t]) {
|
||||||
const double share = 100.0 * count * typeSize(t) / totalNodeMemoryUsage;
|
const double share = 100.0 * count * typeSize(t) / totalNodeMemoryUsage;
|
||||||
addStat("Node memory share (%), " + typeName(t), share, 2);
|
addStat("Node memory share (%), " + typeName(t), share, 2);
|
||||||
|
|
@ -147,8 +149,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expression combinations
|
// Expression combinations
|
||||||
for (int t1 = 0; t1 < VNType::_ENUM_END; ++t1) {
|
for (size_t t1 = 0; t1 < VNType::NUM_TYPES(); ++t1) {
|
||||||
for (int t2 = 0; t2 < VNType::_ENUM_END; ++t2) {
|
for (size_t t2 = 0; t2 < VNType::NUM_TYPES(); ++t2) {
|
||||||
if (const uint64_t c = m_counters.m_statAbove[t1][t2]) {
|
if (const uint64_t c = m_counters.m_statAbove[t1][t2]) {
|
||||||
addStat("Expr combination, " + typeName(t1) + " over " + typeName(t2), c);
|
addStat("Expr combination, " + typeName(t1) + " over " + typeName(t2), c);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
114
src/V3Width.cpp
114
src/V3Width.cpp
|
|
@ -8015,15 +8015,15 @@ class WidthVisitor final : public VNVisitor {
|
||||||
if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp());
|
if (!nodep->dtypep()) nodep->dtypeFrom(nodep->lhsp());
|
||||||
// To simplify callers, some node types don't need to change
|
// To simplify callers, some node types don't need to change
|
||||||
switch (nodep->type()) {
|
switch (nodep->type()) {
|
||||||
case VNType::atEq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::Eq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atNeq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::Neq: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atEqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::EqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atNeqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::NeqCase: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atEqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::EqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atNeqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::NeqWild: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atAdd: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::Add: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atSub: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::Sub: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
case VNType::atShiftL: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
case VNType::ShiftL: nodep->dtypeChgSigned(signedFlavorNeeded); return nullptr;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
FileLine* const fl = nodep->fileline();
|
FileLine* const fl = nodep->fileline();
|
||||||
|
|
@ -8031,22 +8031,22 @@ class WidthVisitor final : public VNVisitor {
|
||||||
AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
|
AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack();
|
||||||
AstNodeBiop* newp = nullptr;
|
AstNodeBiop* newp = nullptr;
|
||||||
switch (nodep->type()) {
|
switch (nodep->type()) {
|
||||||
case VNType::atGt: newp = new AstGtS{fl, lhsp, rhsp}; break;
|
case VNType::Gt: newp = new AstGtS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atGtS: newp = new AstGt{fl, lhsp, rhsp}; break;
|
case VNType::GtS: newp = new AstGt{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atGte: newp = new AstGteS{fl, lhsp, rhsp}; break;
|
case VNType::Gte: newp = new AstGteS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atGteS: newp = new AstGte{fl, lhsp, rhsp}; break;
|
case VNType::GteS: newp = new AstGte{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLt: newp = new AstLtS{fl, lhsp, rhsp}; break;
|
case VNType::Lt: newp = new AstLtS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLtS: newp = new AstLt{fl, lhsp, rhsp}; break;
|
case VNType::LtS: newp = new AstLt{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLte: newp = new AstLteS{fl, lhsp, rhsp}; break;
|
case VNType::Lte: newp = new AstLteS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLteS: newp = new AstLte{fl, lhsp, rhsp}; break;
|
case VNType::LteS: newp = new AstLte{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atDiv: newp = new AstDivS{fl, lhsp, rhsp}; break;
|
case VNType::Div: newp = new AstDivS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atDivS: newp = new AstDiv{fl, lhsp, rhsp}; break;
|
case VNType::DivS: newp = new AstDiv{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atModDiv: newp = new AstModDivS{fl, lhsp, rhsp}; break;
|
case VNType::ModDiv: newp = new AstModDivS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atModDivS: newp = new AstModDiv{fl, lhsp, rhsp}; break;
|
case VNType::ModDivS: newp = new AstModDiv{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atMul: newp = new AstMulS{fl, lhsp, rhsp}; break;
|
case VNType::Mul: newp = new AstMulS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atMulS: newp = new AstMul{fl, lhsp, rhsp}; break;
|
case VNType::MulS: newp = new AstMul{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atShiftR: newp = new AstShiftRS{fl, lhsp, rhsp}; break;
|
case VNType::ShiftR: newp = new AstShiftRS{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atShiftRS: newp = new AstShiftR{fl, lhsp, rhsp}; break;
|
case VNType::ShiftRS: newp = new AstShiftR{fl, lhsp, rhsp}; break;
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep);
|
nodep->v3fatalSrc("Node needs sign change, but bad case: " << nodep);
|
||||||
break;
|
break;
|
||||||
|
|
@ -8066,25 +8066,25 @@ class WidthVisitor final : public VNVisitor {
|
||||||
AstNodeBiop* newp = nullptr;
|
AstNodeBiop* newp = nullptr;
|
||||||
// No width change on output;... // All below have bool or double outputs
|
// No width change on output;... // All below have bool or double outputs
|
||||||
switch (nodep->type()) {
|
switch (nodep->type()) {
|
||||||
case VNType::atAdd: newp = new AstAddD{fl, lhsp, rhsp}; break;
|
case VNType::Add: newp = new AstAddD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atSub: newp = new AstSubD{fl, lhsp, rhsp}; break;
|
case VNType::Sub: newp = new AstSubD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atPow: newp = new AstPowD{fl, lhsp, rhsp}; break;
|
case VNType::Pow: newp = new AstPowD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atEq:
|
case VNType::Eq:
|
||||||
case VNType::atEqCase: newp = new AstEqD{fl, lhsp, rhsp}; break;
|
case VNType::EqCase: newp = new AstEqD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atNeq:
|
case VNType::Neq:
|
||||||
case VNType::atNeqCase: newp = new AstNeqD{fl, lhsp, rhsp}; break;
|
case VNType::NeqCase: newp = new AstNeqD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atGt:
|
case VNType::Gt:
|
||||||
case VNType::atGtS: newp = new AstGtD{fl, lhsp, rhsp}; break;
|
case VNType::GtS: newp = new AstGtD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atGte:
|
case VNType::Gte:
|
||||||
case VNType::atGteS: newp = new AstGteD{fl, lhsp, rhsp}; break;
|
case VNType::GteS: newp = new AstGteD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLt:
|
case VNType::Lt:
|
||||||
case VNType::atLtS: newp = new AstLtD{fl, lhsp, rhsp}; break;
|
case VNType::LtS: newp = new AstLtD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLte:
|
case VNType::Lte:
|
||||||
case VNType::atLteS: newp = new AstLteD{fl, lhsp, rhsp}; break;
|
case VNType::LteS: newp = new AstLteD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atDiv:
|
case VNType::Div:
|
||||||
case VNType::atDivS: newp = new AstDivD{fl, lhsp, rhsp}; break;
|
case VNType::DivS: newp = new AstDivD{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atMul:
|
case VNType::Mul:
|
||||||
case VNType::atMulS: newp = new AstMulD{fl, lhsp, rhsp}; break;
|
case VNType::MulS: newp = new AstMulD{fl, lhsp, rhsp}; break;
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep);
|
nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep);
|
||||||
break;
|
break;
|
||||||
|
|
@ -8105,18 +8105,18 @@ class WidthVisitor final : public VNVisitor {
|
||||||
AstNodeBiop* newp = nullptr;
|
AstNodeBiop* newp = nullptr;
|
||||||
// No width change on output;... // All below have bool or double outputs
|
// No width change on output;... // All below have bool or double outputs
|
||||||
switch (nodep->type()) {
|
switch (nodep->type()) {
|
||||||
case VNType::atEq:
|
case VNType::Eq:
|
||||||
case VNType::atEqCase: newp = new AstEqN{fl, lhsp, rhsp}; break;
|
case VNType::EqCase: newp = new AstEqN{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atNeq:
|
case VNType::Neq:
|
||||||
case VNType::atNeqCase: newp = new AstNeqN{fl, lhsp, rhsp}; break;
|
case VNType::NeqCase: newp = new AstNeqN{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atGt:
|
case VNType::Gt:
|
||||||
case VNType::atGtS: newp = new AstGtN{fl, lhsp, rhsp}; break;
|
case VNType::GtS: newp = new AstGtN{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atGte:
|
case VNType::Gte:
|
||||||
case VNType::atGteS: newp = new AstGteN{fl, lhsp, rhsp}; break;
|
case VNType::GteS: newp = new AstGteN{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLt:
|
case VNType::Lt:
|
||||||
case VNType::atLtS: newp = new AstLtN{fl, lhsp, rhsp}; break;
|
case VNType::LtS: newp = new AstLtN{fl, lhsp, rhsp}; break;
|
||||||
case VNType::atLte:
|
case VNType::Lte:
|
||||||
case VNType::atLteS: newp = new AstLteN{fl, lhsp, rhsp}; break;
|
case VNType::LteS: newp = new AstLteN{fl, lhsp, rhsp}; break;
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
nodep->v3fatalSrc("Node needs conversion to string, but bad case: " << nodep);
|
nodep->v3fatalSrc("Node needs conversion to string, but bad case: " << nodep);
|
||||||
break;
|
break;
|
||||||
|
|
@ -8135,7 +8135,7 @@ class WidthVisitor final : public VNVisitor {
|
||||||
AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack();
|
AstNodeExpr* const lhsp = nodep->lhsp()->unlinkFrBack();
|
||||||
AstNodeUniop* newp = nullptr;
|
AstNodeUniop* newp = nullptr;
|
||||||
switch (nodep->type()) {
|
switch (nodep->type()) {
|
||||||
case VNType::atNegate: newp = new AstNegateD{fl, lhsp}; break;
|
case VNType::Negate: newp = new AstNegateD{fl, lhsp}; break;
|
||||||
default: // LCOV_EXCL_LINE
|
default: // LCOV_EXCL_LINE
|
||||||
nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep);
|
nodep->v3fatalSrc("Node needs conversion to double, but bad case: " << nodep);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
22
src/astgen
22
src/astgen
|
|
@ -832,22 +832,21 @@ def write_type_enum(prefix, nodeList):
|
||||||
|
|
||||||
fh.write(" enum en : uint16_t {\n")
|
fh.write(" enum en : uint16_t {\n")
|
||||||
for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId):
|
for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId):
|
||||||
fh.write(" at{t} = {n},\n".format(t=node.name, n=node.typeId))
|
fh.write(" {t} = {n},\n".format(t=node.name, n=node.typeId))
|
||||||
fh.write(" _ENUM_END = {n}\n".format(n=root.typeIdMax + 1))
|
|
||||||
fh.write(" };\n")
|
fh.write(" };\n")
|
||||||
|
fh.write(" static constexpr size_t NUM_TYPES() {{ return {n}; }}\n".format(
|
||||||
|
n=root.typeIdMax + 1))
|
||||||
|
|
||||||
fh.write(" enum bounds : uint16_t {\n")
|
fh.write(" enum bounds : uint16_t {\n")
|
||||||
for node in sorted(filter(lambda _: not _.isLeaf, nodeList), key=lambda _: _.typeIdMin):
|
for node in sorted(filter(lambda _: not _.isLeaf, nodeList), key=lambda _: _.typeIdMin):
|
||||||
fh.write(" first{t} = {n},\n".format(t=node.name, n=node.typeIdMin))
|
fh.write(" first{t} = {n},\n".format(t=node.name, n=node.typeIdMin))
|
||||||
fh.write(" last{t} = {n},\n".format(t=node.name, n=node.typeIdMax))
|
fh.write(" last{t} = {n},\n".format(t=node.name, n=node.typeIdMax))
|
||||||
fh.write(" _BOUNDS_END\n")
|
|
||||||
fh.write(" };\n")
|
fh.write(" };\n")
|
||||||
|
|
||||||
fh.write(" const char* ascii() const VL_MT_SAFE {\n")
|
fh.write(" const char* ascii() const VL_MT_SAFE {\n")
|
||||||
fh.write(" static const char* const names[_ENUM_END + 1] = {\n")
|
fh.write(" static const char* const names[] = {\n")
|
||||||
for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId):
|
for node in sorted(filter(lambda _: _.isLeaf, nodeList), key=lambda _: _.typeId):
|
||||||
fh.write(' "{T}",\n'.format(T=node.name.upper()))
|
fh.write(' "{T}",\n'.format(T=node.name.upper()))
|
||||||
fh.write(" \"_ENUM_END\"\n")
|
|
||||||
fh.write(" };\n")
|
fh.write(" };\n")
|
||||||
fh.write(" return names[m_e];\n")
|
fh.write(" return names[m_e];\n")
|
||||||
fh.write(" }\n")
|
fh.write(" }\n")
|
||||||
|
|
@ -879,9 +878,7 @@ def write_type_tests(prefix, nodeList):
|
||||||
"return static_cast<int>({v}->type()) >= static_cast<int>({e}::first{t}) && static_cast<int>({v}->type()) <= static_cast<int>({e}::last{t});"
|
"return static_cast<int>({v}->type()) >= static_cast<int>({e}::first{t}) && static_cast<int>({v}->type()) <= static_cast<int>({e}::last{t});"
|
||||||
.format(v=variable, e=enum, t=node.name))
|
.format(v=variable, e=enum, t=node.name))
|
||||||
else:
|
else:
|
||||||
fh.write("return {v}->type() == {e}::at{t};".format(v=variable,
|
fh.write("return {v}->type() == {e}::{t};".format(v=variable, e=enum, t=node.name))
|
||||||
e=enum,
|
|
||||||
t=node.name))
|
|
||||||
fh.write(" }\n")
|
fh.write(" }\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1147,9 +1144,8 @@ def write_ast_macros(filename):
|
||||||
|
|
||||||
# Only care about leaf classes for the rest
|
# Only care about leaf classes for the rest
|
||||||
if node.isLeaf:
|
if node.isLeaf:
|
||||||
fh.write(
|
fh.write("#define ASTGEN_SUPER_{t}(...) Ast{b}(VNType::{t}, __VA_ARGS__)\n".format(
|
||||||
"#define ASTGEN_SUPER_{t}(...) Ast{b}(VNType::at{t}, __VA_ARGS__)\n".format(
|
t=node.name, b=node.superClass.name))
|
||||||
t=node.name, b=node.superClass.name))
|
|
||||||
fh.write("\n")
|
fh.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1180,7 +1176,7 @@ def write_dfg_macros(filename):
|
||||||
|
|
||||||
if node.isLeaf:
|
if node.isLeaf:
|
||||||
emitBlock('''\
|
emitBlock('''\
|
||||||
static constexpr VDfgType dfgType() {{ return VDfgType::at{t}; }};
|
static constexpr VDfgType dfgType() {{ return VDfgType::{t}; }};
|
||||||
using Super = Dfg{s};
|
using Super = Dfg{s};
|
||||||
void accept(DfgVisitor& v) override {{ v.visit(this); }}
|
void accept(DfgVisitor& v) override {{ v.visit(this); }}
|
||||||
''',
|
''',
|
||||||
|
|
@ -1249,7 +1245,7 @@ def write_dfg_clone_cases(filename):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
emitBlock('''\
|
emitBlock('''\
|
||||||
case VDfgType::at{t}: {{
|
case VDfgType::{t}: {{
|
||||||
Dfg{t}* const cp = new Dfg{t}{{*clonep, vtx.fileline(), vtx.dtypep()}};
|
Dfg{t}* const cp = new Dfg{t}{{*clonep, vtx.fileline(), vtx.dtypep()}};
|
||||||
vtxp2clonep.emplace(&vtx, cp);
|
vtxp2clonep.emplace(&vtx, cp);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue