Add --dump-tree-addrids developer option

This commit is contained in:
Geza Lore 2020-05-23 18:31:30 +01:00
parent 95534fa5c5
commit 656c460605
7 changed files with 63 additions and 15 deletions

View File

@ -300,6 +300,7 @@ detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
--dump-tree Enable dumping .tree files
--dump-treei <level> Enable dumping .tree files at a level
--dump-treei-<srcfile> <level> Enable dumping .tree file at a source file at a level
--dump-tree-addrids Use short identifiers instead of addresses
-E Preprocess, but do not compile
--error-limit <value> Abort after this number of errors
--exe Link to create executable
@ -812,6 +813,14 @@ file to the specified tree dumping level (e.g. C<--dump-treei-V3Order 9>).
Level 0 disbles dumps and is equivalent to "--no-dump-tree". Level 9
enables dumping of every stage.
=item --dump-tree-addrids
Rarely needed - for developer use. Replace AST node addresses with short
identifiers in tree dumps to enhance readability. Each unique pointer value
is mapped to a unique identifier, but note that this is not necessarily
unique per node instance as an address might get reused by a newly allocated
node after a node with the same address has been dumped then freed.
=item -E
Preprocess the source code, but do not compile, as with 'gcc -E'. Output

View File

@ -850,7 +850,10 @@ correspond directly to Verilog entities (for example `MODULE` and
Address of the node::
A hexadecimal address of the node in memory. Useful for examining with the
debugger.
debugger. If the actual address values are not important, then using the
`--dump-tree-addrids` option will convert address values to short identifiers
of the form `([A-Z]*)`, which is hopefully easier for the reader to cross
reference throughout the dump.
Last edit number::

View File

@ -964,28 +964,37 @@ void AstWhile::addNextStmt(AstNode* newp, AstNode* belowp) {
//======================================================================
// Per-type Debugging
// Render node address for dumps. By default this is just the address
// printed as hex, but with --dump-tree-addrids we map addresses to short
// strings with a bijection to aid human readability. Observe that this might
// not actually be a unique identifier as the address can get reused after a
// node has been freed.
static std::string nodeAddr(const AstNode* nodep) {
return v3Global.opt.dumpTreeAddrids() ? v3Global.ptrToId(nodep) : cvtToHex(nodep);
}
void AstNode::dump(std::ostream& str) const {
str << typeName() << " "
<< cvtToHex(this)
//<<" "<<cvtToHex(this)->m_backp
<< nodeAddr(this)
//<< " " << nodeAddr(m_backp)
<< " <e" << std::dec << editCount() << ((editCount() >= editCountLast()) ? "#>" : ">")
<< " {" << fileline()->filenameLetters() << std::dec << fileline()->lastLineno()
<< fileline()->firstColumnLetters() << "}";
if (user1p()) str << " u1=" << cvtToHex(user1p());
if (user2p()) str << " u2=" << cvtToHex(user2p());
if (user3p()) str << " u3=" << cvtToHex(user3p());
if (user4p()) str << " u4=" << cvtToHex(user4p());
if (user5p()) str << " u5=" << cvtToHex(user5p());
if (user1p()) str << " u1=" << nodeAddr(user1p());
if (user2p()) str << " u2=" << nodeAddr(user2p());
if (user3p()) str << " u3=" << nodeAddr(user3p());
if (user4p()) str << " u4=" << nodeAddr(user4p());
if (user5p()) str << " u5=" << nodeAddr(user5p());
if (hasDType()) {
// Final @ so less likely to by accident read it as a nodep
if (dtypep() == this) {
str << " @dt=this@";
} else {
str << " @dt=" << cvtToHex(dtypep()) << "@";
str << " @dt=" << nodeAddr(dtypep()) << "@";
}
if (AstNodeDType* dtp = dtypep()) { dtp->dumpSmall(str); }
} else { // V3Broken will throw an error
if (dtypep()) str << " %Error-dtype-exp=null,got=" << cvtToHex(dtypep());
if (dtypep()) str << " %Error-dtype-exp=null,got=" << nodeAddr(dtypep());
}
if (name() != "") {
if (VN_IS(this, Const)) {
@ -1240,7 +1249,7 @@ void AstNodeDType::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (generic()) str << " [GENERIC]";
if (AstNodeDType* dtp = virtRefDTypep()) {
str << " refdt=" << cvtToHex(dtp);
str << " refdt=" << nodeAddr(dtp);
dtp->dumpSmall(str);
}
}
@ -1385,7 +1394,7 @@ void AstVarScope::dump(std::ostream& str) const {
}
void AstVarXRef::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (packagep()) { str << " pkg=" << cvtToHex(packagep()); }
if (packagep()) { str << " pkg=" << nodeAddr(packagep()); }
if (lvalue()) {
str << " [LV] => ";
} else {
@ -1403,7 +1412,7 @@ void AstVarXRef::dump(std::ostream& str) const {
}
void AstVarRef::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (packagep()) { str << " pkg=" << cvtToHex(packagep()); }
if (packagep()) { str << " pkg=" << nodeAddr(packagep()); }
if (lvalue()) {
str << " [LV] => ";
} else {
@ -1455,7 +1464,7 @@ void AstParseRef::dump(std::ostream& str) const {
}
void AstPackageRef::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (packagep()) { str << " pkg=" << cvtToHex(packagep()); }
if (packagep()) { str << " pkg=" << nodeAddr(packagep()); }
str << " -> ";
if (packagep()) {
packagep()->dump(str);
@ -1478,7 +1487,7 @@ void AstActive::dump(std::ostream& str) const {
}
void AstNodeFTaskRef::dump(std::ostream& str) const {
this->AstNode::dump(str);
if (packagep()) { str << " pkg=" << cvtToHex(packagep()); }
if (packagep()) { str << " pkg=" << nodeAddr(packagep()); }
str << " -> ";
if (dotted() != "") { str << ".=" << dotted() << " "; }
if (taskp()) {

View File

@ -80,3 +80,20 @@ void V3Global::dumpCheckGlobalTree(const string& stagename, int newNumber, bool
doDump);
if (v3Global.opt.stats()) V3Stats::statsStage(stagename);
}
const std::string& V3Global::ptrToId(const void* p) {
PtrToIdMap::iterator it = m_ptrToId.find(p);
if (it == m_ptrToId.end()) {
std::ostringstream os;
if (p) {
os << "(";
unsigned id = m_ptrToId.size();
do { os << static_cast<char>('A' + id % 26); } while (id /= 26);
os << ")";
} else {
os << "0";
}
it = m_ptrToId.insert(std::make_pair(p, os.str())).first;
}
return it->second;
}

View File

@ -31,6 +31,7 @@
#include "V3Options.h"
#include <string>
#include VL_INCLUDE_UNORDERED_MAP
class AstNetlist;
@ -79,6 +80,10 @@ class V3Global {
bool m_dpi; // Need __Dpi include files
bool m_useParallelBuild; // Use parallel build for model
// Memory address to short string mapping (for debug)
typedef vl_unordered_map<const void*, std::string> PtrToIdMap; // The map type
PtrToIdMap m_ptrToId; // The actual 'address' <=> 'short string' bijection
public:
// Options
V3Options opt; // All options; let user see them directly
@ -133,6 +138,7 @@ public:
void dpi(bool flag) { m_dpi = flag; }
void useParallelBuild(bool flag) { m_useParallelBuild = flag; }
bool useParallelBuild() const { return m_useParallelBuild; }
const std::string& ptrToId(const void* p);
};
extern V3Global v3Global;

View File

@ -856,6 +856,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-dpi-hdr-only", flag/*ref*/)) { m_dpiHdrOnly = flag; }
else if ( onoff (sw, "-dump-defines", flag/*ref*/)) { m_dumpDefines = flag; }
else if ( onoff (sw, "-dump-tree", flag/*ref*/)) { m_dumpTree = flag ? 3 : 0; } // Also see --dump-treei
else if ( onoff (sw, "-dump-tree-addrids", flag/*ref*/)){ m_dumpTreeAddrids = flag; }
else if ( onoff (sw, "-exe", flag/*ref*/)) { m_exe = flag; }
else if ( onoff (sw, "-flatten", flag/*ref*/)) { m_flatten = flag; }
else if ( onoff (sw, "-ignc", flag/*ref*/)) { m_ignc = flag; }
@ -1612,6 +1613,7 @@ V3Options::V3Options() {
m_buildJobs = 1;
m_convergeLimit = 100;
m_dumpTree = 0;
m_dumpTreeAddrids = false;
m_gateStmts = 100;
m_ifDepth = 0;
m_inlineMult = 2000;

View File

@ -276,6 +276,7 @@ private:
int m_buildJobs; // main switch: -j
int m_convergeLimit;// main switch: --converge-limit
int m_dumpTree; // main switch: --dump-tree
bool m_dumpTreeAddrids;// main switch: --dump-tree-addrids
int m_gateStmts; // main switch: --gate-stmts
int m_ifDepth; // main switch: --if-depth
int m_inlineMult; // main switch: --inline-mult
@ -468,6 +469,7 @@ public:
int buildJobs() const { return m_buildJobs; }
int convergeLimit() const { return m_convergeLimit; }
int dumpTree() const { return m_dumpTree; }
bool dumpTreeAddrids() const { return m_dumpTreeAddrids; }
int gateStmts() const { return m_gateStmts; }
int ifDepth() const { return m_ifDepth; }
int inlineMult() const { return m_inlineMult; }