Skip to content

Commit 2c1883c

Browse files
committed
Refactor LTO type determination
Instead of only determining whether some form of LTO is necessary, determine whether thin, fat or no LTO is necessary. I've rewritten the conditions in a way that I think is more obvious, i.e. specified LTO type + additional preconditions.
1 parent 9c657e8 commit 2c1883c

File tree

1 file changed

+41
-35
lines changed

1 file changed

+41
-35
lines changed

src/librustc_codegen_ssa/back/write.rs

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,13 @@ fn execute_work_item<B: ExtraBackendMethods>(
696696
}
697697
}
698698

699+
// Actual LTO type we end up chosing based on multiple factors.
700+
enum ComputedLtoType {
701+
No,
702+
Thin,
703+
Fat,
704+
}
705+
699706
fn execute_optimize_work_item<B: ExtraBackendMethods>(
700707
cgcx: &CodegenContext<B>,
701708
module: ModuleCodegen<B::Module>,
@@ -708,54 +715,53 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
708715
B::optimize(cgcx, &diag_handler, &module, module_config, timeline)?;
709716
}
710717

711-
let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled();
712-
713718
// After we've done the initial round of optimizations we need to
714719
// decide whether to synchronously codegen this module or ship it
715720
// back to the coordinator thread for further LTO processing (which
716721
// has to wait for all the initial modules to be optimized).
717-
//
718-
// Here we dispatch based on the `cgcx.lto` and kind of module we're
719-
// codegenning...
720-
let needs_lto = match cgcx.lto {
721-
Lto::No => false,
722722

723-
// If the linker does LTO, we don't have to do it. Note that we
724-
// keep doing full LTO, if it is requested, as not to break the
725-
// assumption that the output will be a single module.
726-
Lto::Thin | Lto::ThinLocal if linker_does_lto => false,
723+
// If the linker does LTO, we don't have to do it. Note that we
724+
// keep doing full LTO, if it is requested, as not to break the
725+
// assumption that the output will be a single module.
726+
let linker_does_lto = cgcx.opts.debugging_opts.cross_lang_lto.enabled();
727727

728-
// Here we've got a full crate graph LTO requested. We ignore
729-
// this, however, if the crate type is only an rlib as there's
730-
// no full crate graph to process, that'll happen later.
731-
//
732-
// This use case currently comes up primarily for targets that
733-
// require LTO so the request for LTO is always unconditionally
734-
// passed down to the backend, but we don't actually want to do
735-
// anything about it yet until we've got a final product.
736-
Lto::Fat | Lto::Thin => {
737-
cgcx.crate_types.len() != 1 ||
738-
cgcx.crate_types[0] != config::CrateType::Rlib
739-
}
728+
// When we're automatically doing ThinLTO for multi-codegen-unit
729+
// builds we don't actually want to LTO the allocator modules if
730+
// it shows up. This is due to various linker shenanigans that
731+
// we'll encounter later.
732+
let is_allocator = module.kind == ModuleKind::Allocator;
740733

741-
// When we're automatically doing ThinLTO for multi-codegen-unit
742-
// builds we don't actually want to LTO the allocator modules if
743-
// it shows up. This is due to various linker shenanigans that
744-
// we'll encounter later.
745-
Lto::ThinLocal => {
746-
module.kind != ModuleKind::Allocator
747-
}
748-
};
734+
// We ignore a request for full crate grath LTO if the cate type
735+
// is only an rlib, as there is no full crate graph to process,
736+
// that'll happen later.
737+
//
738+
// This use case currently comes up primarily for targets that
739+
// require LTO so the request for LTO is always unconditionally
740+
// passed down to the backend, but we don't actually want to do
741+
// anything about it yet until we've got a final product.
742+
let is_rlib = cgcx.crate_types.len() == 1
743+
&& cgcx.crate_types[0] == config::CrateType::Rlib;
749744

750745
// Metadata modules never participate in LTO regardless of the lto
751746
// settings.
752-
let needs_lto = needs_lto && module.kind != ModuleKind::Metadata;
753-
754-
if needs_lto {
755-
Ok(WorkItemResult::NeedsLTO(module))
747+
let lto_type = if module.kind == ModuleKind::Metadata {
748+
ComputedLtoType::No
756749
} else {
750+
match cgcx.lto {
751+
Lto::ThinLocal if !linker_does_lto && !is_allocator
752+
=> ComputedLtoType::Thin,
753+
Lto::Thin if !linker_does_lto && !is_rlib
754+
=> ComputedLtoType::Thin,
755+
Lto::Fat if !is_rlib => ComputedLtoType::Fat,
756+
_ => ComputedLtoType::No,
757+
}
758+
};
759+
760+
if let ComputedLtoType::No = lto_type {
757761
let module = unsafe { B::codegen(cgcx, &diag_handler, module, module_config, timeline)? };
758762
Ok(WorkItemResult::Compiled(module))
763+
} else {
764+
Ok(WorkItemResult::NeedsLTO(module))
759765
}
760766
}
761767

0 commit comments

Comments
 (0)