Skip to content

Commit 31d230b

Browse files
committed
Re-write text to propose likely/unlikely instead of expect
It's clear that `likely`/`unlikely` is the more popular option, so make that the main focus. Also expands on the guarantees the intrinsics provide (i.e. none) and mentions the prevalance of `LIKELY`/`UNLIKELY` macros in many C/C++ projects.
1 parent e6da401 commit 31d230b

File tree

1 file changed

+22
-9
lines changed

1 file changed

+22
-9
lines changed

text/0000-expect-intrinsic.md

+22-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
# Summary
77

8-
Provide an intrinsic function for hinting the likelyhood of branches being taken.
8+
Provide a pair of intrinsic functions for hinting the likelyhood of branches being taken.
99

1010
# Motivation
1111

@@ -22,21 +22,34 @@ quintillion cases.
2222

2323
# Detailed design
2424

25-
Implement an `expect` intrinsic with the signature: `fn(bool, bool) -> bool`. The first argument is
26-
the condition being tested, the second argument is the expected result. The return value is the
27-
same as the first argument, meaning that `if foo == bar { .. }` can be simply replaced with
28-
`if expect(foo == bar, false) { .. }`.
25+
Implement a pair of intrinsics `likely` and `unlikely`, both with signature `fn(bool) -> bool`
26+
which hint at the probability of the passed value being true or false. Specifically, `likely` hints
27+
to the compiler that the passed value is likely to be true, and `unlikely` hints that it is likely
28+
to be false. Both functions simply return the value they are passed.
2929

30-
The expected value is required to be a constant value.
30+
The primary reason for this design is that it reflects common usage of this general feature in many
31+
C and C++ projects, most of which define simple `LIKELY` and `UNLIKELY` macros around the gcc
32+
`__builtin_expect` intrinsic. It also provides the most flexibility, allowing branches on any
33+
condition to be hinted at, even if the process that produced the branched-upon value is
34+
complex. For why an equivalent to `__builtin_expect` is not being exposed, see the Alternatives
35+
section.
36+
37+
There are no observable changes in behaviour from use of these intrinsics. It is valid to implement
38+
these intrinsics simply as the identity function. Though it is expected that the intrinsics provide
39+
information to the optimizer, that information is not guaranteed to change the decisions the
40+
optimiser makes.
3141

3242
# Drawbacks
3343

34-
The second argument is required to be a constant value, which can't be easily expressed.
44+
The intrinsics cannot be used to hint at arms in `match` expressions. However, given that hints
45+
would need to be variants, a simple intrinsic would not be sufficient for those purposes.
3546

3647
# Alternatives
3748

38-
Provide a pair of intrinsics `likely` and `unlikely`, these are the same as `expect` just with
39-
`true` and `false` substituted in for the expected value, respectively.
49+
Expose an `expect` intrinsic. This is what gcc/clang does with `__builtin_expect`. However there is
50+
a restriction that the second argument be a constant value, a requirement that is not easily
51+
expressible in Rust code. The split into `likely` and `unlikely` intrinsics reflects the strategy
52+
we have used for similar restrictions like the ordering constraint of the atomic intrinsics.
4053

4154
# Unresolved questions
4255

0 commit comments

Comments
 (0)