perf(compiler): add EVM peepholes and branch shaping - #435
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a set of EVM frontend and x86 backend peephole optimizations aimed at reducing redundant MIR materialization (notably around ISZERO/NOT) and producing tighter x86 compare/branch sequences and short-diamond branch layouts.
Changes:
- Add EVM MIR builder constant-identity folds (e.g.,
+0,*0/*1,&0,&~0,|0,^0) and introduce deferred operand kinds for bitwise-NOT and zero-test to enable collapsingISZEROchains. - Materialize deferred values only when needed by teaching
extractU256Operand()/ argument conversion paths to realize deferred operands and by extendinghandleCompareEQZ()with a negation mode. - Improve x86 output by (a) folding
cmp/test -> setcc -> [movzx] -> test -> jneinto a directjcc, and (b) shaping “short diamond” branches to prefer fallthrough to the true block.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/compiler/target/x86/x86lowering.cpp | Adds short-diamond detection and inverts branch emission to make the true block fall through when safe. |
| src/compiler/target/x86/x86_cg_peephole.cpp | Extends compare-chain peephole to handle optional movzx and shortens compare+branch sequences. |
| src/compiler/evm_frontend/evm_mir_compiler.h | Introduces deferred operand kinds and constant helper predicates; adds identity folds in arithmetic/bitwise handlers; updates handleCompareEQZ() signature. |
| src/compiler/evm_frontend/evm_mir_compiler.cpp | Implements MUL identity folds, deferred NOT/ISZERO materialization, and realizes deferred operands in extraction and arg-lowering paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
⚡ Performance Regression Check Results✅ Performance Check Passed (interpreter)Performance Benchmark Results (threshold: 25%)
Summary: 194 benchmarks, 0 regressions ✅ Performance Check Passed (multipass)Performance Benchmark Results (threshold: 25%)
Summary: 194 benchmarks, 0 regressions |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
6f3f6fb to
28b6771
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…st_cast Add begin()/end() const overloads to MBasicBlock so read-only queries can iterate statements without casting away const. Remove the const_cast in isShortDiamondTrueFallthrough() that was only needed because const iterators were missing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The compare-chain peephole (cmp->setcc->[movzx]->test->jne => cmp->jcc) was erasing SETCC/MOVZX instructions without checking if their virtual registers had other uses. The lowering cache (_expr_reg_map) can share these registers across consumers, so erasing them could leave dangling references. Add hasOneNonDBGUse guards to bail out when the registers are still live. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nd enum Replace the separate bool field with ZERO_TEST_EQ/ZERO_TEST_NE enum variants, eliminating a redundant state that could silently be inert when DeferredValueKind was BITWISE_NOT. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
d781522 to
e39b95f
Compare
Summary
ADD,SUB,MUL,AND,OR, andXORNOTand zero-test materialization soISZEROchains can collapse without building redundant 256-bit MIR valuesmovzx/testsequencesImplementation
src/compiler/evm_frontend/evm_mir_compiler.hOperandsrc/compiler/evm_frontend/evm_mir_compiler.cppMULzero/one fast pathshandleCompareEQZ()to emit eithereqornefor deferred zero testsU256Instis actually neededsrc/compiler/target/x86/x86_cg_peephole.cppcmp/test -> setcc -> [movzx] -> test -> jneinto a shorter compare/branch formsrc/compiler/target/x86/x86lowering.cppValidation
tools/format.sh check./build/evmStateTests1798/1798Benchmark
Compared with the same-session
fix2baseline onevmone-benchexternal totals:11.4%3.8%Representative wins:
external/total/main/jump_around/empty: about48%fasterexternal/total/main/memory_grow_mload/by32: improvedexternal/total/main/memory_grow_mstore/by16: improvedKnown remaining hot spots:
JUMPDEST_n0loop_with_many_jumpdests