3
0
Fork 0
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:
whitequark 2020-12-13 07:03:16 +00:00
parent 3b5a1314cd
commit ece25a45d4
5 changed files with 278 additions and 71 deletions

View file

@ -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 &register_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 &register_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) {