Skip to content

Commit 21d05f6

Browse files
incr.ThinLTO: Do some cleanup and add some logging.
1 parent d554575 commit 21d05f6

File tree

2 files changed

+57
-62
lines changed

2 files changed

+57
-62
lines changed

src/librustc_codegen_llvm/back/lto.rs

+33-21
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use {ModuleCodegen, ModuleLlvm, ModuleKind};
2929
use libc;
3030

3131
use std::ffi::{CStr, CString};
32-
use std::fs::File;
32+
use std::fs::{self, File};
3333
use std::ptr;
3434
use std::slice;
3535
use std::sync::Arc;
@@ -423,16 +423,10 @@ fn thin_lto(cgcx: &CodegenContext,
423423
// because only then it will contain the ThinLTO module summary.
424424
if let Some(ref incr_comp_session_dir) = cgcx.incr_comp_session_dir {
425425
if cgcx.config(module.kind).emit_pre_thin_lto_bc {
426-
use std::io::Write;
427-
428426
let path = incr_comp_session_dir
429427
.join(pre_lto_bitcode_filename(&module.name));
430-
let mut file = File::create(&path).unwrap_or_else(|e| {
431-
panic!("Failed to create pre-lto-bitcode file `{}`: {}",
432-
path.display(),
433-
e);
434-
});
435-
file.write_all(buffer.data()).unwrap_or_else(|e| {
428+
429+
fs::write(&path, buffer.data()).unwrap_or_else(|e| {
436430
panic!("Error writing pre-lto-bitcode file `{}`: {}",
437431
path.display(),
438432
e);
@@ -499,12 +493,22 @@ fn thin_lto(cgcx: &CodegenContext,
499493
write::llvm_err(&diag_handler, "failed to prepare thin LTO context".to_string())
500494
})?;
501495

502-
let import_map = ThinLTOImports::from_thin_lto_data(data);
503-
504-
let data = ThinData(data);
505496
info!("thin LTO data created");
506497
timeline.record("data");
507498

499+
let import_map = if cgcx.incr_comp_session_dir.is_some() {
500+
ThinLTOImports::from_thin_lto_data(data)
501+
} else {
502+
// If we don't compile incrementally, we don't need to load the
503+
// import data from LLVM.
504+
assert!(green_modules.is_empty());
505+
ThinLTOImports::new()
506+
};
507+
info!("thin LTO import map loaded");
508+
timeline.record("import-map-loaded");
509+
510+
let data = ThinData(data);
511+
508512
// Throw our data in an `Arc` as we'll be sharing it across threads. We
509513
// also put all memory referenced by the C++ data (buffers, ids, etc)
510514
// into the arc as well. After this we'll create a thin module
@@ -519,25 +523,27 @@ fn thin_lto(cgcx: &CodegenContext,
519523
let mut copy_jobs = vec![];
520524
let mut opt_jobs = vec![];
521525

526+
info!("checking which modules can be-reused and which have to be re-optimized.");
522527
for (module_index, module_name) in shared.module_names.iter().enumerate() {
523528
let module_name = module_name_to_str(module_name);
524529

530+
// If the module hasn't changed and none of the modules it imports
531+
// from has changed, we can re-use the post-ThinLTO version of the
532+
// module.
525533
if green_modules.contains_key(module_name) {
526-
let mut imports_all_green = true;
527-
for imported_module in import_map.modules_imported_by(module_name) {
528-
if !green_modules.contains_key(imported_module) {
529-
imports_all_green = false;
530-
break
531-
}
532-
}
534+
let imports_all_green = import_map.modules_imported_by(module_name)
535+
.iter()
536+
.all(|imported_module| green_modules.contains_key(imported_module));
533537

534538
if imports_all_green {
535539
let work_product = green_modules[module_name].clone();
536540
copy_jobs.push(work_product);
541+
info!(" - {}: re-used", module_name);
537542
continue
538543
}
539544
}
540545

546+
info!(" - {}: re-compiled", module_name);
541547
opt_jobs.push(LtoModuleCodegen::Thin(ThinModule {
542548
shared: shared.clone(),
543549
idx: module_index,
@@ -872,7 +878,13 @@ pub struct ThinLTOImports {
872878
}
873879

874880
impl ThinLTOImports {
875-
pub fn modules_imported_by(&self, llvm_module_name: &str) -> &[String] {
881+
fn new() -> ThinLTOImports {
882+
ThinLTOImports {
883+
imports: FxHashMap(),
884+
}
885+
}
886+
887+
fn modules_imported_by(&self, llvm_module_name: &str) -> &[String] {
876888
self.imports.get(llvm_module_name).map(|v| &v[..]).unwrap_or(&[])
877889
}
878890

@@ -915,4 +927,4 @@ fn module_name_to_str(c_str: &CStr) -> &str {
915927
e)
916928
}
917929
}
918-
}
930+
}

src/librustc_codegen_llvm/back/write.rs

+24-41
Original file line numberDiff line numberDiff line change
@@ -1311,36 +1311,31 @@ fn execute_work_item(cgcx: &CodegenContext,
13111311
timeline: &mut Timeline)
13121312
-> Result<WorkItemResult, FatalError>
13131313
{
1314+
let module_config = cgcx.config(work_item.module_kind());
1315+
13141316
match work_item {
1315-
work_item @ WorkItem::Optimize(_) => {
1316-
execute_optimize_work_item(cgcx, work_item, timeline)
1317+
WorkItem::Optimize(module) => {
1318+
execute_optimize_work_item(cgcx, module, module_config, timeline)
13171319
}
1318-
work_item @ WorkItem::CopyPostLtoArtifacts(_) => {
1319-
execute_copy_from_cache_work_item(cgcx, work_item, timeline)
1320+
WorkItem::CopyPostLtoArtifacts(module) => {
1321+
execute_copy_from_cache_work_item(cgcx, module, module_config, timeline)
13201322
}
1321-
work_item @ WorkItem::LTO(_) => {
1322-
execute_lto_work_item(cgcx, work_item, timeline)
1323+
WorkItem::LTO(module) => {
1324+
execute_lto_work_item(cgcx, module, module_config, timeline)
13231325
}
13241326
}
13251327
}
13261328

13271329
fn execute_optimize_work_item(cgcx: &CodegenContext,
1328-
work_item: WorkItem,
1330+
module: ModuleCodegen,
1331+
module_config: &ModuleConfig,
13291332
timeline: &mut Timeline)
13301333
-> Result<WorkItemResult, FatalError>
13311334
{
1332-
let config = cgcx.config(work_item.module_kind());
1333-
1334-
let module = if let WorkItem::Optimize(module) = work_item {
1335-
module
1336-
} else {
1337-
bug!("execute_optimize_work_item() called with non-WorkItem::Optimize");
1338-
};
1339-
13401335
let diag_handler = cgcx.create_diag_handler();
13411336

13421337
unsafe {
1343-
optimize(cgcx, &diag_handler, &module, config, timeline)?;
1338+
optimize(cgcx, &diag_handler, &module, module_config, timeline)?;
13441339
}
13451340

13461341
let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled();
@@ -1394,25 +1389,18 @@ fn execute_optimize_work_item(cgcx: &CodegenContext,
13941389
Ok(WorkItemResult::NeedsLTO(module))
13951390
} else {
13961391
let module = unsafe {
1397-
codegen(cgcx, &diag_handler, module, config, timeline)?
1392+
codegen(cgcx, &diag_handler, module, module_config, timeline)?
13981393
};
13991394
Ok(WorkItemResult::Compiled(module))
14001395
}
14011396
}
14021397

14031398
fn execute_copy_from_cache_work_item(cgcx: &CodegenContext,
1404-
work_item: WorkItem,
1399+
module: CachedModuleCodegen,
1400+
module_config: &ModuleConfig,
14051401
_: &mut Timeline)
14061402
-> Result<WorkItemResult, FatalError>
14071403
{
1408-
let config = cgcx.config(work_item.module_kind());
1409-
1410-
let module = if let WorkItem::CopyPostLtoArtifacts(module) = work_item {
1411-
module
1412-
} else {
1413-
bug!("execute_copy_from_cache_work_item() called with wrong WorkItem kind.")
1414-
};
1415-
14161404
let incr_comp_session_dir = cgcx.incr_comp_session_dir
14171405
.as_ref()
14181406
.unwrap();
@@ -1459,9 +1447,9 @@ fn execute_copy_from_cache_work_item(cgcx: &CodegenContext,
14591447
}
14601448
}
14611449

1462-
assert_eq!(object.is_some(), config.emit_obj);
1463-
assert_eq!(bytecode.is_some(), config.emit_bc);
1464-
assert_eq!(bytecode_compressed.is_some(), config.emit_bc_compressed);
1450+
assert_eq!(object.is_some(), module_config.emit_obj);
1451+
assert_eq!(bytecode.is_some(), module_config.emit_bc);
1452+
assert_eq!(bytecode_compressed.is_some(), module_config.emit_bc_compressed);
14651453

14661454
Ok(WorkItemResult::Compiled(CompiledModule {
14671455
name: module.name,
@@ -1473,22 +1461,17 @@ fn execute_copy_from_cache_work_item(cgcx: &CodegenContext,
14731461
}
14741462

14751463
fn execute_lto_work_item(cgcx: &CodegenContext,
1476-
work_item: WorkItem,
1464+
mut module: lto::LtoModuleCodegen,
1465+
module_config: &ModuleConfig,
14771466
timeline: &mut Timeline)
14781467
-> Result<WorkItemResult, FatalError>
14791468
{
1480-
let config = cgcx.config(work_item.module_kind());
1481-
1482-
if let WorkItem::LTO(mut lto) = work_item {
1483-
let diag_handler = cgcx.create_diag_handler();
1469+
let diag_handler = cgcx.create_diag_handler();
14841470

1485-
unsafe {
1486-
let module = lto.optimize(cgcx, timeline)?;
1487-
let module = codegen(cgcx, &diag_handler, module, config, timeline)?;
1488-
Ok(WorkItemResult::Compiled(module))
1489-
}
1490-
} else {
1491-
bug!("execute_lto_work_item() called with wrong WorkItem kind.")
1471+
unsafe {
1472+
let module = module.optimize(cgcx, timeline)?;
1473+
let module = codegen(cgcx, &diag_handler, module, module_config, timeline)?;
1474+
Ok(WorkItemResult::Compiled(module))
14921475
}
14931476
}
14941477

0 commit comments

Comments
 (0)