mirror of
https://github.com/YosysHQ/yosys
synced 2025-05-11 17:54:44 +00:00
ast: add GC for dev debugging
This commit is contained in:
parent
272b7fa697
commit
d8cae1d904
3 changed files with 104 additions and 0 deletions
|
@ -248,6 +248,9 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch
|
||||||
children.push_back(child4);
|
children.push_back(child4);
|
||||||
|
|
||||||
fixup_hierarchy_flags();
|
fixup_hierarchy_flags();
|
||||||
|
#ifdef ASTNODE_GC
|
||||||
|
Tagger::get().reg(this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a (deep recursive) copy of a node
|
// create a (deep recursive) copy of a node
|
||||||
|
@ -283,12 +286,28 @@ void AstNode::cloneInto(AstNode *other) const
|
||||||
// delete all children in this node
|
// delete all children in this node
|
||||||
void AstNode::delete_children()
|
void AstNode::delete_children()
|
||||||
{
|
{
|
||||||
|
#ifdef ASTNODE_GC
|
||||||
|
for (auto &it : children)
|
||||||
|
if (Tagger::get().nodes.count(it))
|
||||||
|
delete it;
|
||||||
|
else
|
||||||
|
log("skip child %p\n", it);
|
||||||
|
#else
|
||||||
for (auto &it : children)
|
for (auto &it : children)
|
||||||
delete it;
|
delete it;
|
||||||
|
#endif
|
||||||
children.clear();
|
children.clear();
|
||||||
|
|
||||||
|
#ifdef ASTNODE_GC
|
||||||
|
for (auto &it : attributes)
|
||||||
|
if (Tagger::get().nodes.count(it.second))
|
||||||
|
delete it.second;
|
||||||
|
else
|
||||||
|
log("skip attr %p\n", it.second);
|
||||||
|
#else
|
||||||
for (auto &it : attributes)
|
for (auto &it : attributes)
|
||||||
delete it.second;
|
delete it.second;
|
||||||
|
#endif
|
||||||
attributes.clear();
|
attributes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +315,14 @@ void AstNode::delete_children()
|
||||||
AstNode::~AstNode()
|
AstNode::~AstNode()
|
||||||
{
|
{
|
||||||
astnodes--;
|
astnodes--;
|
||||||
|
#ifdef ASTNODE_GC
|
||||||
|
Tagger::get().unreg(this);
|
||||||
|
#endif
|
||||||
delete_children();
|
delete_children();
|
||||||
|
if (yosys_xtrace) {
|
||||||
|
log("DESTR %X %p\n", hashidx_, this);
|
||||||
|
log_backtrace("", yosys_xtrace-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a nice text representation of the node
|
// create a nice text representation of the node
|
||||||
|
|
|
@ -467,6 +467,72 @@ namespace AST_INTERNAL
|
||||||
AST::AstNode *original_ast = nullptr);
|
AST::AstNode *original_ast = nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef ASTNODE_GC
|
||||||
|
#ifdef ASTNODE_GC
|
||||||
|
struct Tagger {
|
||||||
|
std::set<AST::AstNode*> nodes;
|
||||||
|
std::set<AST::AstNode*> tagged;
|
||||||
|
static Tagger& get() {
|
||||||
|
static Tagger instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
void reg(AST::AstNode* p) {
|
||||||
|
if (!p)
|
||||||
|
return;
|
||||||
|
log_assert(!nodes.count(p));
|
||||||
|
nodes.insert(p);
|
||||||
|
}
|
||||||
|
void unreg(AST::AstNode* p) {
|
||||||
|
if (!p || !nodes.count(p))
|
||||||
|
return;
|
||||||
|
nodes.erase(p);
|
||||||
|
}
|
||||||
|
void tag(AST::AstNode* p) {
|
||||||
|
if (!p)
|
||||||
|
return;
|
||||||
|
tagged.insert(p);
|
||||||
|
for (AST::AstNode* c : p->children)
|
||||||
|
tag(c);
|
||||||
|
for (auto x : p->attributes)
|
||||||
|
tag(x.second);
|
||||||
|
tag(p->id2ast);
|
||||||
|
}
|
||||||
|
void clear() {
|
||||||
|
tagged.clear();
|
||||||
|
}
|
||||||
|
void dump_untagged() {
|
||||||
|
Yosys::log("Dumping untagged:\n");
|
||||||
|
for (auto p : nodes) {
|
||||||
|
if (!tagged.count(p)) {
|
||||||
|
Yosys::log(">> %p\n", p);
|
||||||
|
p->dumpAst(stdout, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void shadow_kill(AST::AstNode* p) {
|
||||||
|
if (!p || !nodes.count(p))
|
||||||
|
return;
|
||||||
|
for (AST::AstNode* c : p->children)
|
||||||
|
shadow_kill(c);
|
||||||
|
for (auto x : p->attributes)
|
||||||
|
shadow_kill(x.second);
|
||||||
|
shadow_kill(p->id2ast);
|
||||||
|
delete p;
|
||||||
|
}
|
||||||
|
void kill_untagged() {
|
||||||
|
auto copy = nodes;
|
||||||
|
while (!copy.empty()) {
|
||||||
|
AST::AstNode* p = *(copy.begin());
|
||||||
|
copy.erase(p);
|
||||||
|
fflush(stdout);
|
||||||
|
if (!tagged.count(p)) {
|
||||||
|
shadow_kill(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // ASTNODE_GC
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
YOSYS_NAMESPACE_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
YOSYS_NAMESPACE_BEGIN
|
YOSYS_NAMESPACE_BEGIN
|
||||||
using namespace VERILOG_FRONTEND;
|
using namespace VERILOG_FRONTEND;
|
||||||
|
|
||||||
|
|
||||||
// use the Verilog bison/flex parser to generate an AST and use AST::process() to convert it to RTLIL
|
// use the Verilog bison/flex parser to generate an AST and use AST::process() to convert it to RTLIL
|
||||||
|
|
||||||
static std::vector<std::string> verilog_defaults;
|
static std::vector<std::string> verilog_defaults;
|
||||||
|
@ -528,7 +529,15 @@ struct VerilogFrontend : public Frontend {
|
||||||
|
|
||||||
AST::process(design, current_ast, flag_nodisplay, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches,
|
AST::process(design, current_ast, flag_nodisplay, flag_dump_ast1, flag_dump_ast2, flag_no_dump_ptr, flag_dump_vlog1, flag_dump_vlog2, flag_dump_rtlil, flag_nolatches,
|
||||||
flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
|
flag_nomeminit, flag_nomem2reg, flag_mem2reg, flag_noblackbox, lib_mode, flag_nowb, flag_noopt, flag_icells, flag_pwires, flag_nooverwrite, flag_overwrite, flag_defer, default_nettype_wire);
|
||||||
|
#ifdef ASTNODE_GC
|
||||||
|
Tagger::get().clear();
|
||||||
|
Tagger::get().tag(current_ast);
|
||||||
|
for (RTLIL::Module* m : design->modules())
|
||||||
|
if (AST::AstModule* am = dynamic_cast<AST::AstModule*>(m))
|
||||||
|
Tagger::get().tag(am->ast);
|
||||||
|
|
||||||
|
Tagger::get().dump_untagged();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!flag_nopp)
|
if (!flag_nopp)
|
||||||
delete lexin;
|
delete lexin;
|
||||||
|
@ -539,6 +548,9 @@ struct VerilogFrontend : public Frontend {
|
||||||
|
|
||||||
delete current_ast;
|
delete current_ast;
|
||||||
current_ast = NULL;
|
current_ast = NULL;
|
||||||
|
#ifdef ASTNODE_GC
|
||||||
|
Tagger::get().kill_untagged();
|
||||||
|
#endif
|
||||||
|
|
||||||
log("Successfully finished Verilog frontend.\n");
|
log("Successfully finished Verilog frontend.\n");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue