mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
Fix of localize for super constructors with function calls as arguments (#6330)
This commit is contained in:
+20
-2
@@ -45,6 +45,9 @@ class LocalizeVisitor final : public VNVisitor {
|
||||
// AstVarScope::user3p() -> Set of CFuncs referencing this VarScope. (via m_accessors)
|
||||
// AstCFunc::user4p() -> Multimap of 'VarScope -> VarRefs that reference that VarScope'
|
||||
// in this function. (via m_references)
|
||||
// AstVarScope::user4() -> Bool indicating VarScope cannot be optimized
|
||||
// - compared to AstVarScope::user1 this guarantees that this
|
||||
// scope won't be optimized.
|
||||
const VNUser1InUse m_user1InUse;
|
||||
const VNUser3InUse m_user3InUse;
|
||||
const VNUser4InUse m_user4InUse;
|
||||
@@ -60,11 +63,15 @@ class LocalizeVisitor final : public VNVisitor {
|
||||
// STATE - for current visit position (use VL_RESTORER)
|
||||
AstCFunc* m_cfuncp = nullptr; // Current active function
|
||||
uint32_t m_nodeDepth = 0; // Node depth under m_cfuncp
|
||||
bool m_inSuperConstructorCallStmt = false; // If under super constructor call statement
|
||||
|
||||
// METHODS
|
||||
bool isOptimizable(AstVarScope* nodep) {
|
||||
// Don't want to malloc/free the backing store all the time
|
||||
if (VN_IS(nodep->dtypep(), NBACommitQueueDType)) return false;
|
||||
// Variables used in super constructor call can't be localized, because
|
||||
// in C++ there is no way to declare them before base class constructor call
|
||||
if (nodep->user4()) return false;
|
||||
return ((!nodep->user1() // Not marked as not optimizable, or ...
|
||||
// .. a block temp used in a single CFunc
|
||||
|| (nodep->varp()->varType() == VVarType::BLOCKTEMP
|
||||
@@ -147,6 +154,14 @@ class LocalizeVisitor final : public VNVisitor {
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
|
||||
void visit(AstCNew* nodep) override {
|
||||
VL_RESTORER(m_inSuperConstructorCallStmt);
|
||||
m_inSuperConstructorCallStmt
|
||||
= m_cfuncp->isConstructor() && VN_IS(nodep->backp(), StmtExpr);
|
||||
m_cfuncp->user1(true); // Mark caller as not a leaf function
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
void visit(AstCCall* nodep) override {
|
||||
m_cfuncp->user1(true); // Mark caller as not a leaf function
|
||||
iterateChildrenConst(nodep);
|
||||
@@ -195,8 +210,11 @@ class LocalizeVisitor final : public VNVisitor {
|
||||
// Remember the reference so we can fix it up later (we always need this as well)
|
||||
m_references(m_cfuncp).emplace(varScopep, nodep);
|
||||
|
||||
// Check if already marked as not optimizable
|
||||
if (!varScopep->user1()) {
|
||||
if (m_inSuperConstructorCallStmt) {
|
||||
// Variable used in super constructor call can't be localized
|
||||
varScopep->user1(true);
|
||||
varScopep->user4(true);
|
||||
} else if (!varScopep->user1()) { // Check if already marked as not optimizable
|
||||
// Note: we only check read variables, as it's ok to localize (and in fact discard)
|
||||
// any variables that are only written but never read.
|
||||
if (nodep->access().isReadOrRW() && !varScopep->user2()) {
|
||||
|
||||
Reference in New Issue
Block a user