mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
![]() improve cold_path() #120370 added a new instrinsic `cold_path()` and used it to fix `likely` and `unlikely` However, in order to limit scope, the information about cold code paths is only used in 2-target switch instructions. This is sufficient for `likely` and `unlikely`, but limits usefulness of `cold_path` for idiomatic rust. For example, code like this: ``` if let Some(x) = y { ... } ``` may generate 3-target switch: ``` switch y.discriminator: 0 => true branch 1 = > false branch _ => unreachable ``` and therefore marking a branch as cold will have no effect. This PR improves `cold_path()` to work with arbitrary switch instructions. Note that for 2-target switches, we can use `llvm.expect`, but for multiple targets we need to manually emit branch weights. I checked Clang and it also emits weights in this situation. The Clang's weight calculation is more complex that this PR, which I believe is mainly because `switch` in `C/C++` can have multiple cases going to the same target. |
||
---|---|---|
.. | ||
aggregate-thin-pointer.rs | ||
carrying_mul_add.rs | ||
cold_path2.rs | ||
cold_path3.rs | ||
cold_path.rs | ||
compare_bytes.rs | ||
const_eval_select.rs | ||
ctlz.rs | ||
ctpop.rs | ||
disjoint_bitor.rs | ||
exact_div.rs | ||
likely_assert.rs | ||
likely.rs | ||
mask.rs | ||
nearby.rs | ||
nontemporal.rs | ||
offset_from.rs | ||
offset.rs | ||
prefetch.rs | ||
ptr_metadata.rs | ||
rotate_left.rs | ||
rustc_intrinsic_must_be_overridden.rs | ||
select_unpredictable.rs | ||
three_way_compare.rs | ||
transmute-niched.rs | ||
transmute-x64.rs | ||
transmute.rs | ||
typed_swap.rs | ||
unchecked_math.rs | ||
unlikely.rs | ||
volatile_order.rs | ||
volatile.rs |