Repository navigation
Conversation
joinVirtRegs built its two JoinVals objects and only then asked isHighCostLiveInterval whether to give up on the pair. Each JoinVals constructor sizes two arrays by the number of values in its interval, so an attempt that was abandoned anyway paid O(#values) to set up state it never read. EVM functions keep the stack size and the stack top in variables whose intervals hold thousands of values, and once such an interval has used up its attempt budget every further copy that involves it takes this path. Run the check first. It reads and updates only the per-interval attempt counter, and the JoinVals constructors have no side effects, so the coalescer makes the same decisions in the same order. On main at e839f6b the JIT code of 338 mainnet contracts is byte-identical with and without the change. For the 50 slowest-to-compile of them the instructions executed during a synchronous compile fall by 1.7% in total (0.7% to 8.7% per contract, Callgrind) and the compile wall time by 1.3%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
⚡ 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 |
5 of 16 tasks
Contributor
Author
|
Folded into #620 as its first commit. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. Does this PR affect any open issues?(Y/N) and add issue references (e.g. "fix #123", "re #123".):
2. What is the scope of this PR (e.g. component or file name):
CgRegisterCoalescer::joinVirtRegsinsrc/compiler/cgir/pass/register_coalescer.cpp.3. Provide a description of the PR(e.g. more details, effects, motivations or doc link):
joinVirtRegsbuilds its twoJoinValsobjects and only then asksisHighCostLiveIntervalwhether to give up on the pair. EachJoinValsconstructor sizes two arrays by the number of values in its interval, so an attempt that is abandoned anyway pays O(#values) to set up state it never reads. EVM functions keep the stack size and the stack top in variables whose intervals hold thousands of values, and once such an interval has used up its attempt budget, every further copy that involves it takes this path. The order is inherited from LLVM'sRegisterCoalescer::joinVirtRegs.This PR moves the check in front of the two constructors (4 lines moved, one comment added). The check reads and updates only the per-interval attempt counter, and the constructors only initialise members, so the coalescer makes the same decisions in the same order and the generated code does not change.
Measured on
mainate839f6b, Release build, multipass JIT with synchronous compilation and gas metering, revision Cancun. The contracts are the 50 slowest to compile out of 338 mainnet contracts:Per contract, the instruction count falls by 0.66% to 8.67% (median 1.69%); it rises for none. The three wall-time repetitions give −0.99%, −1.25% and −1.32%; 12 of the 50 contracts are more than 2% faster and none is more than 2% slower. The saving is modest, and it comes with no change in output.
No change document: the PR changes no capability, contract or compilation decision.
4. Are there any breaking changes?(Y/N) and describe the breaking changes(e.g. more details, motivations or doc link):
5. Are there test cases for these changes?(Y/N) select and add more details, references or doc links:
No new test: the change has no observable effect other than compile time. Checked on this branch:
ctestin a Release multipass build withDTVM_TEST_REVISION=Cancun: 14/14 with default arguments, and 14/14 withSPEC_TESTS_ARGSset as in the CI multipass job. This includesevmJitFrontendTests(182 cases),evmDifferentialTests(79),evmInterpTests(275) andmirPeepholeTests(17).tools/run_evm_tests.py -r build/dtvm --format evm: 209/209 with-m multipass --enable-evm-gas, and 209/209 with-m interpreter.clang-format15.0.7 with--dry-run -Werroron the changed file, andgit diff --check.Benchmark method: a temporary gtest case, not part of this PR, loads one contract per process in multipass mode with
DisableMultipassMultithread, and prints the size and a hash of the JIT code and the load time. Wall time was taken on one pinned performance core, with the two orders alternating within each repetition.6. Release note
🤖 Generated with Claude Code