Skip to content

Implement computed goto dispatch for the CoreCLR interpreter#129216

Open
BrzVlad wants to merge 3 commits into
dotnet:mainfrom
BrzVlad:feature-clrinterp-computed-goto
Open

Implement computed goto dispatch for the CoreCLR interpreter#129216
BrzVlad wants to merge 3 commits into
dotnet:mainfrom
BrzVlad:feature-clrinterp-computed-goto

Conversation

@BrzVlad

@BrzVlad BrzVlad commented Jun 10, 2026

Copy link
Copy Markdown
Member

Instead of making each opcode dispatch to the loop start where we switch on the opcode, we transform every switch case into a label, we let the compiler statically populate the s_dispatchTable which maps each opcode to the label address. This makes opcode dispatch a simple load + branch to the label address from this table. This makes the interpreter 25% faster.

It is unclear whether this has any impact on wasm. Likely not, because wasm has control flow limitations that make random branches impossible.

As an additional optimization, we avoid saving pFrame->ip for each opcode. Removing this can improve execution speed by around 3%. Instead we explicitly save pFrame->ip in opcodes that can trigger GC or throw exception. Add InterpThrow helper to ensure pFrame->ip is set before all throws.

Copilot AI review requested due to automatic review settings June 10, 2026 05:43
@BrzVlad BrzVlad requested review from janvorli and kg as code owners June 10, 2026 05:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot wasn't able to review any files in this pull request.

@BrzVlad

BrzVlad commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-interpreter

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@BrzVlad

BrzVlad commented Jun 10, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-libraries-interpreter

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@jkotas jkotas added the tenet-performance Performance related issue label Jun 10, 2026
@BrzVlad

BrzVlad commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

Assembly before

// INTOP_NEXT
0x105260a0c: ldr    w23, [x28, #0xc]!   // x28 = ip, load the next opcode
0x105260a10: cmp    w23, #0x15f         // check for the default branch
0x105260a14: b.ls   0x10525e034
0x105260a18: b      0x10526295c

// Loop start
0x10525e034: mov    w8, w23
0x10525e038: adrp   x11, 414            // rather long switch dispatch
0x10525e03c: add    x11, x11, #0x624
0x10525e040: adr    x9, 0x10525e008
0x10525e044: ldrh   w10, [x11, x8, lsl #1]
0x10525e048: add    x9, x9, x10, lsl #2
0x10525e04c: br     x9

Assembly after

// INTOP_NEXT
0x1051f63e0: ldr    w23, [x27, #0x8]!       // x27 = ip, load the next opcode
0x1051f63e4: ldr    x8, [x22, x23, lsl #3]  // x22 = s_dispatchTable, load label of next
0x1051f63e8: br     x8                      // dispatch

BrzVlad added 2 commits June 17, 2026 18:42
Instead of making each opcode dispatch to the loop start where we switch on the opcode, we transform every switch case into a label, we let the compiler statically populate the s_dispatchTable which maps each opcode to the label address. This makes opcode dispatch a simple load + branch to the label address from this table. This makes the interpreter 25% faster.

It is unclear whether this has any impact on wasm. Likely not, because wasm has control flow limitations that make random branches impossible.
Removing this can improve execution speed by around 3%. Instead we explicitly save pFrame->ip in opcodes that can trigger GC or throw exception. Add InterpThrow helper to ensure pFrame->ip is set before all throws.
@BrzVlad BrzVlad force-pushed the feature-clrinterp-computed-goto branch from 1f2bd0a to e39e619 Compare June 17, 2026 15:43
@BrzVlad

BrzVlad commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-interpreter
/azp run runtime-libraries-interpreter

@azure-pipelines

Copy link
Copy Markdown
No pipelines are associated with this pull request.

@BrzVlad

BrzVlad commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-interpreter

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

@BrzVlad

BrzVlad commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-libraries-interpreter

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

Copilot AI review requested due to automatic review settings June 18, 2026 12:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 2 changed files in this pull request and generated 3 comments.

Comment on lines +854 to +857
#if USE_COMPUTED_GOTO
#define INTOP_CASE(x) LABEL_ ## x:
#define INTOP_DISPATCH(op) opcode = (uint32_t)(op); goto *s_dispatchTable[opcode]
#define INTOP_NEXT INTOP_DISPATCH(ip[0])
Comment on lines +1417 to +1421
static const void* const s_dispatchTable[] = {
#define OPDEF(a,b,c,d,e,f) &&LABEL_ ## a,
#include "intops.def"
#undef OPDEF
};
Comment on lines +79 to +83
#ifdef PERFTRACING_DISABLE_THREADS
OPDEF(INTOP_PROF_SAMPLEPOINT, "prof.samplepoint", 1, 0, 0, InterpOpNoArgs)
#endif

#if defined(TARGET_BROWSER) && defined(PERFTRACING_DISABLE_THREADS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants