Skip to content

Add tracing to InterpCx::layout_of() #142721

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

Merged
merged 2 commits into from
Jun 27, 2025
Merged

Conversation

Stypox
Copy link
Contributor

@Stypox Stypox commented Jun 19, 2025

This PR adds tracing calls to instantiate_from_frame_and_normalize_erasing_regions and to InterpCx::layout_of(). The latter is done by shadowing LayoutOf's trait method with an inherent method on InterpCx.

Previous attempt by overriding the `layout_of` query (includes downloadable `.diff` patch)

This PR is meant for Miri, but requires a few changes in rustc code, hence why it's here. It adds tracing capabilities to the layout_of function in tcx by overriding the layout_of query (under local_providers) with a wrapper that opens a tracing span and then calls the actual layout_of. To make this possible, I had to make rustc_ty_utils::layout::layout_of public. I added an assert to ensure the providers.layout_of value I am replacing is actually rustc_ty_utils::layout::layout_of, just in case.

I also considered taking the previous value in providers.layout_of and calling that one instead, to avoid making layout_of public. But then the closure would not be castable to a function pointer anymore (providers.layout_of is a function pointer), because it would depend on the local variable storing the previous value of providers.layout_of. Using a global variable would work but would rely on unsafe or on Mutexes, so I wanted to avoid it.

Here is some tracing output when Miri is run on src/tools/miri/tests/pass/hello.rs, visualizable in https://ui.perfetto.dev: trace-1750338860374637.json

Another place where I could have added tracing calls is to the rustc_middle::ty::layout::LayoutCx struct / spanned_layout_of() function, however there is no simple way to disable the tracing calls with compile-time boolean constants there (since LayoutCx::new() is used everywhere and referenced directly), and in any case it seems like spanned_layout_of() just calls tcx.layout_of() anyway. For completeness' sake, here is tracing output for when a tracing call is added to spanned_layout_of(): trace-1750340887920584.json

Patch to override layout_of query: tracing-layout_of-query-override.diff.txt

Note: obtaining tracing output depends on rust-lang/miri#4406, but this PR is standalone and can be merged without waiting for rust-lang/miri#4406.

