diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index bbb04652119fe..4eda4c2f08c69 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -374,6 +374,10 @@ pub struct CodegenContext { pub incr_comp_session_dir: Option, /// Channel back to the main control thread to send messages to pub coordinator_send: Sender>, + /// `true` if the codegen should be run in parallel. + /// + /// Depends on [`CodegenBackend::supports_parallel()`] and `-Zno_parallel_backend`. + pub parallel: bool, } impl CodegenContext { @@ -1152,6 +1156,7 @@ fn start_executing_work( target_arch: tcx.sess.target.arch.to_string(), split_debuginfo: tcx.sess.split_debuginfo(), split_dwarf_kind: tcx.sess.opts.unstable_opts.split_dwarf_kind, + parallel: backend.supports_parallel() && !sess.opts.unstable_opts.no_parallel_backend, }; // This is the "main loop" of parallel work happening for parallel codegen. @@ -1422,7 +1427,7 @@ fn start_executing_work( .binary_search_by_key(&cost, |&(_, cost)| cost) .unwrap_or_else(|e| e); work_items.insert(insertion_index, (work, cost)); - if !cgcx.opts.unstable_opts.no_parallel_llvm { + if cgcx.parallel { helper.request_token(); } } @@ -1545,7 +1550,7 @@ fn start_executing_work( }; work_items.insert(insertion_index, (llvm_work_item, cost)); - if !cgcx.opts.unstable_opts.no_parallel_llvm { + if cgcx.parallel { helper.request_token(); } assert_eq!(main_thread_state, MainThreadState::Codegenning); diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index cb1feff13363e..e6d42c596d2af 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -111,6 +111,13 @@ pub trait CodegenBackend { codegen_results: CodegenResults, outputs: &OutputFilenames, ) -> Result<(), ErrorGuaranteed>; + + /// Returns `true` if this backend can be safely called from multiple threads. + /// + /// Defaults to `true`. + fn supports_parallel(&self) -> bool { + true + } } pub trait ExtraBackendMethods: diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 4f15d1c1d3a0b..c5376f224e363 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -685,7 +685,7 @@ fn test_unstable_options_tracking_hash() { untracked!(nll_facts, true); untracked!(no_analysis, true); untracked!(no_leak_check, true); - untracked!(no_parallel_llvm, true); + untracked!(no_parallel_backend, true); untracked!(parse_only, true); // `pre_link_arg` is omitted because it just forwards to `pre_link_args`. untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 93bef82e4ba15..ea4b8f2463e7f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1772,7 +1772,7 @@ options! { "disable the 'leak check' for subtyping; unsound, but useful for tests"), no_link: bool = (false, parse_no_flag, [TRACKED], "compile without linking"), - no_parallel_llvm: bool = (false, parse_no_flag, [UNTRACKED], + no_parallel_backend: bool = (false, parse_no_flag, [UNTRACKED], "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED], "prevent automatic injection of the profiler_builtins crate"),