mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6715 from ethereum/wordSizeTransformForIf
Word size transform for if
This commit is contained in:
commit
8e3d394803
@ -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
|
||||
|
@ -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&)
|
||||
@ -149,13 +154,8 @@ void WordSizeTransform::rewriteVarDeclList(TypedNameList& _nameList)
|
||||
[&](TypedName const& _n) -> boost::optional<TypedNameList>
|
||||
{
|
||||
TypedNameList ret;
|
||||
yulAssert(m_variableMapping.find(_n.name) == m_variableMapping.end(), "");
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
auto newName = m_nameDispenser.newName(_n.name);
|
||||
m_variableMapping[_n.name][i] = newName;
|
||||
ret.push_back(TypedName{_n.location, newName, "u64"_yulstring});
|
||||
}
|
||||
for (auto newName: generateU64IdentifierNames(_n.name))
|
||||
ret.emplace_back(TypedName{_n.location, newName, "u64"_yulstring});
|
||||
return ret;
|
||||
}
|
||||
);
|
||||
@ -181,12 +181,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);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -194,14 +189,9 @@ void WordSizeTransform::rewriteFunctionCallArguments(vector<Expression>& _args)
|
||||
array<YulString, 4> WordSizeTransform::generateU64IdentifierNames(YulString const& _s)
|
||||
{
|
||||
yulAssert(m_variableMapping.find(_s) == m_variableMapping.end(), "");
|
||||
array<YulString, 4> ret;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
auto newName = m_nameDispenser.newName(_s);
|
||||
m_variableMapping[_s][i] = newName;
|
||||
ret[i] = newName;
|
||||
}
|
||||
return ret;
|
||||
m_variableMapping[_s][i] = m_nameDispenser.newName(YulString{_s.str() + "_" + to_string(i)});
|
||||
return m_variableMapping[_s];
|
||||
}
|
||||
|
||||
array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const& _e)
|
||||
@ -236,3 +226,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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -7,12 +7,12 @@
|
||||
// step: wordSizeTransform
|
||||
// ----
|
||||
// {
|
||||
// let val_1 := 196678011949
|
||||
// let val_2 := 17592899865401375162
|
||||
// let val_3 := 3392951883154430155
|
||||
// let val_4 := 12452437124710337234
|
||||
// val_1 := 1573424111353538
|
||||
// val_2 := 11180339179422519519
|
||||
// val_3 := 5225342777609112214
|
||||
// val_4 := 12264064093151869674
|
||||
// let val_0 := 196678011949
|
||||
// let val_1 := 17592899865401375162
|
||||
// let val_2 := 3392951883154430155
|
||||
// let val_3 := 12452437124710337234
|
||||
// val_0 := 1573424111353538
|
||||
// val_1 := 11180339179422519519
|
||||
// val_2 := 5225342777609112214
|
||||
// val_3 := 12264064093151869674
|
||||
// }
|
||||
|
@ -16,28 +16,28 @@
|
||||
// step: wordSizeTransform
|
||||
// ----
|
||||
// {
|
||||
// function swap(x_2, x_3, x_4, x_5, y_6, y_7, y_8, y_9) -> a_10, a_11, a_12, a_13, b_14, b_15, b_16, b_17
|
||||
// function swap(x_0, x_1, x_2, x_3, y_0, y_1, y_2, y_3) -> a_0, a_1, a_2, a_3, b_0, b_1, b_2, b_3
|
||||
// {
|
||||
// a_10 := y_6
|
||||
// a_11 := y_7
|
||||
// a_12 := y_8
|
||||
// a_13 := y_9
|
||||
// b_14 := x_2
|
||||
// b_15 := x_3
|
||||
// b_16 := x_4
|
||||
// b_17 := x_5
|
||||
// a_0 := y_0
|
||||
// a_1 := y_1
|
||||
// a_2 := y_2
|
||||
// a_3 := y_3
|
||||
// b_0 := x_0
|
||||
// b_1 := x_1
|
||||
// b_2 := x_2
|
||||
// b_3 := x_3
|
||||
// }
|
||||
// function main(v1_18, v1_19, v1_20, v1_21, v2_22, v2_23, v2_24, v2_25) -> r1_26, r1_27, r1_28, r1_29, r2_30, r2_31, r2_32, r2_33
|
||||
// function main(v1_0, v1_1, v1_2, v1_3, v2_0, v2_1, v2_2, v2_3) -> r1_0, r1_1, r1_2, r1_3, r2_0, r2_1, r2_2, r2_3
|
||||
// {
|
||||
// let tmp_34 := 1770102123480502530
|
||||
// let tmp_35 := 591943673742124792
|
||||
// let tmp_36 := 13663686148824196892
|
||||
// let tmp_37 := 8198552921648689607
|
||||
// r1_26, r1_27, r1_28, r1_29, r2_30, r2_31, r2_32, r2_33 := swap(v1_18, v1_19, v1_20, v1_21, tmp_34, tmp_35, tmp_36, tmp_37)
|
||||
// let _1_38 := 354020424
|
||||
// let _1_39 := 12840787883880108911
|
||||
// let _1_40 := 12527970737989311368
|
||||
// let _1_41 := 16397105843297379214
|
||||
// r1_26, r1_27, r1_28, r1_29, r2_30, r2_31, r2_32, r2_33 := swap(_1_38, _1_39, _1_40, _1_41, r2_30, r2_31, r2_32, r2_33)
|
||||
// let tmp_0 := 1770102123480502530
|
||||
// let tmp_1 := 591943673742124792
|
||||
// let tmp_2 := 13663686148824196892
|
||||
// let tmp_3 := 8198552921648689607
|
||||
// r1_0, r1_1, r1_2, r1_3, r2_0, r2_1, r2_2, r2_3 := swap(v1_0, v1_1, v1_2, v1_3, tmp_0, tmp_1, tmp_2, tmp_3)
|
||||
// let _1_0 := 354020424
|
||||
// let _1_1 := 12840787883880108911
|
||||
// let _1_2 := 12527970737989311368
|
||||
// let _1_3 := 16397105843297379214
|
||||
// r1_0, r1_1, r1_2, r1_3, r2_0, r2_1, r2_2, r2_3 := swap(_1_0, _1_1, _1_2, _1_3, r2_0, r2_1, r2_2, r2_3)
|
||||
// }
|
||||
// }
|
||||
|
@ -5,13 +5,13 @@
|
||||
// step: wordSizeTransform
|
||||
// ----
|
||||
// {
|
||||
// let _1_3 := 12390
|
||||
// let _1_4 := 13186919961226471680
|
||||
// let _1_5 := 18324050535993369984
|
||||
// let _1_6 := 15884696285694336113
|
||||
// let _2_7 := 159309
|
||||
// let _2_8 := 3525417123811528497
|
||||
// let _2_9 := 6328259118096044006
|
||||
// let _2_10 := 9223372036854775807
|
||||
// let x_11, x_12, x_13, x_14 := add(_2_7, _2_8, _2_9, _2_10, _1_3, _1_4, _1_5, _1_6)
|
||||
// let _1_0 := 12390
|
||||
// let _1_1 := 13186919961226471680
|
||||
// let _1_2 := 18324050535993369984
|
||||
// let _1_3 := 15884696285694336113
|
||||
// let _2_0 := 159309
|
||||
// let _2_1 := 3525417123811528497
|
||||
// let _2_2 := 6328259118096044006
|
||||
// let _2_3 := 9223372036854775807
|
||||
// let x_0, x_1, x_2, x_3 := add(_2_0, _2_1, _2_2, _2_3, _1_0, _1_1, _1_2, _1_3)
|
||||
// }
|
||||
|
49
test/libyul/yulOptimizerTests/wordSizeTransform/if.yul
Normal file
49
test/libyul/yulOptimizerTests/wordSizeTransform/if.yul
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
if calldataload(0) { sstore(0, 1) }
|
||||
if add(calldataload(0), calldataload(1)) { sstore(0, 2) }
|
||||
}
|
||||
// ====
|
||||
// step: wordSizeTransform
|
||||
// ----
|
||||
// {
|
||||
// let _1_0 := 0
|
||||
// let _1_1 := 0
|
||||
// let _1_2 := 0
|
||||
// let _1_3 := 0
|
||||
// let _2_0, _2_1, _2_2, _2_3 := calldataload(_1_0, _1_1, _1_2, _1_3)
|
||||
// if or_bool(_2_0, _2_1, _2_2, _2_3)
|
||||
// {
|
||||
// let _3_0 := 0
|
||||
// let _3_1 := 0
|
||||
// let _3_2 := 0
|
||||
// let _3_3 := 1
|
||||
// let _4_0 := 0
|
||||
// let _4_1 := 0
|
||||
// let _4_2 := 0
|
||||
// let _4_3 := 0
|
||||
// sstore(_4_0, _4_1, _4_2, _4_3, _3_0, _3_1, _3_2, _3_3)
|
||||
// }
|
||||
// let _5_0 := 0
|
||||
// let _5_1 := 0
|
||||
// let _5_2 := 0
|
||||
// let _5_3 := 1
|
||||
// let _6_0, _6_1, _6_2, _6_3 := calldataload(_5_0, _5_1, _5_2, _5_3)
|
||||
// let _7_0 := 0
|
||||
// let _7_1 := 0
|
||||
// let _7_2 := 0
|
||||
// let _7_3 := 0
|
||||
// let _8_0, _8_1, _8_2, _8_3 := calldataload(_7_0, _7_1, _7_2, _7_3)
|
||||
// let _9_0, _9_1, _9_2, _9_3 := add(_8_0, _8_1, _8_2, _8_3, _6_0, _6_1, _6_2, _6_3)
|
||||
// if or_bool(_9_0, _9_1, _9_2, _9_3)
|
||||
// {
|
||||
// let _10_0 := 0
|
||||
// let _10_1 := 0
|
||||
// let _10_2 := 0
|
||||
// let _10_3 := 2
|
||||
// let _11_0 := 0
|
||||
// let _11_1 := 0
|
||||
// let _11_2 := 0
|
||||
// let _11_3 := 0
|
||||
// sstore(_11_0, _11_1, _11_2, _11_3, _10_0, _10_1, _10_2, _10_3)
|
||||
// }
|
||||
// }
|
Loading…
Reference in New Issue
Block a user