Merge pull request #8236 from ethereum/wordSizeTransformTypes

Properly assign types during word size transform.
This commit is contained in:
chriseth 2020-02-04 18:56:38 +01:00 committed by GitHub
commit d7bf6f7137
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 30 deletions

View File

@ -1232,7 +1232,7 @@ Object EVMToEwasmTranslator::run(Object const& _object)
MainFunction{}(ast);
ForLoopConditionIntoBody::run(context, ast);
ExpressionSplitter::run(context, ast);
WordSizeTransform::run(m_dialect, ast, nameDispenser);
WordSizeTransform::run(m_dialect, WasmDialect::instance().defaultType, ast, nameDispenser);
NameDisplacer{nameDispenser, m_polyfillFunctions}(ast);
for (auto const& st: m_polyfill->statements)

View File

@ -43,7 +43,11 @@ void WordSizeTransform::operator()(FunctionCall& _fc)
{
if (BuiltinFunction const* fun = m_inputDialect.builtin(_fc.functionName.name))
if (fun->literalArguments)
{
for (Expression& arg: _fc.arguments)
get<Literal>(arg).type = m_defaultType;
return;
}
rewriteFunctionCallArguments(_fc.arguments);
}
@ -85,8 +89,13 @@ void WordSizeTransform::operator()(Block& _block)
{
VariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);
// Special handling for datasize and dataoffset - they will only need one variable.
if (varDecl.value && holds_alternative<FunctionCall>(*varDecl.value))
if (!varDecl.value)
rewriteVarDeclList(varDecl.variables);
else if (holds_alternative<FunctionCall>(*varDecl.value))
{
visit(*varDecl.value);
// Special handling for datasize and dataoffset - they will only need one variable.
if (BuiltinFunction const* f = m_inputDialect.builtin(std::get<FunctionCall>(*varDecl.value).functionName.name))
if (f->literalArguments)
{
@ -108,12 +117,6 @@ void WordSizeTransform::operator()(Block& _block)
return {std::move(ret)};
}
if (
!varDecl.value ||
holds_alternative<FunctionCall>(*varDecl.value)
)
{
if (varDecl.value) visit(*varDecl.value);
rewriteVarDeclList(varDecl.variables);
return std::nullopt;
}
@ -144,8 +147,11 @@ void WordSizeTransform::operator()(Block& _block)
Assignment& assignment = std::get<Assignment>(_s);
yulAssert(assignment.value, "");
// Special handling for datasize and dataoffset - they will only need one variable.
if (holds_alternative<FunctionCall>(*assignment.value))
{
visit(*assignment.value);
// Special handling for datasize and dataoffset - they will only need one variable.
if (BuiltinFunction const* f = m_inputDialect.builtin(std::get<FunctionCall>(*assignment.value).functionName.name))
if (f->literalArguments)
{
@ -167,9 +173,6 @@ void WordSizeTransform::operator()(Block& _block)
return {std::move(ret)};
}
if (holds_alternative<FunctionCall>(*assignment.value))
{
if (assignment.value) visit(*assignment.value);
rewriteIdentifierList(assignment.variableNames);
return std::nullopt;
}
@ -204,12 +207,16 @@ void WordSizeTransform::operator()(Block& _block)
);
}
void WordSizeTransform::run(Dialect const& _inputDialect, Block& _ast, NameDispenser& _nameDispenser)
void WordSizeTransform::run(
Dialect const& _inputDialect,
YulString _targetDefaultType,
Block& _ast,
NameDispenser& _nameDispenser
)
{
// Free the name `or_bool`.
NameDisplacer{_nameDispenser, {"or_bool"_yulstring}}(_ast);
YulString defaultType; // should be i64 at some point.
WordSizeTransform{_inputDialect, _nameDispenser, defaultType}(_ast);
WordSizeTransform{_inputDialect, _nameDispenser, _targetDefaultType}(_ast);
}
void WordSizeTransform::rewriteVarDeclList(TypedNameList& _nameList)

View File

