Skip to content

Commit 8d3617b

Browse files
authored
Merge pull request ethereum#5655 from ethereum/removeUnassignedVarDefs
Add variable declaration initializer.
2 parents 633dd44 + bc22a25 commit 8d3617b

37 files changed

+249
-349
lines changed

libyul/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@ add_library(yul
4343
optimiser/SyntacticalEquality.cpp
4444
optimiser/UnusedPruner.cpp
4545
optimiser/Utilities.cpp
46-
optimiser/VarDeclPropagator.cpp
46+
optimiser/VarDeclInitializer.cpp
4747
)
4848
target_link_libraries(yul PUBLIC evmasm devcore langutil)

libyul/optimiser/FullInliner.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
168168

169169
m_driver.tentativelyUpdateCodeSize(function->name, m_currentFunction);
170170

171+
static Expression const zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}};
172+
171173
// helper function to create a new variable that is supposed to model
172174
// an existing variable.
173175
auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) {
@@ -176,6 +178,8 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
176178
VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}};
177179
if (_value)
178180
varDecl.value = make_shared<Expression>(std::move(*_value));
181+
else
182+
varDecl.value = make_shared<Expression>(zero);
179183
newStatements.emplace_back(std::move(varDecl));
180184
};
181185

libyul/optimiser/Suite.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <libyul/optimiser/Suite.h>
2222

2323
#include <libyul/optimiser/Disambiguator.h>
24+
#include <libyul/optimiser/VarDeclInitializer.h>
2425
#include <libyul/optimiser/FunctionGrouper.h>
2526
#include <libyul/optimiser/FunctionHoister.h>
2627
#include <libyul/optimiser/ExpressionSplitter.h>
@@ -35,7 +36,6 @@
3536
#include <libyul/optimiser/SSATransform.h>
3637
#include <libyul/optimiser/StructuralSimplifier.h>
3738
#include <libyul/optimiser/RedundantAssignEliminator.h>
38-
#include <libyul/optimiser/VarDeclPropagator.h>
3939
#include <libyul/AsmAnalysisInfo.h>
4040
#include <libyul/AsmData.h>
4141
#include <libyul/AsmPrinter.h>
@@ -56,6 +56,7 @@ void OptimiserSuite::run(
5656

5757
Block ast = boost::get<Block>(Disambiguator(_analysisInfo, reservedIdentifiers)(_ast));
5858

59+
(VarDeclInitializer{})(ast);
5960
(FunctionHoister{})(ast);
6061
(FunctionGrouper{})(ast);
6162
(ForLoopInitRewriter{})(ast);
@@ -68,7 +69,6 @@ void OptimiserSuite::run(
6869
ExpressionSplitter{dispenser}(ast);
6970
SSATransform::run(ast, dispenser);
7071
RedundantAssignEliminator::run(ast);
71-
VarDeclPropagator{}(ast);
7272
RedundantAssignEliminator::run(ast);
7373

7474
CommonSubexpressionEliminator{}(ast);
@@ -95,27 +95,22 @@ void OptimiserSuite::run(
9595
RedundantAssignEliminator::run(ast);
9696
CommonSubexpressionEliminator{}(ast);
9797
FullInliner{ast, dispenser}.run();
98-
VarDeclPropagator{}(ast);
9998
SSATransform::run(ast, dispenser);
10099
RedundantAssignEliminator::run(ast);
101-
VarDeclPropagator{}(ast);
102100
RedundantAssignEliminator::run(ast);
103101
ExpressionSimplifier::run(ast);
104102
StructuralSimplifier{}(ast);
105103
CommonSubexpressionEliminator{}(ast);
106104
SSATransform::run(ast, dispenser);
107105
RedundantAssignEliminator::run(ast);
108-
VarDeclPropagator{}(ast);
109106
RedundantAssignEliminator::run(ast);
110107
UnusedPruner::runUntilStabilised(ast, reservedIdentifiers);
111108
}
112109
ExpressionJoiner::run(ast);
113-
VarDeclPropagator{}(ast);
114110
UnusedPruner::runUntilStabilised(ast);
115111
ExpressionJoiner::run(ast);
116112
UnusedPruner::runUntilStabilised(ast);
117113
ExpressionJoiner::run(ast);
118-
VarDeclPropagator{}(ast);
119114
UnusedPruner::runUntilStabilised(ast);
120115
ExpressionJoiner::run(ast);
121116
UnusedPruner::runUntilStabilised(ast);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
This file is part of solidity.
3+
4+
solidity is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
solidity is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with solidity. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#include <libyul/optimiser/VarDeclInitializer.h>
19+
#include <libyul/AsmData.h>
20+
21+
#include <libdevcore/CommonData.h>
22+
#include <libdevcore/Visitor.h>
23+
24+
using namespace std;
25+
using namespace dev;
26+
using namespace yul;
27+
28+
void VarDeclInitializer::operator()(Block& _block)
29+
{
30+
ASTModifier::operator()(_block);
31+
32+
static Expression const zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}};
33+
34+
using OptionalStatements = boost::optional<vector<Statement>>;
35+
GenericFallbackReturnsVisitor<OptionalStatements, VariableDeclaration> visitor{
36+
[](VariableDeclaration& _varDecl) -> OptionalStatements
37+
{
38+
if (_varDecl.value)
39+
return {};
40+
else if (_varDecl.variables.size() == 1)
41+
{
42+
_varDecl.value = make_shared<Expression>(zero);
43+
return {};
44+
}
45+
else
46+
{
47+
OptionalStatements ret{vector<Statement>{}};
48+
langutil::SourceLocation loc{std::move(_varDecl.location)};
49+
for (auto& var: _varDecl.variables)
50+
ret->push_back(VariableDeclaration{loc, {std::move(var)}, make_shared<Expression>(zero)});
51+
return ret;
52+
}
53+
}
54+
};
55+
iterateReplacing(_block.statements, boost::apply_visitor(visitor));
56+
}

