Open daejunpark opened 4 years ago
Note that neither the copmpiler nor optimizer does any lifetime tracking of memory objects. abi.encodePacked
returns a memory object and thus could be used further down the road, so lifetime tracking is required here if we do not just want to optimize for a special case. There are proposals to do lifetime tracking in the yul optimizer, though.
Just like we have a codegen shortcut for assigning hashes to constants (#4024) and address.code.length
(#10778), we could have a similar shortcut for the keccak256(abi.encode*..)
and keccak256(bytes.concat..)
(see #10903) cases.
We may want to be a bit reserved though, as this will incentivise this pattern, and I think we should add this shortcut if we believe in the long term we can have this done efficiently even without the shortcut.
[This issue has been discussed with @axic, and reported here to be tracked and further discussed.]
Description
In the current code generation (even with the optimization enabled with the flags
--optimize --optimize-runs 5000000
), there is still room for improvement of the memory usage for loops.Specifically, if we have
sha256(abi.encodePacked(arg1, arg2))
in a loop, every iteration consumes new memory entries to store the argumentsarg1
andarg2
, even if the same memory entries can be reused over the whole iterations.For example, for this loop, the first iteration consumes the following entries to store the arguments:
and then the second iteration consumes the following:
and so on.
In the end, the total 3072 (= 32 iterations * 96 bytes per iteration) bytes of memory are consumed to compute the
sha256
function, while the optimized behavior would consume only the 96 bytes for the whole iterations. This ended up wasting ~300 gas unit.Environment
0.6.8+commit.0bbfe453.Linux.g++
--optimize --optimize-runs 5000000
Steps to Reproduce
Compile
https://github.com/axic/eth2-deposit-contract/blob/r1/deposit_contract.sol
with the following command line flags:Then see the generated assembly code for the aforementioned loop (i.e., code blocks between
tag_123
andtag_124
).(I'll provide a minimal example later.)