r? @RalfJung

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 19, 2025
Comment on lines 149 to 158
assert!(std::ptr::fn_addr_eq(providers.layout_of, rustc_ty_utils::layout_of as
for<'tcx> fn(TyCtxt<'tcx>, PseudoCanonicalInput<'tcx, Ty<'tcx>>) -> Result<TyAndLayout<'tcx>, &'tcx LayoutError<'tcx>>));
providers.layout_of = |tcx, query| {
let _span = tracing::info_span!("tcx.layout_of", "query = {:?}", query.value.kind()).entered();
rustc_ty_utils::layout_of(tcx, query)
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What a hack.^^

But also, this will only measure the time inside the query, not the time spent in the query machinery, so I think this is the wrong place to add the tracing span.

Ultimately we want to catch all the self.layout_of calls in InterpCx. Maybe just add a new inherent method, which should take priority over the trait method, and do the tracing there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ultimately we want to catch all the self.layout_of calls in InterpCx. Maybe just add a new inherent method, which should take priority over the trait method, and do the tracing there?

Oh ok, thanks for clarifying. I pushed a commit that does that, and added a comment on the inherent method hoping it won't cause confusion. Here is a trace collected with both the query override and the inherent method: trace-1751014622990785.json

Should I keep the query override? I think it may still provide useful info, as by looking at the trace it seems like the layout_of query is sometimes called outside of InterpCx::layout_of.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer not to have the query override -- but it may be good to figure out where those "outside" calls are coming from. They may be coming from other parts of the compiler, not from Miri itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I removed that commit and added a todo on my side to figure out where the "outside" calls come from

@Stypox Stypox force-pushed the tracing-layout-of branch from 8c4dd93 to a1a54ca Compare June 27, 2025 09:47
@Stypox Stypox force-pushed the tracing-layout-of branch from a1a54ca to 708dc15 Compare June 27, 2025 09:51
@Stypox Stypox changed the title Add tracing in Miri for tcx.layout_of calls Add tracing to InterpCx::layout_of() Jun 27, 2025
@Stypox
Copy link
Contributor Author

Stypox commented Jun 27, 2025

@rustbot ready

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 27, 2025
@Stypox Stypox marked this pull request as ready for review June 27, 2025 10:11
@rustbot
Copy link
Collaborator

rustbot commented Jun 27, 2025

The Miri subtree was changed

cc @rust-lang/miri

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@RalfJung
Copy link
Member

Thanks!
@bors r+ rollup

@bors
Copy link
Collaborator

bors commented Jun 27, 2025

📌 Commit 708dc15 has been approved by RalfJung

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 27, 2025
bors added a commit that referenced this pull request Jun 27, 2025
Rollup of 10 pull requests

Successful merges:

 - #142270 (Rustdoc js: even more typechecking improvements)
 - #142420 (Report infer ty errors during hir ty lowering)
 - #142671 (add #![rustc_no_implicit_bounds])
 - #142721 (Add tracing to `InterpCx::layout_of()` )
 - #142818 (Port `#[used]` to new attribute parsing infrastructure)
 - #143020 (codegen_fn_attrs: make comment more precise)
 - #143051 (Add tracing to `validate_operand`)
 - #143060 (Only args in main diag are saved and restored without removing the newly added ones)
 - #143065 (Improve recovery when users write `where:`)
 - #143084 (const-eval: error when initializing a static writes to that static)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 6d8f74d into rust-lang:master Jun 27, 2025
10 checks passed
@rustbot rustbot added this to the 1.90.0 milestone Jun 27, 2025
rust-timer added a commit that referenced this pull request Jun 27, 2025
Rollup merge of #142721 - Stypox:tracing-layout-of, r=RalfJung

Add tracing to `InterpCx::layout_of()`

This PR adds tracing calls to `instantiate_from_frame_and_normalize_erasing_regions` and to `InterpCx::layout_of()`. The latter is done by shadowing `LayoutOf`'s trait method with an inherent method on `InterpCx`.

<details><summary>Previous attempt by overriding the `layout_of` query (includes downloadable `.diff` patch)</summary>

This PR is meant for Miri, but requires a few changes in `rustc` code, hence why it's here. It adds tracing capabilities to the `layout_of` function in `tcx` by overriding the `layout_of` query (under `local_providers`) with a wrapper that opens a tracing span and then calls the actual `layout_of`. To make this possible, I had to make `rustc_ty_utils::layout::layout_of` public. I added an assert to ensure the `providers.layout_of` value I am replacing is actually `rustc_ty_utils::layout::layout_of`, just in case.

I also considered taking the previous value in `providers.layout_of` and calling that one instead, to avoid making `layout_of` public. But then the closure would not be castable to a function pointer anymore (`providers.layout_of` is a function pointer), because it would depend on the local variable storing the previous value of `providers.layout_of`. Using a global variable would work but would rely on `unsafe` or on `Mutex`es, so I wanted to avoid it.

Here is some tracing output when Miri is run on `src/tools/miri/tests/pass/hello.rs`, visualizable in https://ui.perfetto.dev: [trace-1750338860374637.json](https://github.com/user-attachments/files/20820392/trace-1750338860374637.json)

Another place where I could have added tracing calls is to the `rustc_middle::ty::layout::LayoutCx` struct / `spanned_layout_of()` function, however there is no simple way to disable the tracing calls with compile-time boolean constants there (since `LayoutCx::new()` is used everywhere and referenced directly), and in any case it seems like `spanned_layout_of()` just calls `tcx.layout_of()` anyway. For completeness' sake, here is tracing output for when a tracing call is added to `spanned_layout_of()`: [trace-1750340887920584.json](https://github.com/user-attachments/files/20820609/trace-1750340887920584.json)

Patch to override `layout_of` query: [tracing-layout_of-query-override.diff.txt](https://github.com/user-attachments/files/20944497/tracing-layout_of-query-override.diff.txt)

</details>

**Note: obtaining tracing output depends on rust-lang/miri#4406, but this PR is standalone and can be merged without waiting for rust-lang/miri#4406

r? `@RalfJung`
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Jun 28, 2025
Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#142270 (Rustdoc js: even more typechecking improvements)
 - rust-lang/rust#142420 (Report infer ty errors during hir ty lowering)
 - rust-lang/rust#142671 (add #![rustc_no_implicit_bounds])
 - rust-lang/rust#142721 (Add tracing to `InterpCx::layout_of()` )
 - rust-lang/rust#142818 (Port `#[used]` to new attribute parsing infrastructure)
 - rust-lang/rust#143020 (codegen_fn_attrs: make comment more precise)
 - rust-lang/rust#143051 (Add tracing to `validate_operand`)
 - rust-lang/rust#143060 (Only args in main diag are saved and restored without removing the newly added ones)
 - rust-lang/rust#143065 (Improve recovery when users write `where:`)
 - rust-lang/rust#143084 (const-eval: error when initializing a static writes to that static)

r? `@ghost`
`@rustbot` modify labels: rollup
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants