How much of Rust's compile time is LLVM?

I'm wondering how Rust's compile times compare to C++'s when both go through LLVM as I know Rust used to have issues there.

Is the bottleneck during compilation Rust or LLVM?

2 Likes

I don't know how to set this up but LLVM has boolean flags you can set to measure timings of the pass manager.

https://doc.rust-lang.org/stable/nightly-rustc/rustc_session/options/dbsetters/fn.time_llvm_passes.html

2 Likes

Obviously the exact percentage depends on the program being compiled, but even in debug mode quite a bit of time is spend in LLVM (and linking). The rustc_codegen_cranelift project is an alternate backend that significantly reduces this time, albeit with a runtime performance impact.

How much of Rust’s compile time is LLVM?

The general answer to this question is: what is the delta between cargo build and cargo check for your project? cargo check runs basically all of the compiler except for the backend (LLVM) while cargo build runs everything including the backend.

2 Likes

You can pass the -Z time argument to rustc if you want detailed timing information about a particular build.

For example, this is what I get when I do an incremental build for hotg-ai/rune:

$ cd hotg-ai/rune
$ cargo rustc -- -Z time
time:   0.000; rss:   54MB ->   56MB (   +2MB)	parse_crate
time:   0.000; rss:   56MB ->   56MB (   +0MB)	attributes_injection
time:   0.000; rss:   56MB ->   56MB (   +0MB)	recursion_limit
time:   0.000; rss:   56MB ->   56MB (   +0MB)	plugin_loading
time:   0.000; rss:   56MB ->   56MB (   +0MB)	plugin_registration
time:   0.000; rss:   59MB ->   59MB (   +0MB)	crate_injection
time:   0.129; rss:   59MB ->  169MB ( +110MB)	expand_crate
time:   0.000; rss:  169MB ->  169MB (   +0MB)	check_unused_macros
time:   0.129; rss:   59MB ->  169MB ( +110MB)	macro_expand_crate
time:   0.000; rss:  169MB ->  169MB (   +0MB)	maybe_building_test_harness
time:   0.001; rss:  169MB ->  169MB (   +0MB)	AST_validation
time:   0.000; rss:  169MB ->  169MB (   +0MB)	maybe_create_a_macro_crate
time:   0.000; rss:  169MB ->  169MB (   +0MB)	finalize_imports
time:   0.000; rss:  169MB ->  170MB (   +1MB)	finalize_macro_resolutions
time:   0.005; rss:  170MB ->  176MB (   +6MB)	late_resolve_crate
time:   0.000; rss:  176MB ->  176MB (   +0MB)	resolve_main
time:   0.000; rss:  176MB ->  176MB (   +0MB)	resolve_check_unused
time:   0.000; rss:  176MB ->  176MB (   +0MB)	resolve_report_errors
time:   0.000; rss:  176MB ->  176MB (   +0MB)	resolve_postprocess
time:   0.006; rss:  169MB ->  176MB (   +7MB)	resolve_crate
time:   0.000; rss:  176MB ->  176MB (   +0MB)	complete_gated_feature_checking
time:   0.136; rss:   56MB ->  176MB ( +120MB)	configure_and_expand
time:   0.000; rss:  176MB ->  176MB (   +0MB)	prepare_outputs
time:   0.004; rss:  176MB ->  179MB (   +4MB)	hir_lowering
time:   0.001; rss:  179MB ->  180MB (   +0MB)	early_lint_checks
time:   0.000; rss:  180MB ->  180MB (   +0MB)	setup_global_ctxt
time:   0.000; rss:  180MB ->  180MB (   +0MB)	create_global_ctxt
time:   0.000; rss:  184MB ->  184MB (   +0MB)	looking_for_entry_point
time:   0.000; rss:  184MB ->  184MB (   +0MB)	looking_for_plugin_registrar
time:   0.000; rss:  184MB ->  184MB (   +0MB)	looking_for_derive_registrar
time:   0.004; rss:  184MB ->  187MB (   +3MB)	misc_checking_1
time:   0.004; rss:  187MB ->  189MB (   +2MB)	type_collecting
time:   0.000; rss:  189MB ->  189MB (   +0MB)	impl_wf_inference
time:   0.000; rss:  288MB ->  288MB (   +0MB)	unsafety_checking
time:   0.000; rss:  288MB ->  288MB (   +0MB)	orphan_checking
time:   0.048; rss:  189MB ->  288MB (  +99MB)	coherence_checking
time:   0.009; rss:  288MB ->  291MB (   +3MB)	wf_checking
time:   0.005; rss:  291MB ->  294MB (   +2MB)	item_types_checking
time:   0.105; rss:  294MB ->  307MB (  +13MB)	item_bodies_checking
time:   0.171; rss:  187MB ->  307MB ( +120MB)	type_check_crate
time:   0.011; rss:  307MB ->  312MB (   +6MB)	match_checking
time:   0.002; rss:  312MB ->  312MB (   +0MB)	liveness_and_intrinsic_checking
time:   0.013; rss:  307MB ->  312MB (   +6MB)	misc_checking_2
time:   0.093; rss:  312MB ->  321MB (   +8MB)	MIR_borrow_checking
time:   0.000; rss:  321MB ->  321MB (   +0MB)	MIR_effect_checking
time:   0.000; rss:  321MB ->  321MB (   +0MB)	layout_testing
time:   0.001; rss:  321MB ->  321MB (   +0MB)	death_checking
time:   0.000; rss:  321MB ->  321MB (   +0MB)	unused_lib_feature_checking
time:   0.004; rss:  321MB ->  321MB (   +0MB)	crate_lints
time:   0.002; rss:  321MB ->  321MB (   +0MB)	module_lints
time:   0.007; rss:  321MB ->  321MB (   +0MB)	lint_checking
time:   0.003; rss:  321MB ->  321MB (   +0MB)	privacy_checking_modules
time:   0.013; rss:  321MB ->  321MB (   +0MB)	misc_checking_3
time:   0.000; rss:  322MB ->  322MB (   +0MB)	monomorphization_collector_root_collections
time:   0.222; rss:  322MB ->  374MB (  +52MB)	monomorphization_collector_graph_walk
time:   0.032; rss:  374MB ->  379MB (   +5MB)	partition_and_assert_distinct_symbols
time:   0.000; rss:  380MB ->  380MB (   +0MB)	write_allocator_module
time:   0.000; rss:  380MB ->  380MB (   +0MB)	find_cgu_reuse
time:   0.965; rss:  380MB ->  435MB (  +56MB)	codegen_to_LLVM_IR
time:   1.223; rss:  321MB ->  435MB ( +114MB)	codegen_crate
time:   0.000; rss:  435MB ->  435MB (   +0MB)	serialize_dep_graph
time:   0.013; rss:  435MB ->  279MB ( -156MB)	free_global_ctxt
time:   0.000; rss:  281MB ->  281MB (   +0MB)	join_worker_thread
time:   0.172; rss:  279MB ->  281MB (   +2MB)	finish_ongoing_codegen
time:   0.000; rss:  280MB ->  280MB (   +0MB)	llvm_dump_timing_file
time:   0.000; rss:  280MB ->  280MB (   +0MB)	serialize_work_products
time:   0.000; rss:  280MB ->  278MB (   -2MB)	link_binary_check_files_are_writeable
time:   0.759; rss:  276MB ->  270MB (   -6MB)	run_linker
time:   0.002; rss:  270MB ->  270MB (   +0MB)	link_binary_remove_temps
time:   0.762; rss:  280MB ->  270MB (  -10MB)	link_binary
time:   0.762; rss:  280MB ->  268MB (  -12MB)	link_crate
time:   0.935; rss:  279MB ->  268MB (  -11MB)	link
time:   2.625; rss:   45MB ->  135MB (  +90MB)	total

There's a lot to unpack here and I wasn't building from scratch so a lot of work would have been cached, but here are some lines I'd like to point out:

  • expand_crate took 0.129 seconds
  • type_check_crate tool 0.171 seconds
  • MIR_borrow_checking took 0.093 seconds
  • monomorphization_collector_graph_walk tool 0.222 seconds - expanding generics takes longer than typechecking the entire crate :disappointed:
  • codegen_to_LLVM_IR took 0.965 seconds
  • codegen_crate (LLVM) took 1.223 seconds
  • link took 0.935 seconds
10 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.