mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Only count variables if only variables are needed.
This commit is contained in:
parent
310a58dd31
commit
f1febf69d0
@ -668,10 +668,9 @@ bool statementNeedsReturnVariableSetup(Statement const& _statement, vector<Typed
|
|||||||
holds_alternative<Assignment>(_statement)
|
holds_alternative<Assignment>(_statement)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ReferencesCounter referencesCounter{ReferencesCounter::CountWhat::OnlyVariables};
|
map<YulString, size_t> references = VariableReferencesCounter::countReferences(_statement);
|
||||||
referencesCounter.visit(_statement);
|
auto isReferenced = [&references](TypedName const& _returnVariable) {
|
||||||
auto isReferenced = [&referencesCounter](TypedName const& _returnVariable) {
|
return references.count(_returnVariable.name);
|
||||||
return referencesCounter.references().count(_returnVariable.name);
|
|
||||||
};
|
};
|
||||||
if (ranges::none_of(_returnVariables, isReferenced))
|
if (ranges::none_of(_returnVariables, isReferenced))
|
||||||
return false;
|
return false;
|
||||||
|
@ -86,7 +86,7 @@ void ExpressionJoiner::visit(Expression& _e)
|
|||||||
|
|
||||||
ExpressionJoiner::ExpressionJoiner(Block& _ast)
|
ExpressionJoiner::ExpressionJoiner(Block& _ast)
|
||||||
{
|
{
|
||||||
m_references = ReferencesCounter::countReferences(_ast);
|
m_references = VariableReferencesCounter::countReferences(_ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExpressionJoiner::handleArguments(vector<Expression>& _arguments)
|
void ExpressionJoiner::handleArguments(vector<Expression>& _arguments)
|
||||||
|
@ -71,7 +71,7 @@ bool LoopInvariantCodeMotion::canBePromoted(
|
|||||||
return false;
|
return false;
|
||||||
if (_varDecl.value)
|
if (_varDecl.value)
|
||||||
{
|
{
|
||||||
for (auto const& ref: ReferencesCounter::countReferences(*_varDecl.value, ReferencesCounter::OnlyVariables))
|
for (auto const& ref: VariableReferencesCounter::countReferences(*_varDecl.value))
|
||||||
if (_varsDefinedInCurrentScope.count(ref.first) || !m_ssaVariables.count(ref.first))
|
if (_varsDefinedInCurrentScope.count(ref.first) || !m_ssaVariables.count(ref.first))
|
||||||
return false;
|
return false;
|
||||||
SideEffectsCollector sideEffects{m_dialect, *_varDecl.value, &m_functionSideEffects};
|
SideEffectsCollector sideEffects{m_dialect, *_varDecl.value, &m_functionSideEffects};
|
||||||
|
@ -56,30 +56,62 @@ void ReferencesCounter::operator()(Identifier const& _identifier)
|
|||||||
|
|
||||||
void ReferencesCounter::operator()(FunctionCall const& _funCall)
|
void ReferencesCounter::operator()(FunctionCall const& _funCall)
|
||||||
{
|
{
|
||||||
if (m_countWhat == VariablesAndFunctions)
|
++m_references[_funCall.functionName.name];
|
||||||
++m_references[_funCall.functionName.name];
|
|
||||||
ASTWalker::operator()(_funCall);
|
ASTWalker::operator()(_funCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<YulString, size_t> ReferencesCounter::countReferences(Block const& _block, CountWhat _countWhat)
|
map<YulString, size_t> ReferencesCounter::countReferences(Block const& _block)
|
||||||
{
|
{
|
||||||
ReferencesCounter counter(_countWhat);
|
ReferencesCounter counter;
|
||||||
counter(_block);
|
counter(_block);
|
||||||
return counter.references();
|
return std::move(counter.m_references);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<YulString, size_t> ReferencesCounter::countReferences(FunctionDefinition const& _function, CountWhat _countWhat)
|
map<YulString, size_t> ReferencesCounter::countReferences(FunctionDefinition const& _function)
|
||||||
{
|
{
|
||||||
ReferencesCounter counter(_countWhat);
|
ReferencesCounter counter;
|
||||||
counter(_function);
|
counter(_function);
|
||||||
return counter.references();
|
return std::move(counter.m_references);
|
||||||
}
|
}
|
||||||
|
|
||||||
map<YulString, size_t> ReferencesCounter::countReferences(Expression const& _expression, CountWhat _countWhat)
|
map<YulString, size_t> ReferencesCounter::countReferences(Expression const& _expression)
|
||||||
{
|
{
|
||||||
ReferencesCounter counter(_countWhat);
|
ReferencesCounter counter;
|
||||||
counter.visit(_expression);
|
counter.visit(_expression);
|
||||||
return counter.references();
|
return std::move(counter.m_references);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VariableReferencesCounter::operator()(Identifier const& _identifier)
|
||||||
|
{
|
||||||
|
++m_references[_identifier.name];
|
||||||
|
}
|
||||||
|
|
||||||
|
map<YulString, size_t> VariableReferencesCounter::countReferences(Block const& _block)
|
||||||
|
{
|
||||||
|
VariableReferencesCounter counter;
|
||||||
|
counter(_block);
|
||||||
|
return std::move(counter.m_references);
|
||||||
|
}
|
||||||
|
|
||||||
|
map<YulString, size_t> VariableReferencesCounter::countReferences(FunctionDefinition const& _function)
|
||||||
|
{
|
||||||
|
VariableReferencesCounter counter;
|
||||||
|
counter(_function);
|
||||||
|
return std::move(counter.m_references);
|
||||||
|
}
|
||||||
|
|
||||||
|
map<YulString, size_t> VariableReferencesCounter::countReferences(Expression const& _expression)
|
||||||
|
{
|
||||||
|
VariableReferencesCounter counter;
|
||||||
|
counter.visit(_expression);
|
||||||
|
return std::move(counter.m_references);
|
||||||
|
}
|
||||||
|
|
||||||
|
map<YulString, size_t> VariableReferencesCounter::countReferences(Statement const& _statement)
|
||||||
|
{
|
||||||
|
VariableReferencesCounter counter;
|
||||||
|
counter.visit(_statement);
|
||||||
|
return std::move(counter.m_references);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentsSinceContinue::operator()(ForLoop const& _forLoop)
|
void AssignmentsSinceContinue::operator()(ForLoop const& _forLoop)
|
||||||
|
@ -71,23 +71,33 @@ private:
|
|||||||
class ReferencesCounter: public ASTWalker
|
class ReferencesCounter: public ASTWalker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum CountWhat { VariablesAndFunctions, OnlyVariables };
|
|
||||||
|
|
||||||
explicit ReferencesCounter(CountWhat _countWhat = VariablesAndFunctions):
|
|
||||||
m_countWhat(_countWhat)
|
|
||||||
{}
|
|
||||||
|
|
||||||
using ASTWalker::operator ();
|
using ASTWalker::operator ();
|
||||||
void operator()(Identifier const& _identifier) override;
|
void operator()(Identifier const& _identifier) override;
|
||||||
void operator()(FunctionCall const& _funCall) override;
|
void operator()(FunctionCall const& _funCall) override;
|
||||||
|
|
||||||
static std::map<YulString, size_t> countReferences(Block const& _block, CountWhat _countWhat = VariablesAndFunctions);
|
static std::map<YulString, size_t> countReferences(Block const& _block);
|
||||||
static std::map<YulString, size_t> countReferences(FunctionDefinition const& _function, CountWhat _countWhat = VariablesAndFunctions);
|
static std::map<YulString, size_t> countReferences(FunctionDefinition const& _function);
|
||||||
static std::map<YulString, size_t> countReferences(Expression const& _expression, CountWhat _countWhat = VariablesAndFunctions);
|
static std::map<YulString, size_t> countReferences(Expression const& _expression);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::map<YulString, size_t> m_references;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specific AST walker that counts all references to all variable declarations.
|
||||||
|
*/
|
||||||
|
class VariableReferencesCounter: public ASTWalker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using ASTWalker::operator ();
|
||||||
|
void operator()(Identifier const& _identifier) override;
|
||||||
|
|
||||||
|
static std::map<YulString, size_t> countReferences(Block const& _block);
|
||||||
|
static std::map<YulString, size_t> countReferences(FunctionDefinition const& _function);
|
||||||
|
static std::map<YulString, size_t> countReferences(Expression const& _expression);
|
||||||
|
static std::map<YulString, size_t> countReferences(Statement const& _statement);
|
||||||
|
|
||||||
std::map<YulString, size_t> const& references() const { return m_references; }
|
|
||||||
private:
|
private:
|
||||||
CountWhat m_countWhat = CountWhat::VariablesAndFunctions;
|
|
||||||
std::map<YulString, size_t> m_references;
|
std::map<YulString, size_t> m_references;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ Rematerialiser::Rematerialiser(
|
|||||||
bool _onlySelectedVariables
|
bool _onlySelectedVariables
|
||||||
):
|
):
|
||||||
DataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore),
|
DataFlowAnalyzer(_dialect, MemoryAndStorage::Ignore),
|
||||||
m_referenceCounts(ReferencesCounter::countReferences(_ast)),
|
m_referenceCounts(VariableReferencesCounter::countReferences(_ast)),
|
||||||
m_varsToAlwaysRematerialize(std::move(_varsToAlwaysRematerialize)),
|
m_varsToAlwaysRematerialize(std::move(_varsToAlwaysRematerialize)),
|
||||||
m_onlySelectedVariables(_onlySelectedVariables)
|
m_onlySelectedVariables(_onlySelectedVariables)
|
||||||
{
|
{
|
||||||
@ -77,7 +77,9 @@ void Rematerialiser::visit(Expression& _e)
|
|||||||
{
|
{
|
||||||
// update reference counts
|
// update reference counts
|
||||||
m_referenceCounts[name]--;
|
m_referenceCounts[name]--;
|
||||||
for (auto const& ref: ReferencesCounter::countReferences(*value->value))
|
for (auto const& ref: VariableReferencesCounter::countReferences(
|
||||||
|
*value->value
|
||||||
|
))
|
||||||
m_referenceCounts[ref.first] += ref.second;
|
m_referenceCounts[ref.first] += ref.second;
|
||||||
_e = (ASTCopier{}).translate(*value->value);
|
_e = (ASTCopier{}).translate(*value->value);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ using namespace solidity::yul::unusedFunctionsCommon;
|
|||||||
|
|
||||||
void UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ast)
|
void UnusedFunctionParameterPruner::run(OptimiserStepContext& _context, Block& _ast)
|
||||||
{
|
{
|
||||||
map<YulString, size_t> references = ReferencesCounter::countReferences(_ast);
|
map<YulString, size_t> references = VariableReferencesCounter::countReferences(_ast);
|
||||||
auto used = [&](auto v) -> bool { return references.count(v.name); };
|
auto used = [&](auto v) -> bool { return references.count(v.name); };
|
||||||
|
|
||||||
// Function name and a pair of boolean masks, the first corresponds to parameters and the second
|
// Function name and a pair of boolean masks, the first corresponds to parameters and the second
|
||||||
|
Loading…
Reference in New Issue
Block a user