Yul Optimizer: Switch elimination for cheap switch cases.
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 21
Description
Came up with https://github.com/ethereum/solidity/issues/12930.
Currently for
```
function f(bool cond) external pure returns (uint256 x) {
return cond ? 1 : 0;
}
```
(roughly) results in the following snippet in optimized yul code
```
switch cond
case 0 { x := 0x00 }
default { x := 0x01 }
```
which is of course silly.
We could, for example, generically eliminate a switch of the form
```
switch cond
case 0 { x := a }
default { x := b }
```
by ``x := or(mul(iszero(cond), a), mul(iszero(iszero(cond)), b)``.
This could generalize to a transformation of
```
switch cond
case { x := a }
default { x := b }
```
to
```
let _1 := eq(cond, )
x := or(mul(_1, a), mul(iszero(_1), b)
```
Maybe also worth a thought how this would look like with multiple switch cases and without default case.
This would require guessing, when the combined cost of the switch cases and merging them is cheaper than actual branching.
Even more generally, this could happen for arbitrary switch case bodies, as long as they are side-effect free, which would require merging all variables assigned in at least one case body. (Although this would complicate the cost calculation and we'd need to check, if this ever makes sense gas-wise if it's more than one variable)
Contributor guide
Research direction
No source files or tests are named. Start by locating the Yul optimizer logic and its switch-related tests, then assess the gas-cost tradeoff for eliminating simple switch cases; done means the selected transformations are implemented with coverage for the proposed cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, solidity
- Domain
- blockchain, compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100