Remove docs for old -Z profile-queries flag
This commit is contained in:
parent
dfdff33685
commit
b5814b34da
|
|
@ -59,7 +59,6 @@
|
||||||
- [Incremental compilation](./queries/incremental-compilation.md)
|
- [Incremental compilation](./queries/incremental-compilation.md)
|
||||||
- [Incremental compilation In Detail](./queries/incremental-compilation-in-detail.md)
|
- [Incremental compilation In Detail](./queries/incremental-compilation-in-detail.md)
|
||||||
- [Debugging and Testing](./incrcomp-debugging.md)
|
- [Debugging and Testing](./incrcomp-debugging.md)
|
||||||
- [Profiling Queries](./queries/profiling.md)
|
|
||||||
- [Salsa](./salsa.md)
|
- [Salsa](./salsa.md)
|
||||||
- [Memory Management in Rustc](./memory.md)
|
- [Memory Management in Rustc](./memory.md)
|
||||||
- [Serialization in Rustc](./serialization.md)
|
- [Serialization in Rustc](./serialization.md)
|
||||||
|
|
|
||||||
|
|
@ -1,346 +0,0 @@
|
||||||
# Profiling Queries
|
|
||||||
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
In an effort to support _incremental compilation_, the latest design of the Rust
|
|
||||||
compiler consists of a _query-based_ model.
|
|
||||||
|
|
||||||
The details of this model are outside the scope of this document,
|
|
||||||
however, we explain [some background of this model](#background), in an effort
|
|
||||||
to explain how we profile its performance. We intend this profiling effort to
|
|
||||||
address [issue 42678](https://github.com/rust-lang/rust/issues/42678).
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
### 0. Enable debug assertions
|
|
||||||
|
|
||||||
```
|
|
||||||
./configure --enable-debug-assertions
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1. Compile `rustc`
|
|
||||||
|
|
||||||
Compile the compiler, up to at least stage 1:
|
|
||||||
|
|
||||||
```
|
|
||||||
./x.py build library/std
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Run `rustc`, with flags
|
|
||||||
|
|
||||||
Run the compiler on a source file, supplying two additional debugging flags with
|
|
||||||
`-Z`:
|
|
||||||
|
|
||||||
```
|
|
||||||
rustc -Z profile-queries -Z incremental=cache foo.rs
|
|
||||||
```
|
|
||||||
|
|
||||||
Regarding the two additional parameters:
|
|
||||||
|
|
||||||
- `-Z profile-queries` tells the compiler to run a separate thread that profiles
|
|
||||||
the queries made by the main compiler thread(s).
|
|
||||||
- `-Z incremental=cache` tells the compiler to "cache" various files that
|
|
||||||
describe the compilation dependencies, in the subdirectory `cache`.
|
|
||||||
|
|
||||||
This command will generate the following files:
|
|
||||||
|
|
||||||
- `profile_queries.html` consists of an HTML-based representation of the
|
|
||||||
[trace of queries](#trace-of-queries).
|
|
||||||
- `profile_queries.counts.txt` consists of a histogram, where each histogram
|
|
||||||
"bucket" is a query provider.
|
|
||||||
|
|
||||||
### 3. Run `rustc`, with `-Z time-passes`:
|
|
||||||
|
|
||||||
- This additional flag will add all timed passes to the output files mentioned
|
|
||||||
above, in step 2. As described below, these passes appear visually distinct
|
|
||||||
from the queries in the HTML output (they appear as green boxes, via
|
|
||||||
CSS).
|
|
||||||
|
|
||||||
### 4. Inspect the output
|
|
||||||
|
|
||||||
- 4(a). Open the HTML file (`profile_queries.html`) with a browser. See
|
|
||||||
[this section](#interpret-the-html-output) for an explanation of this file.
|
|
||||||
- 4(b). Open the data file (`profile_queries.counts.txt`) with a text editor, or
|
|
||||||
spreadsheet. See [this section](#interpret-the-data-output) for an explanation
|
|
||||||
of this file.
|
|
||||||
|
|
||||||
## Interpret the HTML Output
|
|
||||||
|
|
||||||
### Example 0
|
|
||||||
|
|
||||||
The following image gives some example output, from tracing the queries of
|
|
||||||
`hello_world.rs` (a single `main` function, that prints `"hello world"` via the
|
|
||||||
macro `println!`). This image only shows a short prefix of the total output; the
|
|
||||||
_actual_ output is much longer.
|
|
||||||
|
|
||||||
[][profile-example-html]
|
|
||||||
[View full HTML output][profile-example-html]. Note; it could take up
|
|
||||||
to a second to properly render depending on your browser.
|
|
||||||
|
|
||||||
Here is the corresponding [text output](./example-0.counts.txt).
|
|
||||||
|
|
||||||
[profile-example-html]: ./example-0.html
|
|
||||||
|
|
||||||
### Example 0 explanation
|
|
||||||
|
|
||||||
The trace of the queries has a formal structure; see
|
|
||||||
[Trace of Queries](#trace-of-queries) for details.
|
|
||||||
|
|
||||||
We style this formal structure as follows:
|
|
||||||
|
|
||||||
- **Timed passes:** Green boxes, when present (via `-Z time-passes`), represent
|
|
||||||
_timed passes_ in the compiler. As of <!-- date: 2021-01 --> January 2021
|
|
||||||
these passes are not queries, but may be replaced by queries in future versions.
|
|
||||||
- **Labels:** Some green and red boxes are labeled with text. Where they are
|
|
||||||
present, the labels give the following information:
|
|
||||||
- The [query's _provider_](#queries), sans its _key_ and its _result_, which
|
|
||||||
are often too long to include in these labels.
|
|
||||||
- The _duration_ of the provider, as a fraction of the total time (for the
|
|
||||||
entire trace). This fraction includes the query's entire extent (that is,
|
|
||||||
the sum total of all of its sub-queries).
|
|
||||||
- **Query hits:** Blue dots represent query hits. They consist of leaves in the
|
|
||||||
trace's tree. (CSS class: `hit`).
|
|
||||||
- **Query misses:** Red boxes represent query misses. They consist of internal
|
|
||||||
nodes in the trace's tree. (CSS class: `miss`).
|
|
||||||
- **Nesting structure:** Many red boxes contain _nested boxes and dots_. This
|
|
||||||
nesting structure reflects that some providers _depend on_ results from other
|
|
||||||
providers, which consist of their nested children.
|
|
||||||
- Some red boxes are _labeled_ with text, and have highlighted borders (light
|
|
||||||
red, and bolded). (See [heuristics](#heuristics) for details).
|
|
||||||
|
|
||||||
## Heuristics
|
|
||||||
|
|
||||||
Heuristics-based CSS Classes:
|
|
||||||
|
|
||||||
- `important` -- Trace nodes are `important` if they have an extent of 6 (or
|
|
||||||
more), _or_ they have a duration fraction of one percent (or more). These
|
|
||||||
numbers are simple heuristics (hard-coded, but easy to modify).
|
|
||||||
Important nodes are styled with textual labels, and highlighted borders (light
|
|
||||||
red, and bolded).
|
|
||||||
|
|
||||||
- `frac-50`, `-40`, ... -- Trace nodes whose total duration (self and children)
|
|
||||||
take a large fraction of the total duration, at or above 50%, 40%, and so on.
|
|
||||||
We style nodes these with larger font and padding.
|
|
||||||
|
|
||||||
## Interpret the Data Output
|
|
||||||
|
|
||||||
The file `profile_queries.counts.txt` contains a table of information about the
|
|
||||||
queries, organized around their providers.
|
|
||||||
|
|
||||||
For each provider (or timed pass, when `-Z time-passes` is present), we produce:
|
|
||||||
|
|
||||||
- A total **count** --- the total number of times this provider was queried
|
|
||||||
|
|
||||||
- A total **duration** --- the total number of seconds spent running this
|
|
||||||
provider, _including_ all providers it may depend on. To get a sense of this
|
|
||||||
dependency structure, and inspect a more fine-grained view of these durations,
|
|
||||||
see [this section](#interpret-the-html-output).
|
|
||||||
|
|
||||||
These rows are **sorted by total duration**, in descending order.
|
|
||||||
|
|
||||||
### Counts: Example 0
|
|
||||||
|
|
||||||
The following example `profile_queries.counts.txt` file results from running on
|
|
||||||
a hello world program (a single main function that uses `println` to print
|
|
||||||
`"hello world"`).
|
|
||||||
|
|
||||||
As explained above, the columns consist of `provider/pass`, `count`, `duration`:
|
|
||||||
|
|
||||||
```
|
|
||||||
translation,1,0.891
|
|
||||||
symbol_name,2658,0.733
|
|
||||||
def_symbol_name,2556,0.268
|
|
||||||
item_attrs,5566,0.162
|
|
||||||
type_of,6922,0.117
|
|
||||||
generics_of,8020,0.084
|
|
||||||
serialize dep graph,1,0.079
|
|
||||||
relevant_trait_impls_for,50,0.063
|
|
||||||
def_span,24875,0.061
|
|
||||||
expansion,1,0.059
|
|
||||||
const checking,1,0.055
|
|
||||||
adt_def,1141,0.048
|
|
||||||
trait_impls_of,32,0.045
|
|
||||||
is_copy_raw,47,0.045
|
|
||||||
is_foreign_item,2638,0.042
|
|
||||||
fn_sig,2172,0.033
|
|
||||||
adt_dtorck_constraint,2,0.023
|
|
||||||
impl_trait_ref,2434,0.023
|
|
||||||
typeck_tables_of,29,0.022
|
|
||||||
item-bodies checking,1,0.017
|
|
||||||
typeck_item_bodies,1,0.017
|
|
||||||
is_default_impl,2320,0.017
|
|
||||||
borrow checking,1,0.014
|
|
||||||
borrowck,4,0.014
|
|
||||||
mir_validated,4,0.013
|
|
||||||
adt_destructor,10,0.012
|
|
||||||
layout_raw,258,0.010
|
|
||||||
load_dep_graph,1,0.007
|
|
||||||
item-types checking,1,0.005
|
|
||||||
mir_const,2,0.005
|
|
||||||
name resolution,1,0.004
|
|
||||||
is_object_safe,35,0.003
|
|
||||||
is_sized_raw,89,0.003
|
|
||||||
parsing,1,0.003
|
|
||||||
is_freeze_raw,11,0.001
|
|
||||||
privacy checking,1,0.001
|
|
||||||
privacy_access_levels,5,0.001
|
|
||||||
resolving dependency formats,1,0.001
|
|
||||||
adt_sized_constraint,9,0.001
|
|
||||||
wf checking,1,0.001
|
|
||||||
liveness checking,1,0.001
|
|
||||||
compute_incremental_hashes_map,1,0.001
|
|
||||||
match checking,1,0.001
|
|
||||||
type collecting,1,0.001
|
|
||||||
param_env,31,0.000
|
|
||||||
effect checking,1,0.000
|
|
||||||
trait_def,140,0.000
|
|
||||||
lowering ast -> hir,1,0.000
|
|
||||||
predicates_of,70,0.000
|
|
||||||
extern_crate,319,0.000
|
|
||||||
lifetime resolution,1,0.000
|
|
||||||
is_const_fn,6,0.000
|
|
||||||
intrinsic checking,1,0.000
|
|
||||||
translation item collection,1,0.000
|
|
||||||
impl_polarity,15,0.000
|
|
||||||
creating allocators,1,0.000
|
|
||||||
language item collection,1,0.000
|
|
||||||
crate injection,1,0.000
|
|
||||||
early lint checks,1,0.000
|
|
||||||
indexing hir,1,0.000
|
|
||||||
maybe creating a macro crate,1,0.000
|
|
||||||
coherence checking,1,0.000
|
|
||||||
optimized_mir,6,0.000
|
|
||||||
is_panic_runtime,33,0.000
|
|
||||||
associated_item_def_ids,7,0.000
|
|
||||||
needs_drop_raw,10,0.000
|
|
||||||
lint checking,1,0.000
|
|
||||||
complete gated feature checking,1,0.000
|
|
||||||
stability index,1,0.000
|
|
||||||
region_maps,11,0.000
|
|
||||||
super_predicates_of,8,0.000
|
|
||||||
coherent_trait,2,0.000
|
|
||||||
AST validation,1,0.000
|
|
||||||
loop checking,1,0.000
|
|
||||||
static item recursion checking,1,0.000
|
|
||||||
variances_of,11,0.000
|
|
||||||
associated_item,5,0.000
|
|
||||||
plugin loading,1,0.000
|
|
||||||
looking for plugin registrar,1,0.000
|
|
||||||
stability checking,1,0.000
|
|
||||||
describe_def,15,0.000
|
|
||||||
variance testing,1,0.000
|
|
||||||
codegen unit partitioning,1,0.000
|
|
||||||
looking for entry point,1,0.000
|
|
||||||
checking for inline asm in case the target doesn't support it,1,0.000
|
|
||||||
inherent_impls,1,0.000
|
|
||||||
crate_inherent_impls,1,0.000
|
|
||||||
trait_of_item,7,0.000
|
|
||||||
crate_inherent_impls_overlap_check,1,0.000
|
|
||||||
attribute checking,1,0.000
|
|
||||||
internalize symbols,1,0.000
|
|
||||||
impl wf inference,1,0.000
|
|
||||||
death checking,1,0.000
|
|
||||||
reachability checking,1,0.000
|
|
||||||
reachable_set,1,0.000
|
|
||||||
is_exported_symbol,3,0.000
|
|
||||||
is_mir_available,2,0.000
|
|
||||||
unused lib feature checking,1,0.000
|
|
||||||
maybe building test harness,1,0.000
|
|
||||||
recursion limit,1,0.000
|
|
||||||
write allocator module,1,0.000
|
|
||||||
assert dep graph,1,0.000
|
|
||||||
plugin registration,1,0.000
|
|
||||||
write metadata,1,0.000
|
|
||||||
```
|
|
||||||
|
|
||||||
# Background
|
|
||||||
|
|
||||||
We give some background about the query model of the Rust compiler.
|
|
||||||
|
|
||||||
## Def IDs
|
|
||||||
|
|
||||||
In the query model, many queries have a key that consists of a Def ID. The Rust
|
|
||||||
compiler uses Def IDs to distinguish definitions in the input Rust program.
|
|
||||||
|
|
||||||
From the compiler source code (`compiler/rustc_span/src/def_id.rs`):
|
|
||||||
|
|
||||||
```
|
|
||||||
/// A DefId identifies a particular *definition*, by combining a crate
|
|
||||||
/// index and a def index.
|
|
||||||
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, RustcDecodable, Hash, Copy)]
|
|
||||||
pub struct DefId {
|
|
||||||
pub krate: CrateNum,
|
|
||||||
pub index: DefIndex,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Queries
|
|
||||||
|
|
||||||
A query relates a _key_ to a _result_, either by invoking a _provider_ that
|
|
||||||
computes this result, or by reusing a cached result that was provided earlier.
|
|
||||||
We explain each term in more detail:
|
|
||||||
|
|
||||||
- Query **Provider**: Each kind of query has a pre-defined _provider_, which
|
|
||||||
refers to the compiler behavior that provides an answer to the query. These
|
|
||||||
providers may nest; see [trace of queries](#trace-of-queries) for more
|
|
||||||
information about this nesting structure.
|
|
||||||
_Example providers:_
|
|
||||||
- `typeck` -- Typecheck a Def ID; produce "tables" of type
|
|
||||||
information.
|
|
||||||
- `borrowck` -- Borrow-check a Def ID.
|
|
||||||
- `optimized_mir` -- Generate an optimized MIR for a Def ID; produce MIR.
|
|
||||||
- For more examples, see [Example 0](#counts-example-0).
|
|
||||||
- Query **Key**: The input/arguments to the provider. Often, this consists of a
|
|
||||||
particular [Def ID](#def-ids).
|
|
||||||
- Query **Result**: The output of the provider.
|
|
||||||
|
|
||||||
## Trace of Queries
|
|
||||||
|
|
||||||
Formally, a _trace_ of the queries consists of a _tree_, where sub-trees
|
|
||||||
represent sub-traces. In particular, the nesting structure of the trace of
|
|
||||||
queries describes how the queries depend on one another.
|
|
||||||
|
|
||||||
Even more precisely, this tree represents a directed acyclic graph (DAG), where
|
|
||||||
shared sub-graphs consist of tree nodes that occur multiple times in the tree,
|
|
||||||
first as "cache misses" and later as "cache hits".
|
|
||||||
|
|
||||||
**Cache hits and misses.** The trace is a tree with the following possible tree
|
|
||||||
nodes:
|
|
||||||
|
|
||||||
- Query, with cache **miss**: The query's result is **unknown**, and its
|
|
||||||
provider runs to compute it. In this case, the dynamic extent of the query's
|
|
||||||
trace consists of the traced behavior of its provider.
|
|
||||||
- Query, with cache **hit**: The query's result is **known**, and is reused; its
|
|
||||||
provider does not rerun. These nodes are leaves in the trace, since they have
|
|
||||||
no dynamic extent. These leaves also represent where the tree, represented as
|
|
||||||
a DAG, would _share_ a sub-graph (namely, the sub-graph of the query that was
|
|
||||||
reused from the cache).
|
|
||||||
|
|
||||||
**Tree node metrics.** To help determine how to style this tree, we define the
|
|
||||||
following tree node metrics:
|
|
||||||
|
|
||||||
- **Depth**: The number of **ancestors** of the node in its path from the tree
|
|
||||||
root.
|
|
||||||
- **Extent**: The number of **immediate children** of the node.
|
|
||||||
|
|
||||||
Intuitively, a dependency tree is "good" for incremental caching when the depth
|
|
||||||
and extent of each node is relatively small. It is pathological when either of
|
|
||||||
these metrics grows too large. For instance, a tree node whose extent consists
|
|
||||||
of 1M immediate children means that if and when this node is re-computed, all 1M
|
|
||||||
children must be re-queried, at the very least (some may also require
|
|
||||||
recomputation, too).
|
|
||||||
|
|
||||||
## External Links
|
|
||||||
|
|
||||||
Related design ideas, and tracking issues:
|
|
||||||
|
|
||||||
- Design document:
|
|
||||||
[On-demand Rustc incremental design doc](https://github.com/nikomatsakis/rustc-on-demand-incremental-design-doc/blob/master/0000-rustc-on-demand-and-incremental.md)
|
|
||||||
- Tracking Issue:
|
|
||||||
["Red/Green" dependency tracking in compiler](https://github.com/rust-lang/rust/issues/42293)
|
|
||||||
|
|
||||||
More discussion and issues:
|
|
||||||
|
|
||||||
- [GitHub issue #42633](https://github.com/rust-lang/rust/issues/42633)
|
|
||||||
- [Incremental Compilation Beta](https://internals.rust-lang.org/t/incremental-compilation-beta/4721)
|
|
||||||
- [Incremental Compilation Announcement](https://blog.rust-lang.org/2016/09/08/incremental.html)
|
|
||||||
21
src/query.md
21
src/query.md
|
|
@ -41,6 +41,8 @@ The [Incremental Compilation in Detail][query-model] chapter gives a more
|
||||||
in-depth description of what queries are and how they work.
|
in-depth description of what queries are and how they work.
|
||||||
If you intend to write a query of your own, this is a good read.
|
If you intend to write a query of your own, this is a good read.
|
||||||
|
|
||||||
|
[query-model]: queries/incremental-compilation-in-detail.md
|
||||||
|
|
||||||
### Invoking queries
|
### Invoking queries
|
||||||
|
|
||||||
To invoke a query is simple. The tcx ("type context") offers a method
|
To invoke a query is simple. The tcx ("type context") offers a method
|
||||||
|
|
@ -288,4 +290,21 @@ rustc_queries! {
|
||||||
|
|
||||||
`rustc_queries` macro will generate an appropriate `impl` automatically.
|
`rustc_queries` macro will generate an appropriate `impl` automatically.
|
||||||
|
|
||||||
[query-model]: queries/incremental-compilation-in-detail.md
|
## External Links
|
||||||
|
|
||||||
|
Related design ideas, and tracking issues:
|
||||||
|
|
||||||
|
- Design document: [On-demand Rustc incremental design doc]
|
||||||
|
- Tracking Issue: ["Red/Green" dependency tracking in compiler]
|
||||||
|
|
||||||
|
More discussion and issues:
|
||||||
|
|
||||||
|
- [GitHub issue #42633]
|
||||||
|
- [Incremental Compilation Beta]
|
||||||
|
- [Incremental Compilation Announcement]
|
||||||
|
|
||||||
|
[On-demand Rustc incremental design doc]: https://github.com/nikomatsakis/rustc-on-demand-incremental-design-doc/blob/master/0000-rustc-on-demand-and-incremental.md
|
||||||
|
["Red/Green" dependency tracking in compiler]: https://github.com/rust-lang/rust/issues/42293
|
||||||
|
[GitHub issue #42633]: https://github.com/rust-lang/rust/issues/42633
|
||||||
|
[Incremental Compilation Beta]: https://internals.rust-lang.org/t/incremental-compilation-beta/4721
|
||||||
|
[Incremental Compilation Announcement]: https://blog.rust-lang.org/2016/09/08/incremental.html
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue