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:
Geza Lore
2021-06-18 16:22:51 +01:00
parent d6237e55b2
commit e5e5bc0fa3
4 changed files with 121 additions and 117 deletions
+32 -4
View File
@@ -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);
}