rustc invocation standarized (#992)

* rustc invocation standarized

* Addressed comments

* Addressed comments

* Addressed comments

* Updated command output
This commit is contained in:
Iñaki Garay 2020-12-28 19:34:51 -03:00 committed by GitHub
parent e0425a9563
commit 7268945c0f
17 changed files with 89 additions and 85 deletions

View File

@ -103,27 +103,27 @@ specifically the `#t-compiler/wg-llvm` stream.
### Compiler options to know and love
The `-Chelp` and `-Zhelp` compiler switches will list out a variety
The `-C help` and `-Z help` compiler switches will list out a variety
of interesting options you may find useful. Here are a few of the most
common that pertain to LLVM development (some of them are employed in the
tutorial above):
- The `--emit llvm-ir` option emits a `<filename>.ll` file with LLVM IR in textual format
- The `--emit llvm-bc` option emits in bytecode format (`<filename>.bc`)
- Passing `-Cllvm-args=<foo>` allows passing pretty much all the
- Passing `-C llvm-args=<foo>` allows passing pretty much all the
options that tools like llc and opt would accept;
e.g. `-Cllvm-args=-print-before-all` to print IR before every LLVM
e.g. `-C llvm-args=-print-before-all` to print IR before every LLVM
pass.
- The `-Cno-prepopulate-passes` will avoid pre-populate the LLVM pass
- The `-C no-prepopulate-passes` will avoid pre-populate the LLVM pass
manager with a list of passes. This will allow you to view the LLVM
IR that rustc generates, not the LLVM IR after optimizations.
- The `-Cpasses=val` option allows you to supply a space separated list of extra LLVM passes to run
- The `-Csave-temps` option saves all temporary output files during compilation
- The `-Zprint-llvm-passes` option will print out LLVM optimization passes being run
- The `-Ztime-llvm-passes` option measures the time of each LLVM pass
- The `-Zverify-llvm-ir` option will verify the LLVM IR for correctness
- The `-Zno-parallel-llvm` will disable parallel compilation of distinct compilation units
- The `-Zllvm-time-trace` option will output a Chrome profiler compatible JSON file
- The `-C passes=val` option allows you to supply a space separated list of extra LLVM passes to run
- The `-C save-temps` option saves all temporary output files during compilation
- The `-Z print-llvm-passes` option will print out LLVM optimization passes being run
- The `-Z time-llvm-passes` option measures the time of each LLVM pass
- The `-Z verify-llvm-ir` option will verify the LLVM IR for correctness
- The `-Z no-parallel-llvm` will disable parallel compilation of distinct compilation units
- The `-Z llvm-time-trace` option will output a Chrome profiler compatible JSON file
which contains details and timings for LLVM passes.
### Filing LLVM bug reports

View File

@ -32,10 +32,10 @@ fn main() {
```
Let's say the above is the content of a file called `immut.rs`. If we compile
`immut.rs` using the following command. The [`-Zdump-mir=all`][dump-mir] flag will cause
`immut.rs` using the following command. The [`-Z dump-mir=all`][dump-mir] flag will cause
`rustc` to generate and dump the [MIR][mir] to a directory called `mir_dump`.
```console
> rustc +stage1 immut.rs -Zdump-mir=all
> rustc +stage1 immut.rs -Z dump-mir=all
```
[mir]: ./mir/index.md
@ -146,7 +146,7 @@ codebase. For closures specifically, set the `RUST_LOG` env variable as below an
output in a file:
```console
> RUST_LOG=rustc_typeck::check::upvar rustc +stage1 -Zdump-mir=all \
> RUST_LOG=rustc_typeck::check::upvar rustc +stage1 -Z dump-mir=all \
<.rs file to compile> 2> <file where the output will be dumped>
```

View File

@ -82,28 +82,31 @@ For example:
```bash
$ cat error.rs
```
```rust
fn main() {
1 + ();
}
```
```bash
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc error.rs
error[E0277]: the trait bound `{integer}: std::ops::Add<()>` is not satisfied
$ rustc +stage1 error.rs
error[E0277]: cannot add `()` to `{integer}`
--> error.rs:2:7
|
2 | 1 + ();
| ^ no implementation for `{integer} + ()`
2 | 1 + ();
| ^ no implementation for `{integer} + ()`
|
= help: the trait `std::ops::Add<()>` is not implemented for `{integer}`
= help: the trait `Add<()>` is not implemented for `{integer}`
error: aborting due to previous error
```
$ # Now, where does the error above come from?
$ RUST_BACKTRACE=1 \
./build/x86_64-unknown-linux-gnu/stage1/bin/rustc \
error.rs \
-Z treat-err-as-bug
Now, where does the error above come from?
```bash
$ RUST_BACKTRACE=1 rustc +stage1 error.rs -Z treat-err-as-bug
error[E0277]: the trait bound `{integer}: std::ops::Add<()>` is not satisfied
--> error.rs:2:7
|
@ -140,9 +143,10 @@ stack backtrace:
(~~~ IRRELEVANT PART OF BACKTRACE REMOVED BY ME ~~~)
36: rustc_driver::run_compiler
at /home/user/rust/compiler/rustc_driver/src/lib.rs:253
$ # Cool, now I have a backtrace for the error
```
Cool, now I have a backtrace for the error!
## Getting logging output
[getting-logging-output]: #getting-logging-output
@ -180,16 +184,16 @@ So to put it together.
```bash
# This puts the output of all debug calls in `rustc_middle/src/traits` into
# standard error, which might fill your console backscroll.
$ RUSTC_LOG=rustc_middle::traits rustc +local my-file.rs
$ RUSTC_LOG=rustc_middle::traits rustc +stage1 my-file.rs
# This puts the output of all debug calls in `rustc_middle/src/traits` in
# `traits-log`, so you can then see it with a text editor.
$ RUSTC_LOG=rustc_middle::traits rustc +local my-file.rs 2>traits-log
$ RUSTC_LOG=rustc_middle::traits rustc +stage1 my-file.rs 2>traits-log
# Not recommended. This will show the output of all `debug!` calls
# in the Rust compiler, and there are a *lot* of them, so it will be
# hard to find anything.
$ RUSTC_LOG=debug rustc +local my-file.rs 2>all-log
$ RUSTC_LOG=debug rustc +stage1 my-file.rs 2>all-log
# This will show the output of all `info!` calls in `rustc_trans`.
#
@ -198,13 +202,13 @@ $ RUSTC_LOG=debug rustc +local my-file.rs 2>all-log
# which function triggers an LLVM assertion, and this is an `info!`
# log rather than a `debug!` log so it will work on the official
# compilers.
$ RUSTC_LOG=rustc_trans=info rustc +local my-file.rs
$ RUSTC_LOG=rustc_trans=info rustc +stage1 my-file.rs
# This will show the output of all `info!` calls made by rustdoc or any rustc library it calls.
$ RUSTDOC_LOG=info rustdoc +local my-file.rs
$ RUSTDOC_LOG=info rustdoc +stage1 my-file.rs
# This will only show `debug!` calls made by rustdoc directly, not any `rustc*` crate.
$ RUSTDOC_LOG=rustdoc rustdoc +local my-file.rs
$ RUSTDOC_LOG=rustdoc rustdoc +stage1 my-file.rs
```
### How to keep or remove `debug!` and `trace!` calls from the resulting binary
@ -271,7 +275,7 @@ In addition to [graphviz output](#formatting-graphviz-output-dot-files), MIR deb
flags include an option to generate a MIR representation called `Spanview` that
uses HTML to highlight code regions in the original source code and display
compiler metadata associated with each region.
[`-Zdump-mir-spanview`](./mir/debugging.md), for example, highlights spans
[`-Z dump-mir-spanview`](./mir/debugging.md), for example, highlights spans
associated with each MIR `Statement`, `Terminator`, and/or `BasicBlock`.
These `.html` files use CSS features to dynamically expand spans obscured by

View File

@ -263,7 +263,7 @@ There are two main ways to find where a given error is emitted:
the error emitting code is removed from the code where the error is
constructed behind a relatively deep call-stack. Even then, it is a good way
to get your bearings.
- Invoking `rustc` with the nightly-only flag `-Ztreat-err-as-bug=1`, which
- Invoking `rustc` with the nightly-only flag `-Z treat-err-as-bug=1`, which
will treat the first error being emitted as an Internal Compiler Error, which
allows you to use the environment variable `RUST_BACKTRACE=full` to get a
stack trace at the point the error has been emitted. Change the `1` to

View File

@ -1,6 +1,6 @@
# HIR Debugging
The `-Zunpretty=hir-tree` flag will dump out the HIR.
The `-Z unpretty=hir-tree` flag will dump out the HIR.
If you are trying to correlate `NodeId`s or `DefId`s with source code, the
`--pretty expanded,identified` flag may be useful.

View File

@ -12,10 +12,10 @@ the HIR. This makes HIR more amenable to analysis than a normal AST.
This chapter covers the main concepts of the HIR.
You can view the HIR representation of your code by passing the
`-Zunpretty=hir-tree` flag to rustc:
`-Z unpretty=hir-tree` flag to rustc:
```bash
cargo rustc -- -Zunpretty=hir-tree
cargo rustc -- -Z unpretty=hir-tree
```
### Out-of-band storage and the `Crate` type

View File

@ -308,7 +308,7 @@ $ ./x.py test src/test/<test-type> --blessed
[spanview-debugging]: compiler-debugging.md#viewing-spanview-output
[`coverage-llvmir`]: https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/coverage-llvmir
## Implementation Details of the `InstrumentCoverage` MIR Pass
## Implementation Details of the `InstrumentCoverage` MIR Pass
The bulk of the implementation of the `InstrumentCoverage` MIR pass is performed
by the [`Instrumentor`][instrumentor]. For each MIR (each non-const, non-inlined
@ -496,8 +496,8 @@ An visual, interactive representation of the final `CoverageSpan`s can be
generated with the following `rustc` flags:
```shell
$ rustc -Zinstrument-coverage -Zdump-mir=InstrumentCoverage \
-Zdump-mir-spanview some_rust_source.rs
$ rustc -Z instrument-coverage -Z dump-mir=InstrumentCoverage \
-Z dump-mir-spanview some_rust_source.rs
```
These flags request Spanview output for the `InstrumentCoverage` pass, and the

View File

@ -201,8 +201,8 @@ for (bb, block) in body.basic_blocks().iter_enumerated() {
### Graphviz Diagrams
When the results of a dataflow analysis are not what you expect, it often helps
to visualize them. This can be done with the `-Zdump-mir` flags described in
[Debugging MIR]. Start with `-Zdump-mir=F -Zdump-mir-dataflow`, where `F` is
to visualize them. This can be done with the `-Z dump-mir` flags described in
[Debugging MIR]. Start with `-Z dump-mir=F -Z dump-mir-dataflow`, where `F` is
either "all" or the name of the MIR body you are interested in.
These `.dot` files will be saved in your `mir_dump` directory and will have the

View File

@ -1,26 +1,26 @@
# MIR Debugging
The `-Zdump-mir` flag can be used to dump a text representation of the MIR.
The following optional flags, used in combination with `-Zdump-mir`, enable
The `-Z dump-mir` flag can be used to dump a text representation of the MIR.
The following optional flags, used in combination with `-Z dump-mir`, enable
additional output formats, including:
* `-Zdump-mir-graphviz` - dumps a `.dot` file that represents MIR as a
* `-Z dump-mir-graphviz` - dumps a `.dot` file that represents MIR as a
control-flow graph
* `-Zdump-mir-dataflow` - dumps a `.dot` file showing the [dataflow state] at
* `-Z dump-mir-dataflow` - dumps a `.dot` file showing the [dataflow state] at
each point in the control-flow graph
* `-Zdump-mir-spanview` - dumps an `.html` file that highlights the source
* `-Z dump-mir-spanview` - dumps an `.html` file that highlights the source
spans associated with MIR elements (including mouse-over actions to reveal
elements obscured by overlaps, and tooltips to view the MIR statements).
This flag takes an optional value: `statement` (the default), `terminator`, or
`block`, to generate span highlights with different levels of granulatity.
`-Zdump-mir=F` is a handy compiler options that will let you view the MIR for
each function at each stage of compilation. `-Zdump-mir` takes a **filter** `F`
`-Z dump-mir=F` is a handy compiler options that will let you view the MIR for
each function at each stage of compilation. `-Z dump-mir` takes a **filter** `F`
which allows you to control which functions and which passes you are
interesting in. For example:
```bash
> rustc -Zdump-mir=foo ...
> rustc -Z dump-mir=foo ...
```
This will dump the MIR for any function whose name contains `foo`; it
@ -34,7 +34,7 @@ fn main() {
println!("Hello, world!");
}
^D
> rustc -Zdump-mir=main foo.rs
> rustc -Z dump-mir=main foo.rs
> ls mir_dump/* | wc -l
161
```
@ -56,7 +56,7 @@ will select for things that reference *both* `main` and the pass
`CleanEndRegions`:
```bash
> rustc -Zdump-mir='main & CleanEndRegions' foo.rs
> rustc -Z dump-mir='main & CleanEndRegions' foo.rs
> ls mir_dump
rustc.main.000-000.CleanEndRegions.after.mir rustc.main.000-000.CleanEndRegions.before.mir
```
@ -67,7 +67,7 @@ NoLandingPads` will select *either* `main` and `CleanEndRegions` *or*
`main` and `NoLandingPads`:
```bash
> rustc -Zdump-mir='main & CleanEndRegions | main & NoLandingPads' foo.rs
> rustc -Z dump-mir='main & CleanEndRegions | main & NoLandingPads' foo.rs
> ls mir_dump
rustc.main-promoted[0].002-000.NoLandingPads.after.mir
rustc.main-promoted[0].002-000.NoLandingPads.before.mir

View File

@ -22,8 +22,8 @@ The ["Debugging LLVM"][d] section of the
rustc-dev-guide gives a step-by-step process for how to help debug bugs
caused by LLVM. In particular, it discusses how to emit LLVM IR, run
the LLVM IR optimization pipelines, and so forth. You may also find
it useful to look at the various codegen options listed under `-Chelp`
and the internal options under `-Zhelp` -- there are a number that
it useful to look at the various codegen options listed under `-C help`
and the internal options under `-Z help` -- there are a number that
pertain to LLVM (just search for LLVM).
[d]: ../backend/debugging.md

View File

@ -32,10 +32,10 @@ we'll talk about that later.
- The token stream passes through a higher-level lexer located in
[`rustc_parse`] to prepare for the next stage of the compile process. The
[`StringReader`] struct is used at this stage to perform a set of validations
and turn strings into interned symbols (_interning_ is discussed later).
[String interning] is a way of storing only one immutable
and turn strings into interned symbols (_interning_ is discussed later).
[String interning] is a way of storing only one immutable
copy of each distinct string value.
- The lexer has a small interface and doesn't depend directly on the
diagnostic infrastructure in `rustc`. Instead it provides diagnostics as plain
data which are emitted in `rustc_parse::lexer::mod` as real diagnostics.
@ -330,7 +330,7 @@ For more details on bootstrapping, see
- Does LLVM ever do optimizations in debug builds?
- How do I explore phases of the compile process in my own sources (lexer,
parser, HIR, etc)? - e.g., `cargo rustc -- -Zunpretty=hir-tree` allows you to
parser, HIR, etc)? - e.g., `cargo rustc -- -Z unpretty=hir-tree` allows you to
view HIR representation
- What is the main source entry point for `X`?
- Where do phases diverge for cross-compilation to machine code across
@ -363,7 +363,7 @@ For more details on bootstrapping, see
- Guide: [Identifiers in the HIR](https://rustc-dev-guide.rust-lang.org/hir.html#identifiers-in-the-hir)
- Guide: [The HIR Map](https://rustc-dev-guide.rust-lang.org/hir.html#the-hir-map)
- Guide: [Lowering AST to HIR](https://rustc-dev-guide.rust-lang.org/lowering.html)
- How to view HIR representation for your code `cargo rustc -- -Zunpretty=hir-tree`
- How to view HIR representation for your code `cargo rustc -- -Z unpretty=hir-tree`
- Rustc HIR definition: [`rustc_hir`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/index.html)
- Main entry point: **TODO**
- Late linting: **TODO**

View File

@ -54,11 +54,11 @@ coverage results for PGO has not been attempted at this time.
Generating a PGO-optimized program involves the following four steps:
1. Compile the program with instrumentation enabled (e.g. `rustc -Cprofile-generate main.rs`)
1. Compile the program with instrumentation enabled (e.g. `rustc -C profile-generate main.rs`)
2. Run the instrumented program (e.g. `./main`) which generates a `default-<id>.profraw` file
3. Convert the `.profraw` file into a `.profdata` file using LLVM's `llvm-profdata` tool.
4. Compile the program again, this time making use of the profiling data
(e.g. `rustc -Cprofile-use=merged.profdata main.rs`)
(e.g. `rustc -C profile-use=merged.profdata main.rs`)
### Compile-Time Aspects

View File

@ -1,29 +1,29 @@
# Profiling the compiler
This section talks about how to profile the compiler and find out where it spends its time.
This section talks about how to profile the compiler and find out where it spends its time.
Depending on what you're trying to measure, there are several different approaches:
- If you want to see if a PR improves or regresses compiler performance:
- The [rustc-perf](https://github.com/rust-lang/rustc-perf) project makes this easy and can be triggered to run on a PR via the `@rustc-perf` bot.
- If you want a medium-to-high level overview of where `rustc` is spending its time:
- The `-Zself-profile` flag and [measureme](https://github.com/rust-lang/measureme) tools offer a query-based approach to profiling.
- The `-Z self-profile` flag and [measureme](https://github.com/rust-lang/measureme) tools offer a query-based approach to profiling.
See [their docs](https://github.com/rust-lang/measureme/blob/master/summarize/Readme.md) for more information.
- If you want function level performance data or even just more details than the above approaches:
- Consider using a native code profiler such as [perf](profiling/with_perf.html)
- or [tracy](https://github.com/nagisa/rust_tracy_client) for a nanosecond-precision,
- Consider using a native code profiler such as [perf](profiling/with_perf.html)
- or [tracy](https://github.com/nagisa/rust_tracy_client) for a nanosecond-precision,
full-featured graphical interface.
- If you want a nice visual representation of the compile times of your crate graph,
you can use [cargo's `-Ztimings` flag](https://doc.rust-lang.org/cargo/reference/unstable.html#timings),
eg. `cargo -Ztimings build`.
You can use this flag on the compiler itself with `CARGOFLAGS="-Ztimings" ./x.py build`
- If you want a nice visual representation of the compile times of your crate graph,
you can use [cargo's `-Z timings` flag](https://doc.rust-lang.org/cargo/reference/unstable.html#timings),
eg. `cargo -Z timings build`.
You can use this flag on the compiler itself with `CARGOFLAGS="-Z timings" ./x.py build`
## Optimizing rustc's bootstrap times with `cargo-llvm-lines`
Using [cargo-llvm-lines](https://github.com/dtolnay/cargo-llvm-lines) you can count the
Using [cargo-llvm-lines](https://github.com/dtolnay/cargo-llvm-lines) you can count the
number of lines of LLVM IR across all instantiations of a generic function.
Since most of the time compiling rustc is spent in LLVM, the idea is that by
reducing the amount of code passed to LLVM, compiling rustc gets faster.
@ -67,12 +67,12 @@ Example output:
49714 (0.4%) 14 (0.0%) rustc_mir::dataflow::framework::graphviz::BlockFormatter<A>::write_node_label
```
Since this doesn't seem to work with incremental compilation or `x.py check`,
Since this doesn't seem to work with incremental compilation or `x.py check`,
you will be compiling rustc _a lot_.
I recommend changing a few settings in `config.toml` to make it bearable:
```
[rust]
# A debug build takes _a third_ as long on my machine,
# A debug build takes _a third_ as long on my machine,
# but compiling more than stage0 rustc becomes unbearably slow.
optimize = false
@ -88,7 +88,7 @@ codegen-units = 0 # num_cpus
The llvm-lines output is affected by several options.
`optimize = false` increases it from 2.1GB to 3.5GB and `codegen-units = 0` to 4.1GB.
MIR optimizations have little impact. Compared to the default `RUSTFLAGS="-Zmir-opt-level=1"`,
level 0 adds 0.3GB and level 2 removes 0.2GB.
MIR optimizations have little impact. Compared to the default `RUSTFLAGS="-Z mir-opt-level=1"`,
level 0 adds 0.3GB and level 2 removes 0.2GB.
Inlining currently only happens in LLVM, but this might change in the future.

View File

@ -150,7 +150,7 @@ the `cargo rustc` command, like so:
```bash
touch src/lib.rs
CARGO_INCREMENTAL=0 perf record -F99 --call-graph dwarf cargo rustc --profile check --lib -- -Zborrowck=mir
CARGO_INCREMENTAL=0 perf record -F99 --call-graph dwarf cargo rustc --profile check --lib -- -Z borrowck=mir
```
[pf]: https://github.com/nikomatsakis/perf-focus

View File

@ -11,7 +11,7 @@ The rustc compiler contains support for following sanitizers:
## How to use the sanitizers?
To enable a sanitizer compile with `-Zsanitizer=...` option, where value is one
To enable a sanitizer compile with `-Z sanitizer=...` option, where value is one
of `address`, `leak`, `memory` or `thread`. For more details how to use
sanitizers please refer to [the unstable book](https://doc.rust-lang.org/unstable-book/).
@ -49,7 +49,7 @@ libraries. Highlight of the most important aspects of the implementation:
* When producing an executable, the sanitizer specific runtime library is
[linked in][sanitizer-link]. The libraries are searched for in target libdir
relative to default system root, so that this process is not affected
by sysroot overrides used for example by cargo `-Zbuild-std` functionality.
by sysroot overrides used for example by cargo `-Z build-std` functionality.
[compiler-rt]: https://github.com/llvm/llvm-project/tree/master/compiler-rt
[sanitizer-build]: https://github.com/rust-lang/rust/blob/a29424a2265411dda7d7446516ac5fd7499e2b55/src/bootstrap/native.rs#L566-L624

View File

@ -129,9 +129,9 @@ default `allow`, but most of the standard library raises it to a warning with
[`deprecated` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute
## -Zforce-unstable-if-unmarked
## -Z force-unstable-if-unmarked
The `-Zforce-unstable-if-unmarked` flag has a variety of purposes to help
The `-Z force-unstable-if-unmarked` flag has a variety of purposes to help
enforce that the correct crates are marked as unstable. It was introduced
primarily to allow rustc and the standard library to link to arbitrary crates
on crates.io which do not themselves use `staged_api`. `rustc` also relies on
@ -152,9 +152,9 @@ This flag has the following effects:
attribute to use other unstable crates. However, that would make it
impossible for a crate from crates.io to access its own dependencies since
that crate won't have a `feature(rustc_private)` attribute, but *everything*
is compiled with `-Zforce-unstable-if-unmarked`.
is compiled with `-Z force-unstable-if-unmarked`.
Code which does not use `-Zforce-unstable-if-unmarked` should include the
Code which does not use `-Z force-unstable-if-unmarked` should include the
`#![feature(rustc_private)]` crate attribute to access these force-unstable
crates. This is needed for things that link `rustc`, such as `miri`, `rls`, or
`clippy`.

View File

@ -109,7 +109,7 @@ to specify a custom flag to give to rustc when the test is compiled:
```rust,ignore
// Test the behavior of `0 - 1` when overflow checks are disabled.
// compile-flags: -Coverflow-checks=off
// compile-flags: -C overflow-checks=off
fn main() {
let x = 0 - 1;