mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Implement word size transform for if.
This commit is contained in:
parent
c3a1c168d0
commit
eaee4412da
@ -36,14 +36,14 @@ add_library(yul
|
|||||||
backends/evm/EVMDialect.h
|
backends/evm/EVMDialect.h
|
||||||
backends/evm/EVMObjectCompiler.cpp
|
backends/evm/EVMObjectCompiler.cpp
|
||||||
backends/evm/EVMObjectCompiler.h
|
backends/evm/EVMObjectCompiler.h
|
||||||
|
backends/evm/NoOutputAssembly.h
|
||||||
|
backends/evm/NoOutputAssembly.cpp
|
||||||
backends/wasm/EWasmCodeTransform.cpp
|
backends/wasm/EWasmCodeTransform.cpp
|
||||||
backends/wasm/EWasmCodeTransform.h
|
backends/wasm/EWasmCodeTransform.h
|
||||||
backends/wasm/EWasmObjectCompiler.cpp
|
backends/wasm/EWasmObjectCompiler.cpp
|
||||||
backends/wasm/EWasmObjectCompiler.h
|
backends/wasm/EWasmObjectCompiler.h
|
||||||
backends/wasm/EWasmToText.cpp
|
backends/wasm/EWasmToText.cpp
|
||||||
backends/wasm/EWasmToText.h
|
backends/wasm/EWasmToText.h
|
||||||
backends/evm/NoOutputAssembly.h
|
|
||||||
backends/evm/NoOutputAssembly.cpp
|
|
||||||
backends/wasm/WasmDialect.cpp
|
backends/wasm/WasmDialect.cpp
|
||||||
backends/wasm/WasmDialect.h
|
backends/wasm/WasmDialect.h
|
||||||
backends/wasm/WordSizeTransform.cpp
|
backends/wasm/WordSizeTransform.cpp
|
||||||
|
@ -44,9 +44,14 @@ void WordSizeTransform::operator()(FunctionCall& _fc)
|
|||||||
rewriteFunctionCallArguments(_fc.arguments);
|
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&)
|
void WordSizeTransform::operator()(Switch&)
|
||||||
@ -181,12 +186,7 @@ void WordSizeTransform::rewriteFunctionCallArguments(vector<Expression>& _args)
|
|||||||
_args,
|
_args,
|
||||||
[&](Expression& _e) -> boost::optional<vector<Expression>>
|
[&](Expression& _e) -> boost::optional<vector<Expression>>
|
||||||
{
|
{
|
||||||
// ExpressionSplitter guarantees arguments to be Identifier or Literal
|
return expandValueToVector(_e);
|
||||||
yulAssert(_e.type() == typeid(Identifier) || _e.type() == typeid(Literal), "");
|
|
||||||
vector<Expression> ret;
|
|
||||||
for (auto& v: expandValue(_e))
|
|
||||||
ret.push_back(*v);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -236,3 +236,11 @@ array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const
|
|||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,12 @@ namespace yul
|
|||||||
* the value of c4 should be
|
* 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)
|
* ((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
|
* Prerequisite: Disambiguator, ExpressionSplitter
|
||||||
*/
|
*/
|
||||||
class WordSizeTransform: public ASTModifier
|
class WordSizeTransform: public ASTModifier
|
||||||
@ -72,6 +78,7 @@ private:
|
|||||||
|
|
||||||
std::array<YulString, 4> generateU64IdentifierNames(YulString const& _s);
|
std::array<YulString, 4> generateU64IdentifierNames(YulString const& _s);
|
||||||
std::array<std::unique_ptr<Expression>, 4> expandValue(Expression const& _e);
|
std::array<std::unique_ptr<Expression>, 4> expandValue(Expression const& _e);
|
||||||
|
std::vector<Expression> expandValueToVector(Expression const& _e);
|
||||||
|
|
||||||
NameDispenser& m_nameDispenser;
|
NameDispenser& m_nameDispenser;
|
||||||
/// maps original u256 variable's name to corresponding u64 variables' names
|
/// maps original u256 variable's name to corresponding u64 variables' names
|
||||||
|
@ -268,7 +268,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line
|
|||||||
else if (m_optimizerStep == "wordSizeTransform")
|
else if (m_optimizerStep == "wordSizeTransform")
|
||||||
{
|
{
|
||||||
disambiguate();
|
disambiguate();
|
||||||
NameDispenser nameDispenser{*m_dialect, *m_ast}; // TODO: Support WasmDialect in yulOptimizerTest
|
NameDispenser nameDispenser{*m_dialect, *m_ast};
|
||||||
ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast);
|
ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast);
|
||||||
WordSizeTransform::run(*m_ast, nameDispenser);
|
WordSizeTransform::run(*m_ast, nameDispenser);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user