# `cargo-remark` [![Build Status]][actions] [![Latest Version]][crates.io] [Build Status]: https://github.com/kobzol/cargo-remark/actions/workflows/check.yml/badge.svg [actions]: https://github.com/kobzol/cargo-remark/actions?query=branch%3Amain [Latest Version]: https://img.shields.io/crates/v/cargo-remark.svg [crates.io]: https://crates.io/crates/cargo-remark **Cargo subcommand that makes it possible to view LLVM [optimization remarks](https://llvm.org/docs/Remarks.html) generated during the compilation of your crate.** These remarks can tell you where and why has LLVM failed to apply certain optimizations. In certain cases[^1], you can use this knowledge to change your code so that it optimizes better. In the future, I hope that `rustc` will be able to emit its own, Rust-specific (MIR?) optimization remarks, but this is just an idea at this point. [^1]: Currently, probably only if you are a LLVM expert. `cargo remark` compiles your crate, generates LLVM remarks, and then parses them and visualizes them in a simple website. It is parallelized, which is important for large programs, because there can be a lot of remarks and since they are in YAML, their parsing is not very fast. **Contributions are welcome!** # Generated output example ![Screenshot of a set of visualized remarks on top of Rust source code](docs/remarks.png) # Installation ```bash $ cargo install cargo-remark ``` Note that `rustc` has [gained](https://github.com/rust-lang/rust/pull/113040) the ability to output LLVM optimization remarks in the YAML format on 2. 7. 2023, and it is currently unstable. Therefore, you will need a recent nightly version[^2] of the compiler to generate LLVM remarks. ```bash $ rustup update nightly ``` [^2]: At least `nightly-2023-07-03-...`. # Usage `rustc` can generate LLVM remarks using the (currently unstable) `-Zremark-dir` flag, which is used internally by this crate. To generate remarks from your crate, use the following command: ```bash $ cargo remark build ``` After the build finishes, the remarks will be located in `target/remarks/yaml`, and the rendered website will be located in `target/remarks/web`. You can open the website by pointing your web browser to `target/remarks/web/index.html` file, or by using the `--open` flag. This command will automatically build your crate with optimizations, so you don't have to pass the `--release` flag. Currently, only missed optimization remarks will be visualized. `Analysis` and `Passed` remarks are ignored. ### CLI parameters | **Flag** | **Default** | **Description** | |--------------|-------------------------------------------------|-------------------------------------------------------------------| | `--open` | (unset) | Open the generated website with the default browser. | | `--external` | (unset) | Visualize remarks from external crates (dependencies) and stdlib. | | `--filter` | `FastISelFailure,NeverInline,SpillReloadCopies` | Comma separated list of remark passes that should be ignored. | ### Features There is currently a single feature `mimalloc`, which is enabled by default, and which enables the use of the [mimalloc](https://docs.rs/mimalloc/latest/mimalloc/) allocator. To disable the feature, compile (or install) the crate with `--no-default-features`. ## Rendering remarks from a directory If you have a directory with YAML remarks on disk, and you just want to visualize them without invoking Cargo, you can use the `analyze-remarks` binary, which comes with this crate. ```bash $ analyze-remarks --source-dir ``` When you use this tool, you need to manually pass the root source directory from where the remarks were generated (with `cargo remark`, it is automatically inferred). You could even use this binary to render remarks generated from C/C++ programs. One advantage of that is that `analyze-remarks` will probably be much faster than [existing](https://github.com/OfekShilon/optview2) C/C++ remark tools, which are written in Python. ## Usage with PGO If you compile your crate with [Profile-guided optimization](https://doc.rust-lang.org/rustc/profile-guided-optimization.html) (PGO), the generated remarks will contain "hotness", a measure of how important is each missed optimization remark. This can help with prioritizing which remarks should be resolved first. You can combine `cargo remark` with the [`cargo-pgo`](https://github.com/Kobzol/cargo-pgo) command to generate remarks from a PGO optimized build: ```bash # Compile with PGO instrumentation $ cargo pgo build # Gather PGO profiles $ ./target/release// # Compile with PGO optimizations and generate remarks $ cargo remark wrap -- pgo optimize ``` # Related work This crate, and especially the generated website was heavily inspired by [optview2](https://github.com/OfekShilon/optview2), a tool for visualizing LLVM optimization remarks generated from C and C++ programs. # License [MIT](LICENSE)