Skip to content

perf(codegen): plan switch lowering#1002

Draft
DaniPopes wants to merge 11 commits into
mainfrom
dani/switch-lowering
Draft

perf(codegen): plan switch lowering#1002
DaniPopes wants to merge 11 commits into
mainfrom
dani/switch-lowering

Conversation

@DaniPopes

Copy link
Copy Markdown
Collaborator

Selects switch lowering late in the EVM backend after MIR optimization. The planner evaluates ordered linear scans, balanced binary trees, modulo buckets, and dense indexed tables against runtime-gas and deployed-size objectives. Indexed jumps retain their possible targets in block EVM IR and become fixed-stride out-of-line jump stubs only after block layout, preserving CFG transformations while enabling dynamic jumps. Nonconstant or duplicate cases conservatively remain ordered linear scans.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Codegen benchmark

bench gas (vs main) solc size (vs main) solc
factorial 209,949 (~0%) 224,168 (✅ +6.77%) 213B (~0%) 226B (✅ +6.10%)
counter 199,086 (~0%) 217,859 (✅ +9.43%) 200B (~0%) 228B (✅ +14.00%)
sum-array 185,503 (~0%) 229,597 (✅ +23.77%) 182B (~0%) 209B (✅ +14.84%)
arithmetic 140,122 (~0%) 158,924 (✅ +13.42%) 214B (~0%) 243B (✅ +13.55%)
openzeppelin-erc20-mock 380,381 (✅ -0.17%) 381,297 (✅ +0.24%) 1,824B (❌ +6.73%) 1,864B (✅ +2.19%)
openzeppelin-vesting-wallet 384,288 (❌ +0.07%) 382,672 (❌ -0.42%) 2,616B (❌ +5.57%) 2,064B (❌ -21.10%)
nitro-one-step-proof 348,206 (❌ +0.02%) 366,604 (✅ +5.28%) 14,574B (❌ +0.10%) 10,806B (❌ -25.85%)
aave-l2-encoder 587,288 (✅ -0.29%) 635,207 (✅ +8.16%) 3,354B (❌ +4.06%) 3,339B (❌ -0.45%)
lilweb3-ens 463,020 (~0%) 468,104 (✅ +1.10%) 419B (~0%) 665B (✅ +58.71%)
lilweb3-flashloan 489,583 (❌ +0.08%) 491,208 (✅ +0.33%) 1,679B (❌ +0.90%) 1,606B (❌ -4.35%)
lilweb3-fractional 330,921 (~0%) 331,397 (✅ +0.14%) 5,683B (❌ +3.89%) 5,622B (❌ -1.07%)
maple-erc20 444,468 (✅ -0.22%) 446,566 (✅ +0.47%) 2,397B (❌ +7.49%) 2,678B (✅ +11.72%)
Peak RSS
compiler benches average peak RSS maximum peak RSS maximum bench
solc 12 19.9 MiB 38.6 MiB nitro-one-step-proof
solar 12 20.1 MiB 22.5 MiB nitro-one-step-proof

Per-benchmark peak RSS

bench solc peak solar peak Solar vs solc
factorial 14.6 MiB 20.1 MiB ❌ +37.65%
counter 14.4 MiB 20.3 MiB ❌ +41.00%
sum-array 14.4 MiB 20.2 MiB ❌ +40.35%
arithmetic 14.7 MiB 20.4 MiB ❌ +38.61%
openzeppelin-erc20-mock 20.4 MiB 19.5 MiB ✅ -4.35%
openzeppelin-vesting-wallet 19.8 MiB 20.0 MiB ❌ +1.42%
nitro-one-step-proof 38.6 MiB 22.5 MiB ✅ -41.75%
aave-l2-encoder 25.4 MiB 20.5 MiB ✅ -19.30%
lilweb3-ens 15.4 MiB 18.9 MiB ❌ +22.90%
lilweb3-flashloan 17.5 MiB 19.4 MiB ❌ +10.84%
lilweb3-fractional 23.5 MiB 19.9 MiB ✅ -15.17%
maple-erc20 20.4 MiB 19.6 MiB ✅ -3.92%

@codspeed-hq

codspeed-hq Bot commented Jul 21, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 78 untouched benchmarks


Comparing dani/switch-lowering (e03c8e6) with main (341e603)

Open in CodSpeed

Use wider fixed-stride targets for large pre-Shanghai initcode, account for relaxed labels and taken split destinations, and bound planner candidate evaluation. Expand runtime coverage across every dispatch case and table boundaries.
Compute bucket costs with one counter array and route empty indexed-table entries directly to the default target, avoiding temporary inner allocations and throwaway EVM IR blocks.
Route empty ordinary-MIR buckets through one shared POP-and-default thunk so the preserved switch value cannot disturb internal return addresses. Cover the path through a non-inlined internal sparse switch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant