3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-07 06:33:24 +00:00

read_liberty: Faster input handling for the liberty lexer

The lexer for liberty files was using istream's `get` and `unget` which
are notorious for bad performance and that showed up during profiling.

This replaces the direct `istream` use with a custom LibertyInputStream
that does its own buffering to provide `get` and `unget` that behave the
same way but are implemented with a fast path that is easy to inline and
optimize.
This commit is contained in:
Jannis Harder 2025-04-01 13:48:44 +02:00
parent c08f72b806
commit 119e998f12
3 changed files with 83 additions and 1 deletions

View file

@ -90,12 +90,43 @@ namespace Yosys
bool eval(dict<std::string, bool>& values);
};
class LibertyInputStream {
std::istream &f;
std::vector<char> buffer;
size_t buf_pos = 0;
size_t buf_end = 0;
bool eof = false;
bool extend_buffer_once();
bool extend_buffer_at_least(size_t size = 1);
YS_COLD int get_cold();
public:
LibertyInputStream(std::istream &f) : f(f) {}
size_t buffered_size() { return buf_end - buf_pos; }
const char *buffered_data() { return buffer.data() + buf_pos; }
int get() {
if (buf_pos == buf_end)
return get_cold();
int c = buffer[buf_pos];
buf_pos += 1;
return c;
}
void unget() {
buf_pos -= 1;
}
};
class LibertyMergedCells;
class LibertyParser
{
friend class LibertyMergedCells;
private:
std::istream &f;
LibertyInputStream f;
int line;
/* lexer return values: