Fix expression simplifying by moving from SSAValueTracker to DataFlowAnalyzer as a base.

This commit is contained in:
chriseth 2019-02-27 12:48:10 +01:00
parent 4c1b0fbafa
commit 477c53a46f
5 changed files with 37 additions and 12 deletions

View File

@ -25,6 +25,7 @@ Bugfixes:
* TypeChecker: Fix internal error and disallow index access on contracts and libraries. * TypeChecker: Fix internal error and disallow index access on contracts and libraries.
* Yul: Properly detect name clashes with functions before their declaration. * Yul: Properly detect name clashes with functions before their declaration.
* Yul: Take builtin functions into account in the compilability checker. * Yul: Take builtin functions into account in the compilability checker.
* Yul Optimizer: Properly take reassignments to variables in sub-expressions into account when replacing in the ExpressionSimplifier.
Build System: Build System:

View File

@ -36,7 +36,7 @@ using namespace dev::solidity;
void ExpressionSimplifier::visit(Expression& _expression) void ExpressionSimplifier::visit(Expression& _expression)
{ {
ASTModifier::visit(_expression); ASTModifier::visit(_expression);
while (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_ssaValues)) while (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_value))
{ {
// Do not apply the rule if it removes non-constant parts of the expression. // Do not apply the rule if it removes non-constant parts of the expression.
// TODO: The check could actually be less strict than "movable". // TODO: The check could actually be less strict than "movable".
@ -53,7 +53,5 @@ void ExpressionSimplifier::visit(Expression& _expression)
void ExpressionSimplifier::run(Dialect const& _dialect, Block& _ast) void ExpressionSimplifier::run(Dialect const& _dialect, Block& _ast)
{ {
SSAValueTracker ssaValues; ExpressionSimplifier{_dialect}(_ast);
ssaValues(_ast);
ExpressionSimplifier{_dialect, ssaValues.values()}(_ast);
} }

View File

@ -22,7 +22,7 @@
#include <libyul/AsmDataForward.h> #include <libyul/AsmDataForward.h>
#include <libyul/optimiser/ASTWalker.h> #include <libyul/optimiser/DataFlowAnalyzer.h>
namespace yul namespace yul
{ {
@ -33,9 +33,12 @@ struct Dialect;
* The component will work best if the code is in SSA form, but * The component will work best if the code is in SSA form, but
* this is not required for correctness. * this is not required for correctness.
* *
* It tracks the current values of variables using the DataFlowAnalyzer
* and takes them into account for replacements.
*
* Prerequisite: Disambiguator. * Prerequisite: Disambiguator.
*/ */
class ExpressionSimplifier: public ASTModifier class ExpressionSimplifier: public DataFlowAnalyzer
{ {
public: public:
using ASTModifier::operator(); using ASTModifier::operator();
@ -43,12 +46,7 @@ public:
static void run(Dialect const& _dialect, Block& _ast); static void run(Dialect const& _dialect, Block& _ast);
private: private:
explicit ExpressionSimplifier(Dialect const& _dialect, std::map<YulString, Expression const*> _ssaValues): explicit ExpressionSimplifier(Dialect const& _dialect): DataFlowAnalyzer(_dialect) {}
m_dialect(_dialect), m_ssaValues(std::move(_ssaValues))
{}
Dialect const& m_dialect;
std::map<YulString, Expression const*> m_ssaValues;
}; };
} }

View File

@ -0,0 +1,12 @@
{
let x := mload(0)
x := 0
mstore(0, add(7, x))
}
// ----
// expressionSimplifier
// {
// let x := mload(0)
// x := 0
// mstore(0, 7)
// }

View File

@ -0,0 +1,16 @@
{
// This tests that a bug is fixed that was related to just taking
// values of SSA variables in account and not clearing them when
// a dependency was reassigned.
pop(foo())
function foo() -> x_9
{
x_9 := sub(1,sub(x_9,1))
mstore(sub(1,div(sub(x_9,1),sub(1,sub(x_9,1)))), 1)
}
}
// ----
// fullSuite
// {
// mstore(1, 1)
// }