@ -67,7 +67,12 @@ public:
void operator()(ForLoop&) override;
void operator()(Block& _block) override;
static void run(Dialect const& _inputDialect, Block& _ast, NameDispenser& _nameDispenser);
static void run(
Dialect const& _inputDialect,
YulString _targetDefaultType,
Block& _ast,
NameDispenser& _nameDispenser
);
private:
explicit WordSizeTransform(

View File

@ -15,9 +15,9 @@ object "object" {
function main()
{
let _1 := 0
mstore_internal(0, _1, _1, _1, _1)
mstore_internal(_1, _1, _1, _1, _1)
mstore_internal(32, _1, _1, _1, 1)
eth.storageStore(0, 32)
eth.storageStore(_1, 32)
}
function endian_swap_16(x) -> y
{
@ -45,7 +45,7 @@ object "object" {
Binary representation:
0061736d0100000001160460000060017e017e60057e7e7e7e7e0060027f7f0002190108657468657265756d0c73746f7261676553746f7265000303060500010101020503010001060100071102066d656d6f72790200046d61696e00010ab501052801017e420021004200200020002000200010054220200020002000420110054200a74220a710000b1c01017e20004208864280fe0383200042088842ff018384210120010b1b01027e20001002421086210220022000421088100284210120010b1b01027e20001003422086210220022000422088100384210120010b3501007e2000a720011004370300200042087ca720021004370300200042107ca720031004370300200042187ca7200410043703000b
0061736d0100000001160460000060017e017e60057e7e7e7e7e0060027f7f0002190108657468657265756d0c73746f7261676553746f7265000303060500010101020503010001060100071102066d656d6f72790200046d61696e00010ab501052801017e420021002000200020002000200010054220200020002000420110052000a74220a710000b1c01017e20004208864280fe0383200042088842ff018384210120010b1b01027e20001002421086210220022000421088100284210120010b1b01027e20001003422086210220022000422088100384210120010b3501007e2000a720011004370300200042087ca720021004370300200042107ca720031004370300200042187ca7200410043703000b
Text representation:
(module
@ -56,9 +56,9 @@ Text representation:
(func $main
(local $_1 i64)
(local.set $_1 (i64.const 0))
(call $mstore_internal (i64.const 0) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))
(call $mstore_internal (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))
(call $mstore_internal (i64.const 32) (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 1))
(call $eth.storageStore (i32.wrap_i64 (i64.const 0)) (i32.wrap_i64 (i64.const 32)))
(call $eth.storageStore (i32.wrap_i64 (local.get $_1)) (i32.wrap_i64 (i64.const 32)))
)
(func $endian_swap_16

View File

@ -10,23 +10,21 @@
(local $p i64)
(local $r i64)
(local $hi i64)
(local $hi_1 i64)
(local $y i64)
(local $hi_2 i64)
(local $hi_1 i64)
(local $_2 i64)
(local.set $_1 (i64.const 0))
(local.set $p (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (i64.const 64)))
(local.set $r (i64.add (local.get $p) (i64.const 64)))
(if (i64.ne (i64.extend_i32_u (i64.lt_u (local.get $r) (local.get $p))) (i64.const 0)) (then
(unreachable)))
(local.set $hi (i64.shl (call $endian_swap_16 (local.get $_1)) (i64.const 16)))
(local.set $hi_1 (i64.shl (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $_1) (i64.const 16)))) (i64.const 32)))
(local.set $y (i64.or (local.get $hi_1) (call $endian_swap_32 (i64.shr_u (local.get $_1) (i64.const 32)))))
(local.set $hi (i64.shl (i64.or (i64.shl (i64.or (i64.and (i64.shl (local.get $_1) (i64.const 8)) (i64.const 65280)) (i64.and (i64.shr_u (local.get $_1) (i64.const 8)) (i64.const 255))) (i64.const 16)) (call $endian_swap_16 (i64.shr_u (local.get $_1) (i64.const 16)))) (i64.const 32)))
(local.set $y (i64.or (local.get $hi) (call $endian_swap_32 (i64.shr_u (local.get $_1) (i64.const 32)))))
(i64.store (i32.wrap_i64 (local.get $r)) (local.get $y))
(i64.store (i32.wrap_i64 (i64.add (local.get $r) (i64.const 8))) (local.get $y))
(i64.store (i32.wrap_i64 (i64.add (local.get $r) (i64.const 16))) (local.get $y))
(local.set $hi_2 (i64.shl (call $endian_swap_32 (i64.const 128)) (i64.const 32)))
(i64.store (i32.wrap_i64 (i64.add (local.get $r) (i64.const 24))) (i64.or (local.get $hi_2) (call $endian_swap_32 (i64.shr_u (i64.const 128) (i64.const 32)))))
(local.set $hi_1 (i64.shl (call $endian_swap_32 (i64.const 128)) (i64.const 32)))
(i64.store (i32.wrap_i64 (i64.add (local.get $r) (i64.const 24))) (i64.or (local.get $hi_1) (call $endian_swap_32 (i64.shr_u (i64.const 128) (i64.const 32)))))
(local.set $_2 (datasize \"C_2_deployed\"))
(call $eth.codeCopy (i32.wrap_i64 (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\"))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_2))))
(call $eth.finish (i32.wrap_i64 (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))) (i32.wrap_i64 (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_2))))

View File

@ -349,7 +349,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line
{
disambiguate();
ExpressionSplitter::run(*m_context, *m_ast);
WordSizeTransform::run(*m_dialect, *m_ast, *m_nameDispenser);
WordSizeTransform::run(*m_dialect, ""_yulstring, *m_ast, *m_nameDispenser);
}
else if (m_optimizerStep == "fullSuite")
{