Mask generation optimization
Abstract
I have a large contract compiled with --via-ir --optimize --optimize-runs 2
Looking at the generated opcodes I see the following mask generation patterns that can be optimized:
I've implemented a change to the constant optimizer for this here: https://github.com/ethereum/solidity/compare/develop...moh-eulith:solidity:mask_generation
May I create a PR from the above?
-
Mask generation 15 instances of
PUSH1 0x1 PUSH1 0x1 PUSH1 0x[0-9A-F]* SHL SUB NOT(sub case of the next one) ->PUSH0 NOT PUSH1 $bits SHL(saves 4 bytes) 247 instances ofPUSH1 0x1 PUSH1 0x1 PUSH1 0x[0-9A-F]* SHL SUB, saves 3*247 bytesPUSH1 0x1 PUSH1 0x1 PUSH1 0x40 SHL SUB: 8 bytes, 3 + 3 + 3 + 3 + 3 = 15 gas ->PUSH0 NOT PUSH1 0xC0 SHR: 5 bytes, 2 + 3 + 3 + 3 = 11 gas -
Shifted mask generation 53 instances of
PUSH1 0x1 PUSH1 0x[0-9A-F]* SHL PUSH1 0x1 PUSH1 0x[0-9A-F]* SHL SUB: saves 3*53PUSH1 0x1 PUSH1 0x40 SHL PUSH1 0x1 PUSH1 0x80 SHL SUB: 11 opcodes ->PUSH0 NOT PUSH1 0xC0 SHR PUSH1 0x40 SHL: 8 opcodes
Motivation
Reduce both binary size and gas.
Specification
just an optimizer change, so no spec changes.
Backwards Compatibility
just an optimizer change, so backwards compatible.
Sorry again for the delay! We'd be happy to review a PR on this! We can also continue this in review, but be sure to note the coding style https://github.com/ethereum/solidity/blob/develop/CODING_STYLE.md (e.g. in the branch I see braces in single line if-statements that we usually skip); also the PR should get a Changelog entry (once https://github.com/ethereum/solidity/pull/15927 is merged)
Thank you for taking a look. PR submitted with the feedback. #15935