Skip to content

Inline single gotos#45

Merged
ncruces merged 5 commits into
mainfrom
gotos
Jul 5, 2026
Merged

Inline single gotos#45
ncruces merged 5 commits into
mainfrom
gotos

Conversation

@ncruces

@ncruces ncruces commented Jun 25, 2026

Copy link
Copy Markdown
Owner

This inlines unique gotos to code that can't otherwise be reached, and that only has explicit exit points.

This is another very ambitious optimization, that further reduces the maximum nesting level of SQLite from 108 to 40 (it's at 222 at the current release).

Problems:

  1. is it correct? seems to be…
  2. it's really slow; and it's unclear how to make it faster

For example, translating lightningcss becomes a 40 second affair.

cc: @pgaskin @msuozzo

@ncruces

ncruces commented Jun 25, 2026

Copy link
Copy Markdown
Owner Author

The slowness comes from "restarting" the optimization from scratch every time a goto is inlined, until no gotos can be inlined anymore. This is slow for large functions, but is necessary because the code can move from "far away" places.

I've also tried collecting all the gotos we want to inline, then doing a pass for each goto that we want to inline, but it takes about as much time.

@pgaskin

pgaskin commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Will take a look on Saturday (edit: some stuff came up, won't get to it on the weekend) next week.

@ncruces ncruces force-pushed the gotos branch 2 times, most recently from 4f2908e to 810254b Compare June 26, 2026 11:38
@ncruces

ncruces commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

Results for LightningCSS are similarly impressive: maximum nesting was initially 607, InlineSwitchGotos brings it down to 278, InlineSingleGotos to 121.

The cost is processing time: 10s, InlineSwitchGotos makes it 12s, but InlineSingleGotos blows it to 45s.

I could add a bound to the infinite loop, but LightningCSS needs it to be in the multiple hundred.

Notable is that both this and the switch optimization, achieve their goals without introducing code duplication: code is "moved" around, not "copied".

To improve the "slow compile" situation we need function outlining, I agree, which should help bound the runtime of this pass too.

The first line of defense there should be on the generation side: it really makes no sense that Rust/whatever creates 100Kb functions. Must be: code generation, templating, too agressive optimization. OTOH, I don't generate pretty code, so who am I to complain.

I've been slow on that front because whatever I create there should be the same thing needed to "outline" functions for the purposes of using defer in exception handling, but exception handling requires other stuff that I haven't yet done.

@ncruces

ncruces commented Jun 27, 2026

Copy link
Copy Markdown
Owner Author

I've managed to make the transform quite a bit faster. LightningCSS is now closer to 30s. So, InlineSingleGotos takes about as much as … everything else. But it's a lot of work: the bigger functions have over 200 goto statements to inline, and require many passes to eventually settle.

@ncruces

ncruces commented Jun 29, 2026

Copy link
Copy Markdown
Owner Author

I've been slow on that front because whatever I create there should be the same thing needed to "outline" functions for the purposes of using defer in exception handling, but exception handling requires other stuff that I haven't yet done.

Small step there: spec tests for it aren't supported by wabt wast2json; 7cf5bf3 adds support for wasm-tools wast2json too.

@msuozzo

msuozzo commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Tested on the treesitter parsers and it seems to be a no-op with the exception of one of them (golang) which sees a 20% reduction in size. No observable changes in behavior so looks good to me.

@ncruces ncruces marked this pull request as ready for review July 2, 2026 06:40

@pgaskin pgaskin 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.

Verified 4d29a9d against:

The optimization code looks good, and I don't see any obvious issues with it.

Comment thread internal/passes/gotos.go
if canComplete(stmts[i]) || canComplete(stmts[len(stmts)-1]) {
continue
}
// Validate the optimization.

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.

The Validate the optimization is a little bit vague, when I first read it, I thought it was trying to do an additional sanity check rather than a core part of the optimization.

@ncruces ncruces merged commit 76f1505 into main Jul 5, 2026
5 checks passed
@ncruces ncruces deleted the gotos branch July 5, 2026 08:02
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.

3 participants