Skip to content

Commit 53867f2

Browse files
committed
Separate thin LTO message and work item types
1 parent 3cf3ec6 commit 53867f2

File tree

1 file changed

+80
-29
lines changed
  • compiler/rustc_codegen_ssa/src/back

1 file changed

+80
-29
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 80 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ fn generate_thin_lto_work<B: ExtraBackendMethods>(
380380
each_linked_rlib_for_lto: &[PathBuf],
381381
needs_thin_lto: Vec<(String, B::ThinBuffer)>,
382382
import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>,
383-
) -> Vec<(WorkItem<B>, u64)> {
383+
) -> Vec<(ThinLtoWorkItem<B>, u64)> {
384384
let _prof_timer = cgcx.prof.generic_activity("codegen_thin_generate_lto_work");
385385

386386
let (lto_modules, copy_jobs) = B::run_thin_lto(
@@ -394,11 +394,11 @@ fn generate_thin_lto_work<B: ExtraBackendMethods>(
394394
.into_iter()
395395
.map(|module| {
396396
let cost = module.cost();
397-
(WorkItem::ThinLto(module), cost)
397+
(ThinLtoWorkItem::ThinLto(module), cost)
398398
})
399399
.chain(copy_jobs.into_iter().map(|wp| {
400400
(
401-
WorkItem::CopyPostLtoArtifacts(CachedModuleCodegen {
401+
ThinLtoWorkItem::CopyPostLtoArtifacts(CachedModuleCodegen {
402402
name: wp.cgu_name.clone(),
403403
source: wp,
404404
}),
@@ -703,6 +703,12 @@ pub(crate) enum WorkItem<B: WriteBackendMethods> {
703703
/// Copy the post-LTO artifacts from the incremental cache to the output
704704
/// directory.
705705
CopyPostLtoArtifacts(CachedModuleCodegen),
706+
}
707+
708+
enum ThinLtoWorkItem<B: WriteBackendMethods> {
709+
/// Copy the post-LTO artifacts from the incremental cache to the output
710+
/// directory.
711+
CopyPostLtoArtifacts(CachedModuleCodegen),
706712
/// Performs thin-LTO on the given module.
707713
ThinLto(lto::ThinModule<B>),
708714
}
@@ -752,7 +758,18 @@ impl<B: WriteBackendMethods> WorkItem<B> {
752758
match self {
753759
WorkItem::Optimize(m) => desc("opt", "optimize module", &m.name),
754760
WorkItem::CopyPostLtoArtifacts(m) => desc("cpy", "copy LTO artifacts for", &m.name),
755-
WorkItem::ThinLto(m) => desc("lto", "thin-LTO module", m.name()),
761+
}
762+
}
763+
}
764+
765+
impl<B: WriteBackendMethods> ThinLtoWorkItem<B> {
766+
/// Generate a short description of this work item suitable for use as a thread name.
767+
fn short_description(&self) -> String {
768+
match self {
769+
ThinLtoWorkItem::CopyPostLtoArtifacts(m) => {
770+
desc("cpy", "copy LTO artifacts for", &m.name)
771+
}
772+
ThinLtoWorkItem::ThinLto(m) => desc("lto", "thin-LTO module", m.name()),
756773
}
757774
}
758775
}
@@ -883,7 +900,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
883900
fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
884901
cgcx: &CodegenContext<B>,
885902
module: CachedModuleCodegen,
886-
) -> WorkItemResult<B> {
903+
) -> CompiledModule {
887904
let _timer = cgcx
888905
.prof
889906
.generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &*module.name);
@@ -956,7 +973,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
956973
cgcx.create_dcx().handle().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name })
957974
}
958975

959-
WorkItemResult::Finished(CompiledModule {
976+
CompiledModule {
960977
links_from_incr_cache,
961978
kind: ModuleKind::Regular,
962979
name: module.name,
@@ -965,7 +982,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
965982
bytecode,
966983
assembly,
967984
llvm_ir,
968-
})
985+
}
969986
}
970987

971988
fn do_fat_lto<B: ExtraBackendMethods>(
@@ -1015,7 +1032,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
10151032
let coordinator_send2 = coordinator_send.clone();
10161033
let helper = jobserver::client()
10171034
.into_helper_thread(move |token| {
1018-
drop(coordinator_send2.send(Message::Token::<B>(token)));
1035+
drop(coordinator_send2.send(ThinLtoMessage::Token(token)));
10191036
})
10201037
.expect("failed to spawn helper thread");
10211038

@@ -1069,7 +1086,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
10691086
while used_token_count < tokens.len() + 1
10701087
&& let Some((item, _)) = work_items.pop()
10711088
{
1072-
spawn_work(&cgcx, coordinator_send.clone(), llvm_start_time, item);
1089+
spawn_thin_lto_work(&cgcx, coordinator_send.clone(), llvm_start_time, item);
10731090
used_token_count += 1;
10741091
}
10751092
} else {
@@ -1087,7 +1104,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
10871104
// Save the token locally and the next turn of the loop will use
10881105
// this to spawn a new unit of work, or it may get dropped
10891106
// immediately if we have no more work to spawn.
1090-
Message::Token(token) => match token {
1107+
ThinLtoMessage::Token(token) => match token {
10911108
Ok(token) => {
10921109
tokens.push(token);
10931110
}
@@ -1098,14 +1115,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
10981115
}
10991116
},
11001117

1101-
Message::CodegenDone { .. }
1102-
| Message::CodegenComplete
1103-
| Message::CodegenAborted
1104-
| Message::AddImportOnlyModule { .. } => {
1105-
unreachable!()
1106-
}
1107-
1108-
Message::WorkItem { result } => {
1118+
ThinLtoMessage::WorkItem { result } => {
11091119
// If a thread exits successfully then we drop a token associated
11101120
// with that worker and update our `used_token_count` count.
11111121
// We may later re-acquire a token to continue running more work.
@@ -1114,12 +1124,7 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
11141124
used_token_count -= 1;
11151125

11161126
match result {
1117-
Ok(WorkItemResult::Finished(compiled_module)) => {
1118-
compiled_modules.push(compiled_module);
1119-
}
1120-
Ok(WorkItemResult::NeedsFatLto(_)) | Ok(WorkItemResult::NeedsThinLto(_, _)) => {
1121-
unreachable!()
1122-
}
1127+
Ok(compiled_module) => compiled_modules.push(compiled_module),
11231128
Err(Some(WorkerFatalError)) => {
11241129
// Like `CodegenAborted`, wait for remaining work to finish.
11251130
codegen_aborted = Some(FatalError);
@@ -1144,12 +1149,11 @@ fn do_thin_lto<'a, B: ExtraBackendMethods>(
11441149
fn execute_thin_lto_work_item<B: ExtraBackendMethods>(
11451150
cgcx: &CodegenContext<B>,
11461151
module: lto::ThinModule<B>,
1147-
) -> WorkItemResult<B> {
1152+
) -> CompiledModule {
11481153
let _timer = cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", module.name());
11491154

11501155
let module = B::optimize_thin(cgcx, module);
1151-
let module = B::codegen(cgcx, module, &cgcx.module_config);
1152-
WorkItemResult::Finished(module)
1156+
B::codegen(cgcx, module, &cgcx.module_config)
11531157
}
11541158

11551159
/// Messages sent to the coordinator.
@@ -1183,6 +1187,17 @@ pub(crate) enum Message<B: WriteBackendMethods> {
11831187
CodegenAborted,
11841188
}
11851189

1190+
/// Messages sent to the coordinator.
1191+
pub(crate) enum ThinLtoMessage {
1192+
/// A jobserver token has become available. Sent from the jobserver helper
1193+
/// thread.
1194+
Token(io::Result<Acquired>),
1195+
1196+
/// The backend has finished processing a work item for a codegen unit.
1197+
/// Sent from a backend worker thread.
1198+
WorkItem { result: Result<CompiledModule, Option<WorkerFatalError>> },
1199+
}
1200+
11861201
/// A message sent from the coordinator thread to the main thread telling it to
11871202
/// process another codegen unit.
11881203
pub struct CguMessage;
@@ -1839,8 +1854,9 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
18391854
B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || {
18401855
let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work {
18411856
WorkItem::Optimize(m) => execute_optimize_work_item(&cgcx, m),
1842-
WorkItem::CopyPostLtoArtifacts(m) => execute_copy_from_cache_work_item(&cgcx, m),
1843-
WorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, m),
1857+
WorkItem::CopyPostLtoArtifacts(m) => {
1858+
WorkItemResult::Finished(execute_copy_from_cache_work_item(&cgcx, m))
1859+
}
18441860
}));
18451861

18461862
let msg = match result {
@@ -1860,6 +1876,41 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
18601876
.expect("failed to spawn work thread");
18611877
}
18621878

1879+
fn spawn_thin_lto_work<'a, B: ExtraBackendMethods>(
1880+
cgcx: &'a CodegenContext<B>,
1881+
coordinator_send: Sender<ThinLtoMessage>,
1882+
llvm_start_time: &mut Option<VerboseTimingGuard<'a>>,
1883+
work: ThinLtoWorkItem<B>,
1884+
) {
1885+
if llvm_start_time.is_none() {
1886+
*llvm_start_time = Some(cgcx.prof.verbose_generic_activity("LLVM_passes"));
1887+
}
1888+
1889+
let cgcx = cgcx.clone();
1890+
1891+
B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || {
1892+
let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work {
1893+
ThinLtoWorkItem::CopyPostLtoArtifacts(m) => execute_copy_from_cache_work_item(&cgcx, m),
1894+
ThinLtoWorkItem::ThinLto(m) => execute_thin_lto_work_item(&cgcx, m),
1895+
}));
1896+
1897+
let msg = match result {
1898+
Ok(result) => ThinLtoMessage::WorkItem { result: Ok(result) },
1899+
1900+
// We ignore any `FatalError` coming out of `execute_work_item`, as a
1901+
// diagnostic was already sent off to the main thread - just surface
1902+
// that there was an error in this worker.
1903+
Err(err) if err.is::<FatalErrorMarker>() => {
1904+
ThinLtoMessage::WorkItem { result: Err(Some(WorkerFatalError)) }
1905+
}
1906+
1907+
Err(_) => ThinLtoMessage::WorkItem { result: Err(None) },
1908+
};
1909+
drop(coordinator_send.send(msg));
1910+
})
1911+
.expect("failed to spawn work thread");
1912+
}
1913+
18631914
enum SharedEmitterMessage {
18641915
Diagnostic(Diagnostic),
18651916
InlineAsmError(SpanData, String, Level, Option<(String, Vec<InnerSpan>)>),

0 commit comments

Comments
 (0)