Skip to content

perf(parser): make Modifiers::accessibility branchless#20827

Merged
graphite-app[bot] merged 1 commit intomainfrom
om/03-28-perf_parser_make_modifiers_accessibility_branchless
Mar 29, 2026
Merged

perf(parser): make Modifiers::accessibility branchless#20827
graphite-app[bot] merged 1 commit intomainfrom
om/03-28-perf_parser_make_modifiers_accessibility_branchless

Conversation

@overlookmotel
Copy link
Copy Markdown
Member

@overlookmotel overlookmotel commented Mar 28, 2026

Modifiers::accessibility is called in many places. Previously it was 10 instructions, including 2 unpredictable branches.

Reduce it to 4 instructions and no branches, by using an 8-byte lookup table.

The code is verbose, but almost all of it is compile-time constants, which boil down to nothing but the 8-byte table. The code could be made shorter, but only by resorting to unsafe code. The version in this PR contains no unsafe code, and produces the same optimal assembly as an unsafe version.

Before:

accessibility:
        mov     al, 2
        test    dil, 8
        jne     .LBB1_3
        mov     al, 1
        test    dil, 4
        jne     .LBB1_3
        xor     eax, eax
        test    dil, 2
        sete    al
        lea     eax, [rax + 2*rax]
.LBB1_3:
        ret

After:

accessibility:
        shr     edi
        and     edi, 7
        lea     rax, [rip + LUT::h8cdda7c57c71092a]
        movzx   eax, byte ptr [rdi + rax]
        ret

LUT::h8cdda7c57c71092a:
        .ascii  "\003\000\001\001\002\002\002\002"

+0.1% - +0.2% improvement on parser benchmarks. But CodSpeed doesn't take into account the cost of branch misprediction which we now avoid, so it's likely an underestimate.

@github-actions github-actions bot added the A-parser Area - Parser label Mar 28, 2026
@github-actions github-actions bot added the C-performance Category - Solution not expected to change functional behavior, only performance label Mar 28, 2026
Copy link
Copy Markdown
Member Author

overlookmotel commented Mar 28, 2026


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@overlookmotel overlookmotel marked this pull request as ready for review March 28, 2026 16:41
Copilot AI review requested due to automatic review settings March 28, 2026 16:41
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes TypeScript accessibility-modifier detection in the parser by making Modifiers::accessibility branchless and delegating the work to a new ModifierKinds::accessibility implementation that uses a packed lookup table.

Changes:

  • Replaced branchy Modifiers::accessibility checks with a call to ModifierKinds::accessibility.
  • Added a new branchless ModifierKinds::accessibility using a packed LUT (u64) for fast decoding.
  • Added a small const fn min helper for const-eval computations used by the LUT setup.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Mar 28, 2026

Merging this PR will degrade performance by 4.46%

❌ 1 regressed benchmark
✅ 47 untouched benchmarks
⏩ 8 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation mangler[RadixUIAdoptionSection.jsx_keep_names] 19.4 µs 20.4 µs -4.46%

Comparing om/03-28-perf_parser_make_modifiers_accessibility_branchless (5995339) with om/03-28-perf_parser_add_inline_to_trivial_modifier_methods (2208114)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@overlookmotel overlookmotel marked this pull request as draft March 28, 2026 17:02
@overlookmotel overlookmotel force-pushed the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch 2 times, most recently from 682b845 to 35d1279 Compare March 28, 2026 17:14
@overlookmotel overlookmotel force-pushed the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch from d1e288e to a69f5db Compare March 29, 2026 00:28
@overlookmotel overlookmotel requested a review from Copilot March 29, 2026 00:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

@overlookmotel overlookmotel marked this pull request as ready for review March 29, 2026 00:48
@overlookmotel overlookmotel force-pushed the om/03-28-perf_parser_add_inline_to_trivial_modifier_methods branch from 92c8d6f to 328e6da Compare March 29, 2026 00:55
@overlookmotel overlookmotel force-pushed the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch from a69f5db to 15ed94a Compare March 29, 2026 00:55
@overlookmotel overlookmotel changed the base branch from om/03-28-perf_parser_add_inline_to_trivial_modifier_methods to graphite-base/20827 March 29, 2026 01:11
@overlookmotel overlookmotel force-pushed the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch from 15ed94a to 7ccff49 Compare March 29, 2026 01:12
@overlookmotel overlookmotel changed the base branch from graphite-base/20827 to om/03-28-perf_parser_add_inline_to_trivial_modifier_methods March 29, 2026 01:12
@overlookmotel overlookmotel force-pushed the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch from 7ccff49 to 2cabc70 Compare March 29, 2026 01:12
@camc314 camc314 added the 0-merge Merge with Graphite Merge Queue label Mar 29, 2026
Copy link
Copy Markdown
Contributor

