mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-22 22:03:40 +00:00
cxxrtl: implement debug information outlining.
Aggressive wire localization and inlining is necessary for CXXRTL to achieve high performance. However, that comes with a cost: reduced debug information coverage. Previously, as a workaround, the `-Og` option could have been used to guarantee complete coverage, at a cost of a significant performance penalty. This commit introduces debug information outlining. The main eval() function is compiled with the user-specified optimization settings. In tandem, an auxiliary debug_eval() function, compiled from the same netlist, can be used to reconstruct the values of localized/inlined signals on demand. To the extent that it is possible, debug_eval() reuses the results of computations performed by eval(), only filling in the missing values. Benchmarking a representative design (Minerva SoC SRAM) shows that: * Switching from `-O4`/`-Og` to `-O6` reduces runtime by ~40%. * Switching from `-g1` to `-g2`, both used with `-O6`, increases compile time by ~25%. * Although `-g2` increases the resident size of generated modules, this has no effect on runtime. Because the impact of `-g2` is minimal and the benefits of having unconditional 100% debug information coverage (and the performance improvement as well) are major, this commit removes `-Og` and changes the defaults to `-O6 -g2`. We'll have our cake and eat it too!
This commit is contained in:
parent
3b5a1314cd
commit
ece25a45d4
5 changed files with 278 additions and 71 deletions
|
@ -28,10 +28,13 @@ class vcd_writer {
|
|||
size_t ident;
|
||||
size_t width;
|
||||
chunk_t *curr;
|
||||
size_t prev_off;
|
||||
size_t cache_offset;
|
||||
debug_outline *outline;
|
||||
bool *outline_warm;
|
||||
};
|
||||
|
||||
std::vector<std::string> current_scope;
|
||||
std::map<debug_outline*, bool> outlines;
|
||||
std::vector<variable> variables;
|
||||
std::vector<chunk_t> cache;
|
||||
std::map<chunk_t*, size_t> aliases;
|
||||
|
@ -112,16 +115,22 @@ class vcd_writer {
|
|||
buffer += '\n';
|
||||
}
|
||||
|
||||
const variable ®ister_variable(size_t width, chunk_t *curr, bool constant = false) {
|
||||
void reset_outlines() {
|
||||
for (auto &outline_it : outlines)
|
||||
outline_it.second = /*warm=*/(outline_it.first == nullptr);
|
||||
}
|
||||
|
||||
variable ®ister_variable(size_t width, chunk_t *curr, bool constant = false, debug_outline *outline = nullptr) {
|
||||
if (aliases.count(curr)) {
|
||||
return variables[aliases[curr]];
|
||||
} else {
|
||||
auto outline_it = outlines.emplace(outline, /*warm=*/(outline == nullptr)).first;
|
||||
const size_t chunks = (width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8);
|
||||
aliases[curr] = variables.size();
|
||||
if (constant) {
|
||||
variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1 });
|
||||
variables.emplace_back(variable { variables.size(), width, curr, (size_t)-1, outline_it->first, &outline_it->second });
|
||||
} else {
|
||||
variables.emplace_back(variable { variables.size(), width, curr, cache.size() });
|
||||
variables.emplace_back(variable { variables.size(), width, curr, cache.size(), outline_it->first, &outline_it->second });
|
||||
cache.insert(cache.end(), &curr[0], &curr[chunks]);
|
||||
}
|
||||
return variables.back();
|
||||
|
@ -129,13 +138,17 @@ class vcd_writer {
|
|||
}
|
||||
|
||||
bool test_variable(const variable &var) {
|
||||
if (var.prev_off == (size_t)-1)
|
||||
if (var.cache_offset == (size_t)-1)
|
||||
return false; // constant
|
||||
if (!*var.outline_warm) {
|
||||
var.outline->eval();
|
||||
*var.outline_warm = true;
|
||||
}
|
||||
const size_t chunks = (var.width + (sizeof(chunk_t) * 8 - 1)) / (sizeof(chunk_t) * 8);
|
||||
if (std::equal(&var.curr[0], &var.curr[chunks], &cache[var.prev_off])) {
|
||||
if (std::equal(&var.curr[0], &var.curr[chunks], &cache[var.cache_offset])) {
|
||||
return false;
|
||||
} else {
|
||||
std::copy(&var.curr[0], &var.curr[chunks], &cache[var.prev_off]);
|
||||
std::copy(&var.curr[0], &var.curr[chunks], &cache[var.cache_offset]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +210,10 @@ public:
|
|||
emit_var(register_variable(item.width, item.curr),
|
||||
"wire", name, item.lsb_at, multipart);
|
||||
break;
|
||||
case debug_item::OUTLINE:
|
||||
emit_var(register_variable(item.width, item.curr, /*constant=*/false, item.outline),
|
||||
"wire", name, item.lsb_at, multipart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,6 +245,7 @@ public:
|
|||
emit_scope({});
|
||||
emit_enddefinitions();
|
||||
}
|
||||
reset_outlines();
|
||||
emit_time(timestamp);
|
||||
for (auto var : variables)
|
||||
if (test_variable(var) || first_sample) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue