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

Liberty file caching with new libcache command

This adds optional in-memory caching of parsed liberty files to speed up
flows that repeatedly parse the same liberty files. To avoid increasing
the memory overhead by default, the caching is disabled by default. The
caching can be controlled globally or on a per path basis using the new
`libcache` command, which also allows purging cached data.
This commit is contained in:
Jannis Harder 2025-04-03 13:11:48 +02:00
parent 26a4b9b0c6
commit 0f13b55173
9 changed files with 253 additions and 17 deletions

View file

@ -132,6 +132,22 @@ namespace Yosys
}
};
#ifndef FILTERLIB
class LibertyAstCache {
LibertyAstCache() {};
~LibertyAstCache() {};
public:
dict<std::string, std::shared_ptr<const LibertyAst>> cached;
bool cache_by_default = false;
dict<std::string, bool> cache_path;
std::shared_ptr<const LibertyAst> cached_ast(const std::string &fname);
void parsed_ast(const std::string &fname, const std::shared_ptr<const LibertyAst> &ast);
static LibertyAstCache instance;
};
#endif
class LibertyMergedCells;
class LibertyParser
{
@ -152,15 +168,29 @@ namespace Yosys
void error(const std::string &str) const;
public:
const LibertyAst *ast;
std::shared_ptr<const LibertyAst> shared_ast;
const LibertyAst *ast = nullptr;
LibertyParser(std::istream &f) : f(f), line(1), ast(parse()) {}
~LibertyParser() { if (ast) delete ast; }
LibertyParser(std::istream &f) : f(f), line(1) {
shared_ast.reset(parse());
ast = shared_ast.get();
}
#ifndef FILTERLIB
LibertyParser(std::istream &f, const std::string &fname) : f(f), line(1) {
shared_ast = LibertyAstCache::instance.cached_ast(fname);
if (!shared_ast) {
shared_ast.reset(parse());
LibertyAstCache::instance.parsed_ast(fname, shared_ast);
}
ast = shared_ast.get();
}
#endif
};
class LibertyMergedCells
{
std::vector<const LibertyAst *> asts;
std::vector<std::shared_ptr<const LibertyAst>> asts;
public:
std::vector<const LibertyAst *> cells;
@ -168,10 +198,7 @@ namespace Yosys
{
if (parser.ast) {
const LibertyAst *ast = parser.ast;
asts.push_back(ast);
// The parser no longer owns its top level ast, but we do.
// sketchy zone
parser.ast = nullptr;
asts.push_back(parser.shared_ast);
if (ast->id != "library")
parser.error("Top level entity isn't \"library\".\n");
for (const LibertyAst *cell : ast->children)
@ -179,11 +206,6 @@ namespace Yosys
cells.push_back(cell);
}
}
~LibertyMergedCells()
{
for (auto ast : asts)
delete ast;
}
};
}