camc314 commented Mar 29, 2026

Merge activity

@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Mar 29, 2026
@graphite-app graphite-app bot force-pushed the om/03-28-perf_parser_add_inline_to_trivial_modifier_methods branch from cee52c3 to c4b3d05 Compare March 29, 2026 15:44
graphite-app bot pushed a commit that referenced this pull request Mar 29, 2026
`Modifiers::accessibility` is called in many places. Previously it was 10 instructions, including 2 unpredictable branches.

Reduce it to 4 instructions and no branches, by using an 8-byte lookup table.

The code is verbose, but almost all of it is compile-time constants, which boil down to nothing but the 8-byte table. The code could be made shorter, but only by resorting to unsafe code. The version in this PR contains no unsafe code, and produces the same optimal assembly as an unsafe version.

Before:

```asm
accessibility:
        mov     al, 2
        test    dil, 8
        jne     .LBB1_3
        mov     al, 1
        test    dil, 4
        jne     .LBB1_3
        xor     eax, eax
        test    dil, 2
        sete    al
        lea     eax, [rax + 2*rax]
.LBB1_3:
        ret
```

After:

```asm
accessibility:
        shr     edi
        and     edi, 7
        lea     rax, [rip + LUT::h8cdda7c57c71092a]
        movzx   eax, byte ptr [rdi + rax]
        ret

LUT::h8cdda7c57c71092a:
        .ascii  "\003\000\001\001\002\002\002\002"
```

+0.1% - +0.2% improvement on parser benchmarks. But CodSpeed doesn't take into account the cost of branch misprediction which we now avoid, so it's likely an underestimate.
@graphite-app graphite-app bot force-pushed the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch from 2cabc70 to 2da6b13 Compare March 29, 2026 15:44
@graphite-app graphite-app bot force-pushed the om/03-28-perf_parser_add_inline_to_trivial_modifier_methods branch from c4b3d05 to 2208114 Compare March 29, 2026 16:39
`Modifiers::accessibility` is called in many places. Previously it was 10 instructions, including 2 unpredictable branches.

Reduce it to 4 instructions and no branches, by using an 8-byte lookup table.

The code is verbose, but almost all of it is compile-time constants, which boil down to nothing but the 8-byte table. The code could be made shorter, but only by resorting to unsafe code. The version in this PR contains no unsafe code, and produces the same optimal assembly as an unsafe version.

Before:

```asm
accessibility:
        mov     al, 2
        test    dil, 8
        jne     .LBB1_3
        mov     al, 1
        test    dil, 4
        jne     .LBB1_3
        xor     eax, eax
        test    dil, 2
        sete    al
        lea     eax, [rax + 2*rax]
.LBB1_3:
        ret
```

After:

```asm
accessibility:
        shr     edi
        and     edi, 7
        lea     rax, [rip + LUT::h8cdda7c57c71092a]
        movzx   eax, byte ptr [rdi + rax]
        ret

LUT::h8cdda7c57c71092a:
        .ascii  "\003\000\001\001\002\002\002\002"
```

+0.1% - +0.2% improvement on parser benchmarks. But CodSpeed doesn't take into account the cost of branch misprediction which we now avoid, so it's likely an underestimate.
@graphite-app graphite-app bot force-pushed the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch from 2da6b13 to 5995339 Compare March 29, 2026 16:40
@graphite-app graphite-app bot added the 0-merge Merge with Graphite Merge Queue label Mar 29, 2026
Base automatically changed from om/03-28-perf_parser_add_inline_to_trivial_modifier_methods to main March 29, 2026 16:48
@graphite-app graphite-app bot merged commit 5995339 into main Mar 29, 2026
37 checks passed
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Mar 29, 2026
@graphite-app graphite-app bot deleted the om/03-28-perf_parser_make_modifiers_accessibility_branchless branch March 29, 2026 16:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-parser Area - Parser C-performance Category - Solution not expected to change functional behavior, only performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants