From ecab46c707f6b297c646c9d88cf854a856da10d9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 18 Jun 2019 18:14:49 +0200 Subject: [PATCH] Finish word size transform. --- libyul/backends/wasm/WordSizeTransform.cpp | 26 ++++++++++++++++--- libyul/backends/wasm/WordSizeTransform.h | 9 ++++--- test/libyul/YulOptimizerTest.cpp | 2 +- .../wordSizeTransform/or_bool_renamed.yul | 25 ++++++++++++++++++ 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/wordSizeTransform/or_bool_renamed.yul diff --git a/libyul/backends/wasm/WordSizeTransform.cpp b/libyul/backends/wasm/WordSizeTransform.cpp index 4388eebd1..08d55e296 100644 --- a/libyul/backends/wasm/WordSizeTransform.cpp +++ b/libyul/backends/wasm/WordSizeTransform.cpp @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include @@ -41,6 +43,10 @@ void WordSizeTransform::operator()(FunctionalInstruction& _ins) void WordSizeTransform::operator()(FunctionCall& _fc) { + if (BuiltinFunction const* fun = m_inputDialect.builtin(_fc.functionName.name)) + if (fun->literalArguments) + return; + rewriteFunctionCallArguments(_fc.arguments); } @@ -48,7 +54,7 @@ void WordSizeTransform::operator()(If& _if) { _if.condition = make_unique(FunctionCall{ locationOf(*_if.condition), - Identifier{locationOf(*_if.condition), "or_bool"_yulstring}, // TODO make sure this is not used + Identifier{locationOf(*_if.condition), "or_bool"_yulstring}, expandValueToVector(*_if.condition) }); (*this)(_if.body); @@ -59,6 +65,18 @@ void WordSizeTransform::operator()(Switch&) yulAssert(false, "Switch statement not implemented."); } +void WordSizeTransform::operator()(ForLoop& _for) +{ + (*this)(_for.pre); + _for.condition = make_unique(FunctionCall{ + locationOf(*_for.condition), + Identifier{locationOf(*_for.condition), "or_bool"_yulstring}, + expandValueToVector(*_for.condition) + }); + (*this)(_for.post); + (*this)(_for.body); +} + void WordSizeTransform::operator()(Block& _block) { iterateReplacing( @@ -142,9 +160,11 @@ void WordSizeTransform::operator()(Block& _block) ); } -void WordSizeTransform::run(Block& _ast, NameDispenser& _nameDispenser) +void WordSizeTransform::run(Dialect const& _inputDialect, Block& _ast, NameDispenser& _nameDispenser) { - WordSizeTransform{_nameDispenser}(_ast); + // Free the name `or_bool`. + NameDisplacer{_nameDispenser, {"or_bool"_yulstring}}(_ast); + WordSizeTransform{_inputDialect, _nameDispenser}(_ast); } void WordSizeTransform::rewriteVarDeclList(TypedNameList& _nameList) diff --git a/libyul/backends/wasm/WordSizeTransform.h b/libyul/backends/wasm/WordSizeTransform.h index 8c71b9817..42bf58940 100644 --- a/libyul/backends/wasm/WordSizeTransform.h +++ b/libyul/backends/wasm/WordSizeTransform.h @@ -51,7 +51,7 @@ namespace yul * take four times the parameters and each of type u64. * In addition, it uses a single other builtin function called `or_bool` that * takes four u64 parameters and is supposed to return the logical disjunction - * of them es a u64 value. + * of them as a u64 value. If this name is already used somewhere, it is renamed. * * Prerequisite: Disambiguator, ExpressionSplitter */ @@ -63,12 +63,14 @@ public: void operator()(FunctionCall&) override; void operator()(If&) override; void operator()(Switch&) override; + void operator()(ForLoop&) override; void operator()(Block& _block) override; - static void run(Block& _ast, NameDispenser& _nameDispenser); + static void run(Dialect const& _inputDialect, Block& _ast, NameDispenser& _nameDispenser); private: - explicit WordSizeTransform(NameDispenser& _nameDispenser): + explicit WordSizeTransform(Dialect const& _inputDialect, NameDispenser& _nameDispenser): + m_inputDialect(_inputDialect), m_nameDispenser(_nameDispenser) { } @@ -80,6 +82,7 @@ private: std::array, 4> expandValue(Expression const& _e); std::vector expandValueToVector(Expression const& _e); + Dialect const& m_inputDialect; NameDispenser& m_nameDispenser; /// maps original u256 variable's name to corresponding u64 variables' names std::map> m_variableMapping; diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 07ab58dd6..b5f397d17 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -297,7 +297,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line disambiguate(); NameDispenser nameDispenser{*m_dialect, *m_ast}; ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast); - WordSizeTransform::run(*m_ast, nameDispenser); + WordSizeTransform::run(*m_dialect, *m_ast, nameDispenser); } else if (m_optimizerStep == "fullSuite") { diff --git a/test/libyul/yulOptimizerTests/wordSizeTransform/or_bool_renamed.yul b/test/libyul/yulOptimizerTests/wordSizeTransform/or_bool_renamed.yul new file mode 100644 index 000000000..016dd9bb8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/wordSizeTransform/or_bool_renamed.yul @@ -0,0 +1,25 @@ +{ + let or_bool := 2 + if or_bool { sstore(0, 1) } +} +// ==== +// step: wordSizeTransform +// ---- +// { +// let or_bool_3_0 := 0 +// let or_bool_3_1 := 0 +// let or_bool_3_2 := 0 +// let or_bool_3_3 := 2 +// if or_bool(or_bool_3_0, or_bool_3_1, or_bool_3_2, or_bool_3_3) +// { +// let _1_0 := 0 +// let _1_1 := 0 +// let _1_2 := 0 +// let _1_3 := 1 +// let _2_0 := 0 +// let _2_1 := 0 +// let _2_2 := 0 +// let _2_3 := 0 +// sstore(_2_0, _2_1, _2_2, _2_3, _1_0, _1_1, _1_2, _1_3) +// } +// }