mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9672 from ethereum/fixRecompilation
Fix inlining order to correspond to source order.
This commit is contained in:
commit
bc4e07d309
@ -18,6 +18,7 @@ Bugfixes:
|
|||||||
* SMTChecker: Fix internal error on array implicit conversion.
|
* SMTChecker: Fix internal error on array implicit conversion.
|
||||||
* SMTChecker: Fix internal error on fixed bytes index access.
|
* SMTChecker: Fix internal error on fixed bytes index access.
|
||||||
* References Resolver: Fix internal bug when using constructor for library.
|
* References Resolver: Fix internal bug when using constructor for library.
|
||||||
|
* Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present.
|
||||||
|
|
||||||
|
|
||||||
### 0.7.0 (2020-07-28)
|
### 0.7.0 (2020-07-28)
|
||||||
|
@ -80,10 +80,20 @@ void FullInliner::run()
|
|||||||
|
|
||||||
// TODO it might be good to determine a visiting order:
|
// TODO it might be good to determine a visiting order:
|
||||||
// first handle functions that are called from many places.
|
// first handle functions that are called from many places.
|
||||||
for (auto const& fun: m_functions)
|
|
||||||
|
// Note that the order of inlining can result in very different code.
|
||||||
|
// Since AST IDs and thus function names depend on whether or not a contract
|
||||||
|
// is compiled together with other source files, a change in AST IDs
|
||||||
|
// should have as little an impact as possible. This is the case
|
||||||
|
// if we handle inlining in source (and thus, for the IR generator,
|
||||||
|
// function name) order.
|
||||||
|
for (auto& statement: m_ast.statements)
|
||||||
{
|
{
|
||||||
handleBlock(fun.second->name, fun.second->body);
|
if (!holds_alternative<FunctionDefinition>(statement))
|
||||||
updateCodeSize(*fun.second);
|
continue;
|
||||||
|
FunctionDefinition& fun = std::get<FunctionDefinition>(statement);
|
||||||
|
handleBlock(fun.name, fun.body);
|
||||||
|
updateCodeSize(fun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
(import \"ethereum\" \"finish\" (func $eth.finish (param i32 i32)))
|
(import \"ethereum\" \"finish\" (func $eth.finish (param i32 i32)))
|
||||||
(memory $memory (export \"memory\") 1)
|
(memory $memory (export \"memory\") 1)
|
||||||
(export \"main\" (func $main))
|
(export \"main\" (func $main))
|
||||||
|
(global $global_ (mut i64) (i64.const 0))
|
||||||
|
(global $global__1 (mut i64) (i64.const 0))
|
||||||
|
(global $global__2 (mut i64) (i64.const 0))
|
||||||
|
|
||||||
(func $main
|
(func $main
|
||||||
(local $_1 i64)
|
(local $_1 i64)
|
||||||
@ -15,6 +18,7 @@
|
|||||||
(local $z1 i64)
|
(local $z1 i64)
|
||||||
(local $z2 i64)
|
(local $z2 i64)
|
||||||
(local $z3 i64)
|
(local $z3 i64)
|
||||||
|
(local $z4 i64)
|
||||||
(local $_3 i64)
|
(local $_3 i64)
|
||||||
(block $label_
|
(block $label_
|
||||||
(local.set $_1 (i64.const 0))
|
(local.set $_1 (i64.const 0))
|
||||||
@ -28,14 +32,18 @@
|
|||||||
(i64.store (i32.add (local.get $r) (i32.const 16)) (local.get $_2))
|
(i64.store (i32.add (local.get $r) (i32.const 16)) (local.get $_2))
|
||||||
(i64.store (i32.add (local.get $r) (i32.const 24)) (call $endian_swap (i64.const 128)))
|
(i64.store (i32.add (local.get $r) (i32.const 24)) (call $endian_swap (i64.const 128)))
|
||||||
(call $eth.getCallValue (i32.const 0))
|
(call $eth.getCallValue (i32.const 0))
|
||||||
(local.set $z1 (call $endian_swap (i64.load (i32.const 0))))
|
(block
|
||||||
(local.set $z2 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 8)))))
|
(local.set $z1 (call $mload_internal (i32.const 0)))
|
||||||
(local.set $z3 (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 16)))))
|
(local.set $z2 (global.get $global_))
|
||||||
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (call $endian_swap (i64.load (i32.add (i32.const 0) (i32.const 24)))))))) (then
|
(local.set $z3 (global.get $global__1))
|
||||||
(call $revert (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1))))
|
(local.set $z4 (global.get $global__2))
|
||||||
|
|
||||||
|
)
|
||||||
|
(if (i32.eqz (i64.eqz (i64.or (i64.or (local.get $z1) (local.get $z2)) (i64.or (local.get $z3) (local.get $z4))))) (then
|
||||||
|
(call $eth.revert (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)))))
|
||||||
(local.set $_3 (datasize \"C_2_deployed\"))
|
(local.set $_3 (datasize \"C_2_deployed\"))
|
||||||
(call $codecopy (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\") (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
|
(call $eth.codeCopy (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (dataoffset \"C_2_deployed\")) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3)))
|
||||||
(call $return (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3))
|
(call $eth.finish (call $to_internal_i32ptr (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_1)) (call $u256_to_i32 (local.get $_1) (local.get $_1) (local.get $_1) (local.get $_3)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,7 +54,7 @@
|
|||||||
(param $x4 i64)
|
(param $x4 i64)
|
||||||
(result i32)
|
(result i32)
|
||||||
(local $v i32)
|
(local $v i32)
|
||||||
(block $label__1
|
(block $label__3
|
||||||
(if (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3))) (then
|
(if (i64.ne (i64.const 0) (i64.or (i64.or (local.get $x1) (local.get $x2)) (local.get $x3))) (then
|
||||||
(unreachable)))
|
(unreachable)))
|
||||||
(if (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32))) (then
|
(if (i64.ne (i64.const 0) (i64.shr_u (local.get $x4) (i64.const 32))) (then
|
||||||
@ -65,7 +73,7 @@
|
|||||||
(result i32)
|
(result i32)
|
||||||
(local $r i32)
|
(local $r i32)
|
||||||
(local $p i32)
|
(local $p i32)
|
||||||
(block $label__2
|
(block $label__4
|
||||||
(local.set $p (call $u256_to_i32 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)))
|
(local.set $p (call $u256_to_i32 (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)))
|
||||||
(local.set $r (i32.add (local.get $p) (i32.const 64)))
|
(local.set $r (i32.add (local.get $p) (i32.const 64)))
|
||||||
(if (i32.lt_u (local.get $r) (local.get $p)) (then
|
(if (i32.lt_u (local.get $r) (local.get $p)) (then
|
||||||
@ -75,29 +83,11 @@
|
|||||||
(local.get $r)
|
(local.get $r)
|
||||||
)
|
)
|
||||||
|
|
||||||
(func $codecopy
|
|
||||||
(param $x1 i64)
|
|
||||||
(param $x2 i64)
|
|
||||||
(param $x3 i64)
|
|
||||||
(param $x4 i64)
|
|
||||||
(param $y1 i64)
|
|
||||||
(param $y2 i64)
|
|
||||||
(param $y3 i64)
|
|
||||||
(param $y4 i64)
|
|
||||||
(param $z1 i64)
|
|
||||||
(param $z2 i64)
|
|
||||||
(param $z3 i64)
|
|
||||||
(param $z4 i64)
|
|
||||||
(block $label__3
|
|
||||||
(call $eth.codeCopy (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)) (call $u256_to_i32 (local.get $z1) (local.get $z2) (local.get $z3) (local.get $z4)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(func $endian_swap_16
|
(func $endian_swap_16
|
||||||
(param $x i64)
|
(param $x i64)
|
||||||
(result i64)
|
(result i64)
|
||||||
(local $y i64)
|
(local $y i64)
|
||||||
(block $label__4
|
(block $label__5
|
||||||
(local.set $y (i64.or (i64.and (i64.shl (local.get $x) (i64.const 8)) (i64.const 65280)) (i64.and (i64.shr_u (local.get $x) (i64.const 8)) (i64.const 255))))
|
(local.set $y (i64.or (i64.and (i64.shl (local.get $x) (i64.const 8)) (i64.const 65280)) (i64.and (i64.shr_u (local.get $x) (i64.const 8)) (i64.const 255))))
|
||||||
|
|
||||||
)
|
)
|
||||||
@ -109,7 +99,7 @@
|
|||||||
(result i64)
|
(result i64)
|
||||||
(local $y i64)
|
(local $y i64)
|
||||||
(local $hi i64)
|
(local $hi i64)
|
||||||
(block $label__5
|
(block $label__6
|
||||||
(local.set $hi (i64.shl (call $endian_swap_16 (local.get $x)) (i64.const 16)))
|
(local.set $hi (i64.shl (call $endian_swap_16 (local.get $x)) (i64.const 16)))
|
||||||
(local.set $y (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $x) (i64.const 16)))))
|
(local.set $y (i64.or (local.get $hi) (call $endian_swap_16 (i64.shr_u (local.get $x) (i64.const 16)))))
|
||||||
|
|
||||||
@ -122,7 +112,7 @@
|
|||||||
(result i64)
|
(result i64)
|
||||||
(local $y i64)
|
(local $y i64)
|
||||||
(local $hi i64)
|
(local $hi i64)
|
||||||
(block $label__6
|
(block $label__7
|
||||||
(local.set $hi (i64.shl (call $endian_swap_32 (local.get $x)) (i64.const 32)))
|
(local.set $hi (i64.shl (call $endian_swap_32 (local.get $x)) (i64.const 32)))
|
||||||
(local.set $y (i64.or (local.get $hi) (call $endian_swap_32 (i64.shr_u (local.get $x) (i64.const 32)))))
|
(local.set $y (i64.or (local.get $hi) (call $endian_swap_32 (i64.shr_u (local.get $x) (i64.const 32)))))
|
||||||
|
|
||||||
@ -130,32 +120,24 @@
|
|||||||
(local.get $y)
|
(local.get $y)
|
||||||
)
|
)
|
||||||
|
|
||||||
(func $return
|
(func $mload_internal
|
||||||
(param $x1 i64)
|
(param $pos i32)
|
||||||
(param $x2 i64)
|
(result i64)
|
||||||
(param $x3 i64)
|
(local $z1 i64)
|
||||||
(param $x4 i64)
|
(local $z2 i64)
|
||||||
(param $y1 i64)
|
(local $z3 i64)
|
||||||
(param $y2 i64)
|
(local $z4 i64)
|
||||||
(param $y3 i64)
|
|
||||||
(param $y4 i64)
|
|
||||||
(block $label__7
|
|
||||||
(call $eth.finish (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
(func $revert
|
|
||||||
(param $x1 i64)
|
|
||||||
(param $x2 i64)
|
|
||||||
(param $x3 i64)
|
|
||||||
(param $x4 i64)
|
|
||||||
(param $y1 i64)
|
|
||||||
(param $y2 i64)
|
|
||||||
(param $y3 i64)
|
|
||||||
(param $y4 i64)
|
|
||||||
(block $label__8
|
(block $label__8
|
||||||
(call $eth.revert (call $to_internal_i32ptr (local.get $x1) (local.get $x2) (local.get $x3) (local.get $x4)) (call $u256_to_i32 (local.get $y1) (local.get $y2) (local.get $y3) (local.get $y4)))
|
(local.set $z1 (call $endian_swap (i64.load (local.get $pos))))
|
||||||
|
(local.set $z2 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 8)))))
|
||||||
|
(local.set $z3 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 16)))))
|
||||||
|
(local.set $z4 (call $endian_swap (i64.load (i32.add (local.get $pos) (i32.const 24)))))
|
||||||
|
|
||||||
)
|
)
|
||||||
|
(global.set $global_ (local.get $z2))
|
||||||
|
(global.set $global__1 (local.get $z3))
|
||||||
|
(global.set $global__2 (local.get $z4))
|
||||||
|
(local.get $z1)
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
@ -17,9 +17,9 @@ contract C {
|
|||||||
// optimize-yul: true
|
// optimize-yul: true
|
||||||
// ----
|
// ----
|
||||||
// creation:
|
// creation:
|
||||||
// codeDepositCost: 603000
|
// codeDepositCost: 616600
|
||||||
// executionCost: 638
|
// executionCost: 651
|
||||||
// totalCost: 603638
|
// totalCost: 617251
|
||||||
// external:
|
// external:
|
||||||
// a(): 1029
|
// a(): 1029
|
||||||
// b(uint256): 2084
|
// b(uint256): 2084
|
||||||
|
@ -36,20 +36,15 @@
|
|||||||
// function f(x)
|
// function f(x)
|
||||||
// {
|
// {
|
||||||
// mstore(0, x)
|
// mstore(0, x)
|
||||||
// let t_20 := 0
|
// let t_14 := 0
|
||||||
// t_20 := 2
|
// t_14 := 2
|
||||||
// mstore(7, t_20)
|
// mstore(7, t_14)
|
||||||
// g(10)
|
// let x_1_15 := 10
|
||||||
|
// f(1)
|
||||||
// mstore(1, x)
|
// mstore(1, x)
|
||||||
// }
|
// }
|
||||||
// function g(x_1)
|
// function g(x_1)
|
||||||
// {
|
// { f(1) }
|
||||||
// let x_14 := 1
|
|
||||||
// mstore(0, x_14)
|
|
||||||
// mstore(7, h())
|
|
||||||
// g(10)
|
|
||||||
// mstore(1, x_14)
|
|
||||||
// }
|
|
||||||
// function h() -> t
|
// function h() -> t
|
||||||
// { t := 2 }
|
// { t := 2 }
|
||||||
// }
|
// }
|
||||||
|
Loading…
Reference in New Issue
Block a user