Skip to content

Commit 1b21aa9

Browse files
committed
Add memoization to SSAValueTracker::isSSAWithDependencies
1 parent e954fab commit 1b21aa9

2 files changed

Lines changed: 24 additions & 9 deletions

File tree

libyul/optimiser/SSAValueTracker.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,38 @@ bool SSAValueTracker::isSSAWithDependencies(Expression const* _expression) const
6161
if (_expression == nullptr)
6262
return true;
6363

64+
// Check cache first
65+
auto cacheIt = m_isSSACache.find(_expression);
66+
if (cacheIt != m_isSSACache.end())
67+
return cacheIt->second;
68+
69+
bool result;
6470
if (auto const* functionCall = std::get_if<FunctionCall>(_expression))
6571
{
72+
result = true;
6673
for (auto const& argument: functionCall->arguments)
6774
if (!isSSAWithDependencies(&argument))
68-
return false;
69-
70-
return true;
75+
{
76+
result = false;
77+
break;
78+
}
7179
}
7280
else if (auto const* identifier = std::get_if<Identifier>(_expression))
7381
{
7482
auto const it = m_values.find(identifier->name);
7583
if (it == m_values.end())
76-
return false;
77-
return isSSAWithDependencies(it->second);
84+
result = false;
85+
else
86+
result = isSSAWithDependencies(it->second);
7887
}
7988
else
89+
{
8090
solAssert(std::holds_alternative<Literal>(*_expression), "Impossible expression type");
91+
result = true;
92+
}
8193

82-
return true;
94+
m_isSSACache[_expression] = result;
95+
return result;
8396
}
8497

8598
std::set<YulName> SSAValueTracker::ssaVariables(Block const& _ast)

libyul/optimiser/SSAValueTracker.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <libyul/optimiser/ASTWalker.h>
2626
#include <libyul/AST.h> // Needed for m_zero below.
2727

28-
#include <map>
28+
#include <unordered_map>
2929
#include <set>
3030

3131
namespace solidity::yul
@@ -47,7 +47,7 @@ class SSAValueTracker: public ASTWalker
4747
void operator()(VariableDeclaration const& _varDecl) override;
4848
void operator()(Assignment const& _assignment) override;
4949

50-
std::map<YulName, Expression const*> const& values() const { return m_values; }
50+
std::unordered_map<YulName, Expression const*> const& values() const { return m_values; }
5151
Expression const* value(YulName _name) const { return m_values.at(_name); }
5252

5353
static std::set<YulName> ssaVariables(Block const& _ast);
@@ -62,7 +62,9 @@ class SSAValueTracker: public ASTWalker
6262
/// Special expression whose address will be used in m_values.
6363
/// YulName does not need to be reset because SSAValueTracker is short-lived.
6464
Expression const m_zero{Literal{{}, LiteralKind::Number, LiteralValue(u256{0})}};
65-
std::map<YulName, Expression const*> m_values;
65+
std::unordered_map<YulName, Expression const*> m_values;
66+
/// Cache for isSSAWithDependencies to avoid redundant traversals
67+
mutable std::unordered_map<Expression const*, bool> m_isSSACache;
6668
};
6769

6870
}

0 commit comments

Comments
 (0)