-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed as not planned
Labels
breakingImplementing this issue could cause existing code to no longer compile or have different behavior.Implementing this issue could cause existing code to no longer compile or have different behavior.proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone
Description
Loosely inspired by #489 (comment) and #20642 (comment).
This proposal supplants:
- @expect() hint to optimizer #489
- replace
@setColdwith@cold#5177 - introduce
@branchWeightbuiltin with numerical branch weights #20642
Introduces a new keyword, reachable, which takes an optional block label, just like break and continue.
Combined, these changes allow branches to hint about how likely or unlikely they are to be reached from any given location.
Basic example syntax:
if (x > 100) {
reachable .likely;
// ...
} else {
// ...
}Advanced example syntax (combined with #8220):
a: switch (x) {
0 => b: {
reachable :a .likely;
continue :a 1;
},
1 => {
reachable :a .unlikely;
reachable :b .likely;
// ...
},
// ...
}pub const BranchHint = enum {
/// This branch of control flow is more likely to be reached than its peers.
/// The optimizer should optimize for reaching it.
likely,
/// Equivalent to no hint given. Compile error to use this value literally.
baseline,
/// This branch of control flow is less likely to be reached than its peers.
/// The optimizer should optimize for not reaching it.
unlikely,
/// This branch of control flow is unlikely to *ever* be reached.
/// The optimizer may place it in a different page of memory to optimize other branches.
cold,
/// For unlabeled `reachable` this is equivalent to the `unreachable`
/// keyword and thus a compile error to use this value literally because `unreachable` must be
/// used instead.
never,
/// It is difficult to predict whether this branch of control flow will be reached.
/// The optimizer should avoid branching behavior with expensive mispredictions.
unpredictable,
};Some rules:
- The BranchHint value is a comptime expression.
- For comparison purposes, "likely" compares greater than than "baseline" (default unannotated branch weight), which compares greater than "unlikely". Equal weight branches are allowed.
- All branches that lead to a
@panic(including from safety check) implicitly are "cold". - It is safety-checked illegal behavior to jump to a branch with a "never reachable" hint with a label corresponding to the jumped-from block.
- Multiple
reachablestatements for the same (or no) label is a compile error. - Just like how
unreachableis required to terminate a block, allreachablestatements are required to be at the beginning of a block.
Furthermore:
- No "expect" builtin or similar.
- No
@coldor@setColdbuiltin. (replaced byreachable .cold;at the beginning of the function. - Error branches (weight error branches against errors #84) get a default hint of
unlikelyand can be overridden with thisreachablekeyword.
Compared to the existing proposals, this generalizes better to switch expressions, and it actually addresses labeled continue syntax inside switch expressions, as well as loops in general.
I will make a separate followup proposal for annotating source with PGO data.
Alternate syntax idea: comefrom 😜
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
breakingImplementing this issue could cause existing code to no longer compile or have different behavior.Implementing this issue could cause existing code to no longer compile or have different behavior.proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.This issue suggests modifications. If it also has the "accepted" label then it is planned.