Implement word size transform for if.

This commit is contained in:
chriseth 2019-05-09 16:47:51 +02:00
parent c3a1c168d0
commit eaee4412da
4 changed files with 26 additions and 11 deletions

View File

@ -36,14 +36,14 @@ add_library(yul
backends/evm/EVMDialect.h
backends/evm/EVMObjectCompiler.cpp
backends/evm/EVMObjectCompiler.h
backends/evm/NoOutputAssembly.h
backends/evm/NoOutputAssembly.cpp
backends/wasm/EWasmCodeTransform.cpp
backends/wasm/EWasmCodeTransform.h
backends/wasm/EWasmObjectCompiler.cpp
backends/wasm/EWasmObjectCompiler.h
backends/wasm/EWasmToText.cpp
backends/wasm/EWasmToText.h
backends/evm/NoOutputAssembly.h
backends/evm/NoOutputAssembly.cpp
backends/wasm/WasmDialect.cpp
backends/wasm/WasmDialect.h
backends/wasm/WordSizeTransform.cpp

View File

@ -44,9 +44,14 @@ void WordSizeTransform::operator()(FunctionCall& _fc)
rewriteFunctionCallArguments(_fc.arguments);
}
void WordSizeTransform::operator()(If&)
void WordSizeTransform::operator()(If& _if)
{
yulAssert(false, "If statement not implemented.");
_if.condition = make_unique<Expression>(FunctionCall{
locationOf(*_if.condition),
Identifier{locationOf(*_if.condition), "or_bool"_yulstring}, // TODO make sure this is not used
expandValueToVector(*_if.condition)
});
(*this)(_if.body);
}
void WordSizeTransform::operator()(Switch&)
@ -181,12 +186,7 @@ void WordSizeTransform::rewriteFunctionCallArguments(vector<Expression>& _args)
_args,
[&](Expression& _e) -> boost::optional<vector<Expression>>
{
// ExpressionSplitter guarantees arguments to be Identifier or Literal
yulAssert(_e.type() == typeid(Identifier) || _e.type() == typeid(Literal), "");
vector<Expression> ret;
for (auto& v: expandValue(_e))
ret.push_back(*v);
return ret;
return expandValueToVector(_e);
}
);
}
@ -236,3 +236,11 @@ array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const
return ret;
}
vector<Expression> WordSizeTransform::expandValueToVector(Expression const& _e)
{
vector<Expression> ret;
for (unique_ptr<Expression>& val: expandValue(_e))
ret.emplace_back(std::move(*val));
return ret;
}

View File

@ -47,6 +47,12 @@ namespace yul
* the value of c4 should be
* ((a1*(2^192) + a2*(2^128) + a3(2^64) + a4) * (b1*(2^192) + b2*(2^128) + b3(2^64) + b4)) & ((1<<64)-1)
*
* The resulting code still uses the EVM builtin functions but assumes that they
* 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.
*
* Prerequisite: Disambiguator, ExpressionSplitter
*/
class WordSizeTransform: public ASTModifier
@ -72,6 +78,7 @@ private:
std::array<YulString, 4> generateU64IdentifierNames(YulString const& _s);
std::array<std::unique_ptr<Expression>, 4> expandValue(Expression const& _e);
std::vector<Expression> expandValueToVector(Expression const& _e);
NameDispenser& m_nameDispenser;
/// maps original u256 variable's name to corresponding u64 variables' names

View File

@ -268,7 +268,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line
else if (m_optimizerStep == "wordSizeTransform")
{
disambiguate();
NameDispenser nameDispenser{*m_dialect, *m_ast}; // TODO: Support WasmDialect in yulOptimizerTest
NameDispenser nameDispenser{*m_dialect, *m_ast};
ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast);
WordSizeTransform::run(*m_ast, nameDispenser);
}