Skip to content

compiler: always inline runtime/volatile functions - #6064

Draft
davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:volatile-alwaysinline
Draft

davecheney wants to merge 1 commit into
tinygo-org:devfrom
davecheney:volatile-alwaysinline

Conversation

@davecheney

@davecheney davecheney commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

At -opt=z every function has minsize, and LLVM ignores inlinehint in a minsize caller. A register write through a pointer, such as a Register32 held in a driver struct, then becomes a call to Set. The inlined store is also smaller than the call.

Measured with the ili9325 Lorenz example from tinygo-org/drivers#926 on an Arduino M0 (SAMD21, 48 MHz). The flash sizes include timing code. The speeds are the mean of three readings.

opt flash before flash after FillScreen before FillScreen after Lorenz steps/s before Lorenz steps/s after
z 24104 24024 137.9 ms 34.2 ms 3125 3667
s 24196 24148 29.2 ms 29.2 ms 3972 3943
1 33620 33620 29.3 ms 29.3 ms 4117 4134
2 33092 33092 29.2 ms 29.5 ms 4156 4116

The z before values are from the same dev commit. The s, 1 and 2 before speeds are from an earlier dev commit.

At -opt=z, FillScreen is still 5 ms slower than at -opt=s, with no calls to runtime/volatile left. That difference comes from minsize in other code and is not part of this change.

Fixes #6063

@davecheney davecheney added this to the 0.45 milestone Oct 28, 2026
@davecheney
davecheney force-pushed the volatile-alwaysinline branch from 852d694 to db46182 Compare October 28, 2026 04:28
At -opt=z every function has minsize, and LLVM ignores inlinehint in a minsize caller. A register write through a pointer, such as a Register32 held in a driver struct, then becomes a call to Set. The inlined store is also smaller than the call.

Measured with the ili9325 Lorenz example from tinygo-org/drivers#926 on an Arduino M0 (SAMD21, 48 MHz). The flash sizes include timing code. The speeds are the mean of three readings.

| opt | flash before | flash after | FillScreen before | FillScreen after | Lorenz steps/s before | Lorenz steps/s after |
|---|---|---|---|---|---|---|
| z | 24104 | 24024 | 137.9 ms | 34.2 ms | 3125 | 3667 |
| s | 24196 | 24148 | 29.2 ms | 29.2 ms | 3972 | 3943 |
| 1 | 33620 | 33620 | 29.3 ms | 29.3 ms | 4117 | 4134 |
| 2 | 33092 | 33092 | 29.2 ms | 29.5 ms | 4156 | 4116 |

The z before values are from the same dev commit. The s, 1 and 2 before speeds are from an earlier dev commit.

At -opt=z, FillScreen is still 5 ms slower than at -opt=s, with no calls to runtime/volatile left. That difference comes from minsize in other code and is not part of this change.

Fixes tinygo-org#6063
@davecheney
davecheney force-pushed the volatile-alwaysinline branch from db46182 to b9a4cfa Compare October 28, 2026 04:29
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.

runtime/volatile: Register32.Set is not inlined at -opt=z

1 participant