Conversation
de8d1a0 to
5f6edef
Compare
|
I think that what you're proposing here is the exact case I analyzed in moh-eulith#1 (comment). In short, such an optimization is doable, but questionable. It requires dynamic jumps (which would be a problem if the EVM finally introduced them; this was more of a concern while there was still hope for EOF) and it erases boundaries between functions. The latter is why it can't be done at Yul level and probably why it interferes with inliner as you've noticed. Perhaps it could be done on the SSA-CFG representation though and, if so, that would be a much better place for it. I don't think it can be done reliably on evmasm level. We discussed it on the 2025-06-18 design call, so far without any decisions. I wanted to get back to it later, though other things keep getting in the way and this does not seem very high priority given the downsides. |
592e589 to
940ea6e
Compare
|
@cameel, thanks for all this.
Yes, I think it is the same thing, though I really want to address only the simplest case, where the block really consists only of
I think here we are not on the same page. Maybe I am missing something. What do you mean by dynamic jumps? I think the potential loss of a debug info is a valid concern, though if debug information can survive inlining and block deduplication, I don't see why it couldn't survive also this transformation. Though I don't know about how debug information is propagated so I will be happy to learn more if my intuition is wrong. |
940ea6e to
c0871b0
Compare
c0871b0 to
2270fec
Compare
| } | ||
| } | ||
|
|
||
| if (_settings.runInliner && !m_eofVersion.has_value()) |
There was a problem hiding this comment.
I am using runInliner setting here to minimize the code changes, although if this would be accepted, it would probably need its own setting flag.
|
After moving this pass after |
Summary
Assembly that falls out of either legacy or IR pipeline can contain what I would call a "trivial block".
This PR adds functionality to the evmasm optimizer to detect and remove trivial blocks.
Trivial block
The following is an example of a trivial block:
Upon entering this block, the only thing the code does is jump immediately to another block.
Note that here I assume that it is not possible to "fall-through" to this block, i.e., the instruction above this block is a jump to a different block.
Full example
Full example with Solidity code and assembly output
Note that
tag_11is a trivial block.Proposed change
Trivial blocks can be deleted from the assembly, after we have updated all references to the trivial block with the reference to its successor.
Gas effects
On our test suite, the results are encouraging.
In a lot of cases we see a small improvement. On a few cases this change yields relatively significant improvement.
Open questions