mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10419 from ethereum/bug-namesimplifier
Fix a bug in NameSimplifier.
This commit is contained in:
commit
27e44b85e3
@ -15,6 +15,8 @@ Compiler Features:
|
|||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Code generator: Do not pad empty string literals with a single 32-byte zero field in the ABI coder v1.
|
* Code generator: Do not pad empty string literals with a single 32-byte zero field in the ABI coder v1.
|
||||||
* SMTChecker: Fix internal compiler error when doing bitwise compound assignment with string literals.
|
* SMTChecker: Fix internal compiler error when doing bitwise compound assignment with string literals.
|
||||||
|
* Yul Optimizer: Fix a bug in NameSimplifier where a new name created by NameSimplifier could also be created by NameDispenser.
|
||||||
|
* Yul Optimizer: Removed NameSimplifier from optimization steps available to users.
|
||||||
|
|
||||||
### 0.7.5 (2020-11-18)
|
### 0.7.5 (2020-11-18)
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ namespace solidity::frontend
|
|||||||
struct OptimiserSettings
|
struct OptimiserSettings
|
||||||
{
|
{
|
||||||
static char constexpr DefaultYulOptimiserSteps[] =
|
static char constexpr DefaultYulOptimiserSteps[] =
|
||||||
"NdhfoDgvulfnTUtnIf" // None of these can make stack problems worse
|
"dhfoDgvulfnTUtnIf" // None of these can make stack problems worse
|
||||||
"["
|
"["
|
||||||
"xarrscLM" // Turn into SSA and simplify
|
"xarrscLM" // Turn into SSA and simplify
|
||||||
"cCTUtTOntnfDIul" // Perform structural simplification
|
"cCTUtTOntnfDIul" // Perform structural simplification
|
||||||
@ -47,7 +47,7 @@ struct OptimiserSettings
|
|||||||
"gvif" // Run full inliner
|
"gvif" // Run full inliner
|
||||||
"CTUcarrLsTOtfDncarrIulc" // SSA plus simplify
|
"CTUcarrLsTOtfDncarrIulc" // SSA plus simplify
|
||||||
"]"
|
"]"
|
||||||
"jmuljuljul VcTOcul jmulN"; // Make source short and pretty
|
"jmuljuljul VcTOcul jmul"; // Make source short and pretty
|
||||||
|
|
||||||
/// No optimisations at all - not recommended.
|
/// No optimisations at all - not recommended.
|
||||||
static OptimiserSettings none()
|
static OptimiserSettings none()
|
||||||
|
@ -35,8 +35,9 @@ using namespace solidity::yul;
|
|||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
|
|
||||||
NameDispenser::NameDispenser(Dialect const& _dialect, Block const& _ast, set<YulString> _reservedNames):
|
NameDispenser::NameDispenser(Dialect const& _dialect, Block const& _ast, set<YulString> _reservedNames):
|
||||||
NameDispenser(_dialect, NameCollector(_ast).names() + std::move(_reservedNames))
|
NameDispenser(_dialect, NameCollector(_ast).names() + _reservedNames)
|
||||||
{
|
{
|
||||||
|
m_reservedNames = move(_reservedNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
NameDispenser::NameDispenser(Dialect const& _dialect, set<YulString> _usedNames):
|
NameDispenser::NameDispenser(Dialect const& _dialect, set<YulString> _usedNames):
|
||||||
@ -61,3 +62,9 @@ bool NameDispenser::illegalName(YulString _name)
|
|||||||
{
|
{
|
||||||
return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name);
|
return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NameDispenser::reset(Block const& _ast)
|
||||||
|
{
|
||||||
|
m_usedNames = NameCollector(_ast).names() + m_reservedNames;
|
||||||
|
m_counter = 0;
|
||||||
|
}
|
||||||
|
@ -51,11 +51,19 @@ public:
|
|||||||
/// return it.
|
/// return it.
|
||||||
void markUsed(YulString _name) { m_usedNames.insert(_name); }
|
void markUsed(YulString _name) { m_usedNames.insert(_name); }
|
||||||
|
|
||||||
private:
|
std::set<YulString> const& usedNames() { return m_usedNames; }
|
||||||
|
|
||||||
|
/// Returns true if `_name` is either used or is a restricted identifier.
|
||||||
bool illegalName(YulString _name);
|
bool illegalName(YulString _name);
|
||||||
|
|
||||||
|
/// Resets `m_usedNames` with *only* the names that are used in the AST. Also resets value of
|
||||||
|
/// `m_counter` to zero.
|
||||||
|
void reset(Block const& _ast);
|
||||||
|
|
||||||
|
private:
|
||||||
Dialect const& m_dialect;
|
Dialect const& m_dialect;
|
||||||
std::set<YulString> m_usedNames;
|
std::set<YulString> m_usedNames;
|
||||||
|
std::set<YulString> m_reservedNames;
|
||||||
size_t m_counter = 0;
|
size_t m_counter = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <libyul/optimiser/NameCollector.h>
|
#include <libyul/optimiser/NameCollector.h>
|
||||||
#include <libyul/AST.h>
|
#include <libyul/AST.h>
|
||||||
#include <libyul/Dialect.h>
|
#include <libyul/Dialect.h>
|
||||||
|
#include <libyul/YulString.h>
|
||||||
|
#include <libyul/optimiser/NameDispenser.h>
|
||||||
#include <libyul/optimiser/OptimizerUtilities.h>
|
#include <libyul/optimiser/OptimizerUtilities.h>
|
||||||
|
|
||||||
#include <libsolutil/CommonData.h>
|
#include <libsolutil/CommonData.h>
|
||||||
@ -28,19 +30,13 @@
|
|||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
NameSimplifier::NameSimplifier(
|
NameSimplifier::NameSimplifier(OptimiserStepContext& _context, Block const& _ast):
|
||||||
OptimiserStepContext& _context,
|
m_context(_context)
|
||||||
Block const& _ast
|
|
||||||
):
|
|
||||||
m_context(_context),
|
|
||||||
m_usedNames(_context.reservedIdentifiers)
|
|
||||||
{
|
{
|
||||||
for (YulString name: m_usedNames)
|
for (YulString name: _context.reservedIdentifiers)
|
||||||
m_translations[name] = name;
|
m_translations[name] = name;
|
||||||
|
|
||||||
set<YulString> allNames = NameCollector(_ast).names();
|
for (YulString const& name: NameCollector(_ast).names())
|
||||||
m_usedNames += allNames;
|
|
||||||
for (YulString name: allNames)
|
|
||||||
findSimplification(name);
|
findSimplification(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +73,7 @@ void NameSimplifier::operator()(FunctionCall& _funCall)
|
|||||||
ASTModifier::operator()(_funCall);
|
ASTModifier::operator()(_funCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NameSimplifier::findSimplification(YulString _name)
|
void NameSimplifier::findSimplification(YulString const& _name)
|
||||||
{
|
{
|
||||||
if (m_translations.count(_name))
|
if (m_translations.count(_name))
|
||||||
return;
|
return;
|
||||||
@ -98,19 +94,19 @@ void NameSimplifier::findSimplification(YulString _name)
|
|||||||
{regex("index_access_t_array"), "index_access"},
|
{regex("index_access_t_array"), "index_access"},
|
||||||
{regex("[0-9]*_$"), ""}
|
{regex("[0-9]*_$"), ""}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto const& [pattern, substitute]: replacements)
|
for (auto const& [pattern, substitute]: replacements)
|
||||||
{
|
{
|
||||||
string candidate = regex_replace(name, pattern, substitute);
|
string candidate = regex_replace(name, pattern, substitute);
|
||||||
if (
|
if (!m_context.dispenser.illegalName(YulString(candidate)))
|
||||||
!isRestrictedIdentifier(m_context.dialect, YulString(candidate)) &&
|
|
||||||
!m_usedNames.count(YulString(candidate))
|
|
||||||
)
|
|
||||||
name = candidate;
|
name = candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name != _name.str())
|
if (name != _name.str())
|
||||||
{
|
{
|
||||||
m_usedNames.insert(YulString(name));
|
YulString newName{name};
|
||||||
m_translations[_name] = YulString(name);
|
m_context.dispenser.markUsed(newName);
|
||||||
|
m_translations[_name] = move(newName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,19 +57,15 @@ public:
|
|||||||
void operator()(FunctionDefinition& _funDef) override;
|
void operator()(FunctionDefinition& _funDef) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NameSimplifier(
|
NameSimplifier(OptimiserStepContext& _context, Block const& _ast);
|
||||||
OptimiserStepContext& _context,
|
|
||||||
Block const& _ast
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Tries to rename a list of variables.
|
/// Tries to rename a list of variables.
|
||||||
void renameVariables(std::vector<TypedName>& _variables);
|
void renameVariables(std::vector<TypedName>& _variables);
|
||||||
|
|
||||||
void findSimplification(YulString _name);
|
void findSimplification(YulString const& _name);
|
||||||
void translate(YulString& _name);
|
void translate(YulString& _name);
|
||||||
|
|
||||||
OptimiserStepContext& m_context;
|
OptimiserStepContext& m_context;
|
||||||
std::set<YulString> m_usedNames;
|
|
||||||
std::map<YulString, YulString> m_translations;
|
std::map<YulString, YulString> m_translations;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ void OptimiserSuite::run(
|
|||||||
// ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely.
|
// ForLoopInitRewriter. Run them first to be able to run arbitrary sequences safely.
|
||||||
suite.runSequence("hfgo", ast);
|
suite.runSequence("hfgo", ast);
|
||||||
|
|
||||||
|
NameSimplifier::run(suite.m_context, ast);
|
||||||
// Now the user-supplied part
|
// Now the user-supplied part
|
||||||
suite.runSequence(_optimisationSequence, ast);
|
suite.runSequence(_optimisationSequence, ast);
|
||||||
|
|
||||||
@ -140,6 +141,9 @@ void OptimiserSuite::run(
|
|||||||
if (ast.statements.size() > 1 && std::get<Block>(ast.statements.front()).statements.empty())
|
if (ast.statements.size() > 1 && std::get<Block>(ast.statements.front()).statements.empty())
|
||||||
ast.statements.erase(ast.statements.begin());
|
ast.statements.erase(ast.statements.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suite.m_dispenser.reset(ast);
|
||||||
|
NameSimplifier::run(suite.m_context, ast);
|
||||||
VarNameCleaner::run(suite.m_context, ast);
|
VarNameCleaner::run(suite.m_context, ast);
|
||||||
|
|
||||||
*_object.analysisInfo = AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object);
|
*_object.analysisInfo = AsmAnalyzer::analyzeStrictAssertCorrect(_dialect, _object);
|
||||||
@ -191,7 +195,6 @@ map<string, unique_ptr<OptimiserStep>> const& OptimiserSuite::allSteps()
|
|||||||
LiteralRematerialiser,
|
LiteralRematerialiser,
|
||||||
LoadResolver,
|
LoadResolver,
|
||||||
LoopInvariantCodeMotion,
|
LoopInvariantCodeMotion,
|
||||||
NameSimplifier,
|
|
||||||
RedundantAssignEliminator,
|
RedundantAssignEliminator,
|
||||||
ReasoningBasedSimplifier,
|
ReasoningBasedSimplifier,
|
||||||
Rematerialiser,
|
Rematerialiser,
|
||||||
@ -203,6 +206,7 @@ map<string, unique_ptr<OptimiserStep>> const& OptimiserSuite::allSteps()
|
|||||||
VarDeclInitializer
|
VarDeclInitializer
|
||||||
>();
|
>();
|
||||||
// Does not include VarNameCleaner because it destroys the property of unique names.
|
// Does not include VarNameCleaner because it destroys the property of unique names.
|
||||||
|
// Does not include NameSimplifier.
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +234,6 @@ map<string, char> const& OptimiserSuite::stepNameToAbbreviationMap()
|
|||||||
{LiteralRematerialiser::name, 'T'},
|
{LiteralRematerialiser::name, 'T'},
|
||||||
{LoadResolver::name, 'L'},
|
{LoadResolver::name, 'L'},
|
||||||
{LoopInvariantCodeMotion::name, 'M'},
|
{LoopInvariantCodeMotion::name, 'M'},
|
||||||
{NameSimplifier::name, 'N'},
|
|
||||||
{ReasoningBasedSimplifier::name, 'R'},
|
{ReasoningBasedSimplifier::name, 'R'},
|
||||||
{RedundantAssignEliminator::name, 'r'},
|
{RedundantAssignEliminator::name, 'r'},
|
||||||
{Rematerialiser::name, 'm'},
|
{Rematerialiser::name, 'm'},
|
||||||
|
@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_strin
|
|||||||
|
|
||||||
BOOST_TEST(chromosome.length() == allSteps.size());
|
BOOST_TEST(chromosome.length() == allSteps.size());
|
||||||
BOOST_TEST(chromosome.optimisationSteps() == allSteps);
|
BOOST_TEST(chromosome.optimisationSteps() == allSteps);
|
||||||
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMNRrmVatpud");
|
BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighTLMRrmVatpud");
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(optimisationSteps_should_translate_chromosomes_genes_to_optimisation_step_names)
|
BOOST_AUTO_TEST_CASE(optimisationSteps_should_translate_chromosomes_genes_to_optimisation_step_names)
|
||||||
|
Loading…
Reference in New Issue
Block a user