solidity icon indicating copy to clipboard operation
solidity copied to clipboard

Optimize ``return(x,0) -> pop(x) return(0,0)`` (and also for ``revert``).

Open ekpyron opened this issue 3 years ago • 10 comments

Nothing fancy, but a few gas here and there... Kind of depends on https://github.com/ethereum/solidity/issues/12913, but wouldn't be fatal to merge without.

ekpyron avatar Mar 09 '22 17:03 ekpyron

Is there an optimizer step that might be more fitting? Structural sounds more like it operates on the structure of the code...

chriseth avatar Mar 09 '22 17:03 chriseth

Is there an optimizer step that might be more fitting? Structural sounds more like it operates on the structure of the code...

I didn't see anything obvious... the expression simplifier only acts on expressions and can't easily add the pop... and the structural simplifier already has the literal rematerializer as soft-requirement, s.t. we likely get the 0 as literal... We could extend the expression simplifier to expression statements instead I guess...

ekpyron avatar Mar 09 '22 18:03 ekpyron

I didn't see anything obvious... the expression simplifier only acts on expressions and can't easily add the pop... and the structural simplifier already has the literal rematerializer as soft-requirement, s.t. we likely get the 0 as literal... We could extend the expression simplifier to expression statements instead I guess...

Or start a new one?

chriseth avatar Mar 10 '22 07:03 chriseth

Actually the ExpressionSimplifier is suitable after all - we already restrict simplification to variables to avoid side-effect issues anyways, so we can also just do that for this (and then don't need to insert a pop at all).

ekpyron avatar Apr 06 '22 16:04 ekpyron

Weird that this change mostly increases gas -- or is that only for the isolated test cases and when it is used in the complete optimisation suite it helps?

axic avatar Jun 16 '22 13:06 axic

Weird that this change mostly increases gas -- or is that only for the isolated test cases and when it is used in the complete optimisation suite it helps?

This is the gas diffs on our semantics test suite

Click for a table of gas differences
File name IR-optimized (%) Legacy-Optimized (%) Legacy (%)
events/event_indexed_string.sol -0.000899607 0 0
events/event_dynamic_nested_array_storage_v2.sol -0.00162047 0 0
events/event_dynamic_array_storage_v2.sol -0.00264278 0 0
events/event_emit_from_other_contract.sol -0.64311 0 0
events/event_dynamic_array_storage.sol -0.00264278 0 0
functionCall/gas_and_value_basic.sol -0.164804 0 0
functionCall/gas_and_value_brace_syntax.sol -0.164804 0 0
externalContracts/base64.sol 0.000561615 0 0
externalContracts/FixedFeeRegistrar.sol 1.04122 0 0
abiEncoderV2/abi_encode_calldata_slice.sol -0.00407541 0 0
userDefinedValueType/calldata.sol -0.0139169 0 0
abiEncoderV1/abi_encode_calldata_slice.sol -0.00407541 0 0
viaYul/array_storage_index_access.sol -7.3568e-05 0 0
viaYul/array_storage_push_empty.sol -0.000546533 0 0
viaYul/copy_struct_invalid_ir_bug.sol 0.0176993 0 0
viaYul/array_storage_index_zeroed_test.sol -0.000181742 0 0
array/dynamic_array_cleanup.sol -0.000577349 0 0
array/dynamic_arrays_in_storage.sol -0.00179453 0 0
array/fixed_array_cleanup.sol -0.00751977 0 0
array/push/nested_bytes_push.sol -0.00167436 0 0
array/push/push_no_args_2d.sol -0.00524586 0 0
array/push/push_no_args_bytes.sol -0.0016341 0 0
array/copying/array_copy_storage_storage_dyn_dyn.sol -0.00538725 0 0
array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol -0.00210321 0 0
structs/struct_delete_storage_with_array.sol -0.00246589 0 0
structs/structs.sol 0.00223159 0 0
various/contract_binary_dependencies.sol -0.641184 0 0
various/swap_in_storage_overwrite.sol -0.00273488 0 0

not sure that qualifies as "mostly increases gas" :-). But I'm just looking at the FixedFeeRegistrar.sol case... what's happening there is that due to the change, two tags in the final assembly end up slightly different, while they were the same before (allowing deduplication) causing a slightly larger code size... (We should also really distinguish code size from runtime gas cost in our tests...)

So, the gas differences are little, but still usually favorable, I'd say, apart from corner cases like that.

Unfortunately, there's some issue with some external test apparently, so so far I'm not getting gas diffs on the external projects, that'd be more interesting.

ekpyron avatar Jun 16 '22 14:06 ekpyron

ir-optimize-evm+yul

project bytecode_size deployment_gas method_gas
bleeps -0.63% ✅ 0% -0%
brink -0.02% ✅
chainlink -0.2% ✅ -0.23% ✅ -0.03% ✅
colony 0%
elementfi +0%
ens 0% -0.19% ✅ +0%
euler -0.1% ✅ -0.1% ✅ +0.06% ❌
gnosis -0.05% ✅ -0% +0%
gp2 +0.09% ❌ +0.04% ❌ +0.01% ❌
perpetual-pools -0.06% ✅ -0.06% ✅ +0.01% ❌
pool-together -0.21% ✅ -0.23% ✅ -0%
prb-math 0% +0% 0%
trident -0.11% ✅ -0.16% ✅ -0.02% ✅
uniswap -0.12% ✅ +0.06% ❌ -0.04% ✅
yield_liquidator -0.24% ✅ -0.24% ✅ -0.01% ✅
zeppelin !V !V !V

Yeah... I'd call that "mixed, slightly favorable" or so :-).

ekpyron avatar Jun 17 '22 14:06 ekpyron

I rebased this PR

Marenz avatar Jul 12 '22 13:07 Marenz

I also re-ran the tests and got the same problems, so the rebase didn't change anything in that regard

Marenz avatar Jul 12 '22 13:07 Marenz

I'd say it's fine to merge given https://github.com/ethereum/solidity/pull/12762#discussion_r900162365

ekpyron avatar Aug 02 '22 11:08 ekpyron

Did anyone ever approve this? We could rebase & merge if someone did

leonardoalt avatar Aug 15 '22 13:08 leonardoalt

I'll rebase it in any case. But yeah, it's basically stuck on missing review.

ekpyron avatar Aug 15 '22 13:08 ekpyron

Rebased... and well, it has been marked priority review for over a month...

ekpyron avatar Aug 15 '22 14:08 ekpyron