@@ -696,6 +696,13 @@ fn execute_work_item<B: ExtraBackendMethods>(
696
696
}
697
697
}
698
698
699
+ // Actual LTO type we end up chosing based on multiple factors.
700
+ enum ComputedLtoType {
701
+ No ,
702
+ Thin ,
703
+ Fat ,
704
+ }
705
+
699
706
fn execute_optimize_work_item < B : ExtraBackendMethods > (
700
707
cgcx : & CodegenContext < B > ,
701
708
module : ModuleCodegen < B :: Module > ,
@@ -708,54 +715,53 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
708
715
B :: optimize ( cgcx, & diag_handler, & module, module_config, timeline) ?;
709
716
}
710
717
711
- let linker_does_lto = cgcx. opts . debugging_opts . cross_lang_lto . enabled ( ) ;
712
-
713
718
// After we've done the initial round of optimizations we need to
714
719
// decide whether to synchronously codegen this module or ship it
715
720
// back to the coordinator thread for further LTO processing (which
716
721
// 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 ,
722
722
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 ( ) ;
727
727
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 ;
740
733
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 ;
749
744
750
745
// Metadata modules never participate in LTO regardless of the lto
751
746
// 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
756
749
} 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 {
757
761
let module = unsafe { B :: codegen ( cgcx, & diag_handler, module, module_config, timeline) ? } ;
758
762
Ok ( WorkItemResult :: Compiled ( module) )
763
+ } else {
764
+ Ok ( WorkItemResult :: NeedsLTO ( module) )
759
765
}
760
766
}
761
767
0 commit comments