Status quo:
@setCold(is_cold: bool) void
Tells the optimizer that a function is rarely called.
Proposal:
@cold() void
Annotates that it is relatively uncommon for control flow to reach this point. Similar to unreachable, but only communicates probability. It communicates a willingness to compromise performance of the cold path in order to improve performance of the hot path.
This makes #489 unnecessary. Instead of:
if (@expect(foo, true)) {
bar();
} else {
baz();
}
With this proposal:
if (foo) {
bar();
} else {
@cold();
baz();
}
How does this work with comptime-known coldness? The old approach would have been:
fn foo() void {
@setCold(comptime_foo_is_cold);
}
But with the new approach:
fn foo() void {
if (comptime_foo_is_cold) {
@cold(); // doesn't work, applies to the if body.
}
// function implementation
}
I guess this might work, since technically there's no scope:
fn foo() void {
if (comptime_foo_is_cold) @cold();
// function implementation
}
That later example would still apply to the then-body of the if statement, communicating that comptime_foo_is_cold is unlikely. Which if the value is comptime-known is meaningless and ignored since the compiler knows precisely whether the branch is taken.
This proposal removes the ability to specify comptime-known coldness. I would be happy to reconsider if there is a convincing enough use case for comptime-known coldness.
ZeeAlloc has manual size tuning using @setCold: https://github.com/fengb/zee_alloc/commit/b11ee8ee6747e292b375b2eae6df97dd2c866dbd#diff-d2841187941f93280c97ecaafd02aeb4R292
Thanks for the example. OK I'll amend the proposal to have @cold accept a comptime argument, same as @setCold. So the proposal is now essentially:
@setCold to @coldThere's a solution over at #5239 -- simple configuration is concise (@{cold};), and doesn't look deceptively like a function call; also, comptime configuration is always possible, but not so easy that it encourages users to go insane with it.