mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Localize variables used in multiple functions
Teach V3Localize how to localize variables that are used in multiple functions, if in all functions where they are used, they are always written in whole before being consumed. This allows a lot more variables to be localized (+20k variables on OpenTitan - when building without --trace), and can cause significant performance improvement (OpenTitan simulates 8.5% - build single threaded and withuot --trace).
This commit is contained in:
+32
-4
@@ -37,6 +37,34 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//######################################################################
|
||||
// Convert every WRITE AstVarRef to a READ ref
|
||||
|
||||
class ConvertWriteRefsToRead final : public AstNVisitor {
|
||||
private:
|
||||
// MEMBERS
|
||||
AstNode* m_result = nullptr;
|
||||
|
||||
// CONSTRUCTORS
|
||||
explicit ConvertWriteRefsToRead(AstNode* nodep) {
|
||||
m_result = iterateSubtreeReturnEdits(nodep);
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
void visit(AstVarRef* nodep) override {
|
||||
UASSERT_OBJ(!nodep->access().isRW(), nodep, "Cannot handle a READWRITE reference");
|
||||
if (nodep->access().isWriteOnly()) {
|
||||
nodep->replaceWith(
|
||||
new AstVarRef(nodep->fileline(), nodep->varScopep(), VAccess::READ));
|
||||
}
|
||||
}
|
||||
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
static AstNode* main(AstNode* nodep) { return ConvertWriteRefsToRead(nodep).m_result; }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Clock state, as a visitor of each AstNode
|
||||
|
||||
@@ -272,14 +300,14 @@ private:
|
||||
// IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; }
|
||||
AstNode* incp = nodep->incp()->unlinkFrBack();
|
||||
AstNode* origp = nodep->origp()->unlinkFrBack();
|
||||
AstNode* changep = nodep->changep()->unlinkFrBack();
|
||||
AstIf* newp = new AstIf(nodep->fileline(), new AstXor(nodep->fileline(), origp, changep),
|
||||
AstNode* changeWrp = nodep->changep()->unlinkFrBack();
|
||||
AstNode* changeRdp = ConvertWriteRefsToRead::main(changeWrp->cloneTree(false));
|
||||
AstIf* newp = new AstIf(nodep->fileline(), new AstXor(nodep->fileline(), origp, changeRdp),
|
||||
incp, nullptr);
|
||||
// We could add another IF to detect posedges, and only increment if so.
|
||||
// It's another whole branch though versus a potential memory miss.
|
||||
// We'll go with the miss.
|
||||
newp->addIfsp(
|
||||
new AstAssign(nodep->fileline(), changep->cloneTree(false), origp->cloneTree(false)));
|
||||
newp->addIfsp(new AstAssign(nodep->fileline(), changeWrp, origp->cloneTree(false)));
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user