forked from github/verilator
Add --dump-tree-addrids developer option
This commit is contained in:
parent
95534fa5c5
commit
656c460605
@ -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
|
||||
|
@ -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::
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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; }
|
||||
|
Loading…
Reference in New Issue
Block a user