#codegen #cargo-rustc #slice #precompilation #cargo

nightly bin+lib cargo-slicer

Speed up Rust release builds by skipping codegen for unreachable functions and processing of other skippable items

2 releases

0.0.2 Feb 14, 2026
0.0.1 Feb 8, 2026

#471 in Programming languages

MIT/Apache

5MB
47K SLoC

Rust 41K SLoC // 0.1% comments C 6K SLoC // 0.2% comments Shell 132 SLoC // 0.2% comments

cargo-slicer

Speed up Rust release builds by skipping codegen for unreachable functions.

cargo-slicer is a RUSTC_WRAPPER that performs whole-program reachability analysis across workspace crates, then replaces unreachable function bodies with abort stubs at the MIR level. This avoids the LLVM codegen cost for functions that would be discarded by the linker anyway.

Quick Start

# 1. Install cargo-slicer (no RUSTC_WRAPPER)
unset RUSTC_WRAPPER CARGO_SLICER_VIRTUAL CARGO_SLICER_CODEGEN_FILTER
rustup component add rust-src rustc-dev llvm-tools-preview
cargo install --path .
cargo +nightly install --path . --profile release-rustc \
  --bin cargo-slicer-rustc --bin cargo_slicer_dispatch \
  --features rustc-driver

# 2. (Optional) Pre-analyze for cross-crate reachability
cargo-slicer pre-analyze

# 3. Build your target project with virtual slicing
cargo clean
CARGO_SLICER_VIRTUAL=1 CARGO_SLICER_CODEGEN_FILTER=1 \
  RUSTC_WRAPPER=~/.cargo/bin/cargo_slicer_dispatch \
  cargo +nightly build --release

A self-slicing demo run on Windows Subsystem for Linux

On WSL with NTFS drives (/mnt/c/, /mnt/d/), add CARGO_SLICER_SCCACHE=/nonexistent and SCCACHE_IDLE_TIMEOUT=0 to disable sccache. See docs/USAGE.md for full details.

How It Works

Rustc already performs dead code elimination via its monomorphization collector — it builds a reachability graph from root items and only codegens what's transitively needed. But this analysis is per-crate. When compiling a library crate, rustc has no way to know which public functions the downstream binary will call, so it must codegen all of them.

cargo-slicer bridges this gap with whole-program analysis:

  1. Pre-analysis scans all workspace crate sources (via syn AST parsing) to build a unified cross-crate call graph.
  2. Cross-crate BFS from main determines which public library functions are actually reachable, replacing the default "all pub = root" assumption.
  3. MIR stubbing replaces unreachable function bodies with Unreachable terminators inside the compiler. When rustc's mono collector encounters a stub, it finds no callees — pruning entire subtrees of the monomorphization graph.

The net effect: library crates compile only the code paths actually needed by the binary, without modifying any source files.

                 rustc (per-crate)              cargo-slicer (whole-program)
                 ─────────────────              ────────────────────────────
Seeds:           ALL public functions            Only public functions called
                 in each library crate           from main (cross-crate BFS)

ripgrep libs:    623 roots                       226 roots (64% reduction)
helix libs:      1,817 roots                     315 roots (83% reduction)

Third-party dependencies (from .cargo/registry/) are routed to sccache and compiled normally — they are already cached on incremental builds, and loading the analysis driver for hundreds of deps would add more overhead than it saves. Only workspace crates go through the slicing driver.

For a detailed comparison with rustc's built-in analysis and David Lattimore's proposed lazy compilation approach, see docs/DESIGN.md.

Benchmark Results

Project Baseline vslice-cc Wall Δ Insn Δ RSS Δ
zed 1012s 719s -29% -37% -45%
rustc 135.8s 112.4s -17% -26% -7%
helix 71.2s 66.6s -6% -11% -18%
ripgrep 11.1s 10.7s -4% -5% -6%

Clean release builds with parallel frontend (-Z threads=8) and wild linker, 3 runs averaged (Feb 2026). Instruction counts from perf stat -e instructions:u.

Speedups scale with the ratio of unused library code. Zed (198 workspace crates, large unused API surfaces) benefits most — 37% fewer CPU instructions, 45% less peak memory. Projects that use most of their library APIs see smaller gains. On 20 single-crate rustc-perf benchmarks, overhead is 0-11%.

Documentation

Requirements

  • Rust nightly

License

MIT & Apache 2.0

Dependencies

~10–28MB
~404K SLoC