libyul/optimiser/VarDeclInitializer.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
This file is part of solidity.
3+
4+
solidity is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
solidity is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with solidity. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
#pragma once
19+
20+
#include <libyul/AsmDataForward.h>
21+
#include <libyul/optimiser/ASTWalker.h>
22+
23+
namespace yul
24+
{
25+
26+
/**
27+
* Rewrites variable declarations so that all of them are initialized.
28+
* Declarations like ``let x, y`` are split into multiple declaration
29+
* statements.
30+
* Only supports initializing with the zero literal for now.
31+
*/
32+
class VarDeclInitializer: public ASTModifier
33+
{
34+
public:
35+
void operator()(Block& _block) override;
36+
};
37+
38+
}

libyul/optimiser/VarDeclPropagator.cpp

Lines changed: 0 additions & 126 deletions
This file was deleted.

libyul/optimiser/VarDeclPropagator.h

Lines changed: 0 additions & 60 deletions
This file was deleted.

test/libyul/YulOptimizerTest.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <test/Options.h>
2323

2424
#include <libyul/optimiser/BlockFlattener.h>
25-
#include <libyul/optimiser/VarDeclPropagator.h>
25+
#include <libyul/optimiser/VarDeclInitializer.h>
2626
#include <libyul/optimiser/Disambiguator.h>
2727
#include <libyul/optimiser/CommonSubexpressionEliminator.h>
2828
#include <libyul/optimiser/NameCollector.h>
@@ -107,11 +107,8 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
107107
disambiguate();
108108
BlockFlattener{}(*m_ast);
109109
}
110-
else if (m_optimizerStep == "varDeclPropagator")
111-
{
112-
disambiguate();
113-
VarDeclPropagator{}(*m_ast);
114-
}
110+
else if (m_optimizerStep == "varDeclInitializer")
111+
VarDeclInitializer{}(*m_ast);
115112
else if (m_optimizerStep == "forLoopInitRewriter")
116113
{
117114
disambiguate();

0 commit comments

Comments
 (0)