@@ -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+
699706fn 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