pacak / cargo-show-asm

cargo subcommand showing the assembly, LLVM-IR and MIR generated for Rust code
Apache License 2.0
712 stars 34 forks source link
assembly cargo cargo-plugin cargo-subcommand llvm-ir optimization rust

cargo-show-asm

A cargo subcommand that displays the Assembly, LLVM-IR, MIR and WASM generated for Rust source code.

Install

$ cargo install cargo-show-asm

Features

cargo asm

Show the code rustc generates for any function

Usage: cargo asm [-p=SPEC] [ARTIFACT] [-M=ARG]... [TARGET-CPU] [--rust] [-c=COUNT] [--simplify] [--include-constants] [--this-workspace | --all-crates | --all-sources] OUTPUT-FORMAT [--everything | FUNCTION [INDEX]]

Usage:

  1. Focus on a single assembly producing target:

    % cargo asm -p isin --lib   # here we are targeting lib in isin crate
    
  2. Narrow down a function:

    % cargo asm -p isin --lib from_ # here "from_" is part of the function you are interested intel
    
  3. Get the full results:

    % cargo asm -p isin --lib isin::base36::from_alphanum

Pick artifact for analysis:

Cargo options

Postprocessing options:

Pick output type:

Pick item to display from the artifact

Available options:

You can start by running cargo asm with no parameters - it will suggest how to narrow the search scope - for workspace crates you need to specify a crate to work with, for crates defining several targets (lib, binaries, examples) you need to specify exactly which target to use. In a workspace cargo asm lists only workspace members as suggestions but any crate from workspace tree is available.

Once cargo asm focuses on a single target it will run rustc producing assembly file and will try to list of available public functions:

$ cargo asm --lib
Try one of those
"<&T as core::fmt::Display>::fmt" [17, 12, 12, 12, 12, 19, 19, 12]
"<&mut W as core::fmt::Write>::write_char" [20]
"<&mut W as core::fmt::Write>::write_fmt" [38]
"<&mut W as core::fmt::Write>::write_str" [90]
"<F as nom::internal::Parser<I,O,E>>::parse" [263]
# ...

Name in quotes is demangled rust name, numbers in square brackets represent number of lines in asm file. Function with the same name can be present in several instances.

Specifying exact function name or a uniquely identifying part of it will print its assembly code

$ cargo asm --lib "cargo_show_asm::opts::focus::{{closure}}"

To pick between different alternatives you can either specify the index

$ cargo asm --lib "cargo_show_asm::opts::focus::{{closure}}" 2

Or start using full names with hex included:

$ cargo asm --lib --full-name
# ...
$ cargo asm --lib "once_cell::imp::OnceCell<T>::initialize::h9c5c7d5bd745000b"

cargo-show-asm comes with a built-in search function. Just pass partial name instead of a full one and only matching functions will be listed

$ cargo asm --lib Debug

My function isn't there!

rustc will only generate the code for your function if it knows what type it is, including generic parameters and if it is exported (in case of a library) and not inlined (in case of a binary, example, test, etc.). If your function takes a generic parameter - try making a monomorphic wrapper around it and make it pub and #[inline(never)].

Alternatively if your function is too small - rustc might decide to inline it automatically with the same result. Marking it with #[inline(never)] fixes this problem. See https://github.com/rust-lang/rust/pull/116505 for more details

Include related functions?

So suppose you have a function foo that calls some other function - bar. With --context N or it's short variant -c N you can ask cargo-show-asm to include body of bar to the input. This is done recursively up to N steps. See https://github.com/pacak/cargo-show-asm/issues/247

What about cargo-asm?

cargo-asm is not maintained: https://github.com/gnzlbg/cargo-asm/issues/244. This crate is a reimplementation which addresses a number of its shortcomings, including:

Shell completion

cargo-asm comes with shell completion generated by bpaf, use one of the lines below and place it into the place right for your shell.

$ cargo-asm --bpaf-complete-style-bash
$ cargo-asm --bpaf-complete-style-zsh
$ cargo-asm --bpaf-complete-style-fish
$ cargo-asm --bpaf-complete-style-elvish

You'll need to use it as cargo-asm command rather than cargo asm to take advantage of it.

Colorful line parser output

You can install cargo-show-asm with one of two features to get prettier command line

cargo install cargo-show-asm -F bright-color
cargo install cargo-show-asm -F dull-color

License

This project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.