Merge pull request #11891 from ethereum/guidedRematerializer

Allow the Rematerializer to be restricted to an exact set of variables.
This commit is contained in:
chriseth 2021-09-06 16:22:14 +02:00 committed by GitHub
commit be95a8172b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 16 deletions

View File

@ -32,39 +32,44 @@ using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::yul; using namespace solidity::yul;
void Rematerialiser::run(Dialect const& _dialect, Block& _ast, set<YulString> _varsToAlwaysRematerialize) void Rematerialiser::run(Dialect const& _dialect, Block& _ast, set<YulString> _varsToAlwaysRematerialize, bool _onlySelectedVariables)
{ {
Rematerialiser{_dialect, _ast, std::move(_varsToAlwaysRematerialize)}(_ast); Rematerialiser{_dialect, _ast, std::move(_varsToAlwaysRematerialize), _onlySelectedVariables}(_ast);
} }
void Rematerialiser::run( void Rematerialiser::run(
Dialect const& _dialect, Dialect const& _dialect,
FunctionDefinition& _function, FunctionDefinition& _function,
set<YulString> _varsToAlwaysRematerialize set<YulString> _varsToAlwaysRematerialize,
bool _onlySelectedVariables
) )
{ {
Rematerialiser{_dialect, _function, std::move(_varsToAlwaysRematerialize)}(_function); Rematerialiser{_dialect, _function, std::move(_varsToAlwaysRematerialize), _onlySelectedVariables}(_function);
} }
Rematerialiser::Rematerialiser( Rematerialiser::Rematerialiser(
Dialect const& _dialect, Dialect const& _dialect,
Block& _ast, Block& _ast,
set<YulString> _varsToAlwaysRematerialize set<YulString> _varsToAlwaysRematerialize,
bool _onlySelectedVariables
): ):
DataFlowAnalyzer(_dialect), DataFlowAnalyzer(_dialect),
m_referenceCounts(ReferencesCounter::countReferences(_ast)), m_referenceCounts(ReferencesCounter::countReferences(_ast)),
m_varsToAlwaysRematerialize(std::move(_varsToAlwaysRematerialize)) m_varsToAlwaysRematerialize(std::move(_varsToAlwaysRematerialize)),
m_onlySelectedVariables(_onlySelectedVariables)
{ {
} }
Rematerialiser::Rematerialiser( Rematerialiser::Rematerialiser(
Dialect const& _dialect, Dialect const& _dialect,
FunctionDefinition& _function, FunctionDefinition& _function,
set<YulString> _varsToAlwaysRematerialize set<YulString> _varsToAlwaysRematerialize,
bool _onlySelectedVariables
): ):
DataFlowAnalyzer(_dialect), DataFlowAnalyzer(_dialect),
m_referenceCounts(ReferencesCounter::countReferences(_function)), m_referenceCounts(ReferencesCounter::countReferences(_function)),
m_varsToAlwaysRematerialize(std::move(_varsToAlwaysRematerialize)) m_varsToAlwaysRematerialize(std::move(_varsToAlwaysRematerialize)),
m_onlySelectedVariables(_onlySelectedVariables)
{ {
} }
@ -81,10 +86,13 @@ void Rematerialiser::visit(Expression& _e)
size_t refs = m_referenceCounts[name]; size_t refs = m_referenceCounts[name];
size_t cost = CodeCost::codeCost(m_dialect, *value.value); size_t cost = CodeCost::codeCost(m_dialect, *value.value);
if ( if (
(refs <= 1 && value.loopDepth == m_loopDepth) || (
cost == 0 || !m_onlySelectedVariables && (
(refs <= 5 && cost <= 1 && m_loopDepth == 0) || (refs <= 1 && value.loopDepth == m_loopDepth) ||
m_varsToAlwaysRematerialize.count(name) cost == 0 ||
(refs <= 5 && cost <= 1 && m_loopDepth == 0)
)
) || m_varsToAlwaysRematerialize.count(name)
) )
{ {
assertThrow(m_referenceCounts[name] > 0, OptimizerException, ""); assertThrow(m_referenceCounts[name] > 0, OptimizerException, "");

View File

@ -50,24 +50,28 @@ public:
static void run( static void run(
Dialect const& _dialect, Dialect const& _dialect,
Block& _ast, Block& _ast,
std::set<YulString> _varsToAlwaysRematerialize = {} std::set<YulString> _varsToAlwaysRematerialize = {},
bool _onlySelectedVariables = false
); );
static void run( static void run(
Dialect const& _dialect, Dialect const& _dialect,
FunctionDefinition& _function, FunctionDefinition& _function,
std::set<YulString> _varsToAlwaysRematerialize = {} std::set<YulString> _varsToAlwaysRematerialize = {},
bool _onlySelectedVariables = false
); );
protected: protected:
Rematerialiser( Rematerialiser(
Dialect const& _dialect, Dialect const& _dialect,
Block& _ast, Block& _ast,
std::set<YulString> _varsToAlwaysRematerialize = {} std::set<YulString> _varsToAlwaysRematerialize = {},
bool _onlySelectedVariables = false
); );
Rematerialiser( Rematerialiser(
Dialect const& _dialect, Dialect const& _dialect,
FunctionDefinition& _function, FunctionDefinition& _function,
std::set<YulString> _varsToAlwaysRematerialize = {} std::set<YulString> _varsToAlwaysRematerialize = {},
bool _onlySelectedVariables = false
); );
using DataFlowAnalyzer::operator(); using DataFlowAnalyzer::operator();
@ -77,6 +81,7 @@ protected:
std::map<YulString, size_t> m_referenceCounts; std::map<YulString, size_t> m_referenceCounts;
std::set<YulString> m_varsToAlwaysRematerialize; std::set<YulString> m_varsToAlwaysRematerialize;
bool m_onlySelectedVariables = false;
}; };
/** /**