-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
coverage: Replace ExpressionOperandId
with enum Operand
#113428
Conversation
r? @jackh726 (rustbot has picked a reviewer for you, use r? to override) |
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
@rustbot label +A-code-coverage |
d21eb94
to
cf38b8d
Compare
ExpressionOperandId
with enum Operand
ExpressionOperandId
with enum Operand
787b627
to
5c4dd5b
Compare
r? compiler |
(I've been rebasing this periodically because I have local changes that build on top of it, but the actual changes in this PR should be stable/complete.) |
0620d11
to
b6c0982
Compare
766b854
to
088d7b0
Compare
i'm not really qualified to review this r? compiler |
Nominating to signal boost this PR and help find a reviewer with more context @rustbot label +I-compiler-nominated |
I’m happy to help guide someone through this as necessary. It’s not actually doing anything fundamentally complicated, since it’s mostly just replacing a u32 with an enum and then tidying up afterwards. |
dde3122
to
d816611
Compare
The actual motivation here is to prevent `rustfmt` from suddenly reformatting these enum variants onto a single line, when they become slightly shorter in the future. But there's no harm in adding some helpful documentation at the same time.
Because the three kinds of operand are now distinguished explicitly, we no longer need fiddly code to disambiguate counter IDs and expression IDs based on the total number of counters/expressions in a function. This does increase the size of operands from 4 bytes to 8 bytes, but that shouldn't be a big deal since they are mostly stored inside boxed structures, and the current coverage code is not particularly size-optimized anyway.
Operand types are now tracked explicitly, so there is no need for expression IDs to avoid counter IDs by descending from `u32::MAX`. Instead they can just count up from 0, and can be used directly as indices when necessary.
Operand types are now tracked explicitly, so there is no need to reserve ID 0 for the special always-zero counter. As part of the renumbering, this change fixes an off-by-one error in the way counters were counted by the `coverageinfo` query. As a result, functions should now have exactly the number of counters they actually need, instead of always having an extra counter that is never used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great, I've left one nitpick comment which isn't a big deal so I'll just go ahead and approve this.
/// expression. Counter/expression operands are referred to by ID. | ||
#[derive(Copy, Clone, PartialEq, Eq)] | ||
#[derive(TyEncodable, TyDecodable, Hash, HashStable, TypeFoldable, TypeVisitable)] | ||
pub enum Operand { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe we could rename this to CoverageOperand
(or something like that), just because mir::Operand
is quite common and it could be easy to get mixed up when reading the coverage code for the first time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I haven't interacted directly with actual MIR very much, so this didn't occur to me.
I have a bunch of other changes stacked up behind this one that use Operand
, so to avoid churning those I definitely won't be renaming it in the near future. But it's something to bear in mind once my current coverage work has settled down.
@bors r+ |
…iaskrgr Rollup of 7 pull requests Successful merges: - rust-lang#100455 (Implement RefUnwindSafe for Backtrace) - rust-lang#113428 (coverage: Replace `ExpressionOperandId` with enum `Operand`) - rust-lang#114283 (Use parking lot's rwlock even without parallel-rustc) - rust-lang#114288 (Improve diagnostic for wrong borrow on binary operations) - rust-lang#114296 (interpret: fix alignment handling for Repeat expressions) - rust-lang#114306 ([rustc_data_structures][perf] Simplify base_n::push_str.) - rust-lang#114320 (Cover statements for stable_mir) r? `@ghost` `@rustbot` modify labels: rollup
This is one step in my larger coverage refactoring ambitions described at rust-lang/compiler-team#645.
LLVM coverage has a concept of “mapping expressions” that allow a span's execution count to be computed as a simple arithmetic expression over other counters/expressions, instead of requiring a dedicated physical counter for every control-flow branch.
These expressions have an operator (
+
or-
) and two operands. Operands are currently represented asExpressionOperandId
, which wraps au32
with the following semantics:u32::MAX
represent the IDs of other expressionsThis change replaces that whole
ExpressionOperandId
scheme with a simple enum that explicitly distinguishes between the three cases.This lets us remove a lot of fiddly code for dealing with the different operand kinds:
u32::MAX
and then get translated into zero-based indices in certain places. Now that they ascend from zero, they can be used as indices directly.(Making counter IDs ascend from 0 also lets us fix an off-by-one error in the query for counting the total number of counters, which would cause LLVM to emit an extra unused counter for every instrumented function.)
This PR may be easiest to review as individual patches, since that breaks it up into clearly distinct parts:
u32
wrapper with an explicit enum, without changing the semantics of the underlying IDs being stored.Operand::Expression
to make expression IDs ascend from 0 (instead of descending fromu32::MAX
).Operand::Counter
to make counter IDs ascend from 0 (instead of ascending from 1).