@@ -334,6 +334,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
334334 pub output_filenames : Arc < OutputFilenames > ,
335335 pub invocation_temp : Option < String > ,
336336 pub module_config : Arc < ModuleConfig > ,
337+ pub allocator_config : Arc < ModuleConfig > ,
337338 pub tm_factory : TargetMachineFactoryFn < B > ,
338339 pub msvc_imps_needed : bool ,
339340 pub is_pe_coff : bool ,
@@ -489,7 +490,7 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
489490
490491 let _timer = sess. timer ( "copy_all_cgu_workproducts_to_incr_comp_cache_dir" ) ;
491492
492- for module in & compiled_modules. modules {
493+ for module in compiled_modules. modules . iter ( ) . filter ( |m| m . kind == ModuleKind :: Regular ) {
493494 let mut files = Vec :: new ( ) ;
494495 if let Some ( object_file_path) = & module. object {
495496 files. push ( ( OutputType :: Object . extension ( ) , object_file_path. as_path ( ) ) ) ;
@@ -794,12 +795,19 @@ pub(crate) fn compute_per_cgu_lto_type(
794795 sess_lto : & Lto ,
795796 opts : & config:: Options ,
796797 sess_crate_types : & [ CrateType ] ,
798+ module_kind : ModuleKind ,
797799) -> ComputedLtoType {
798800 // If the linker does LTO, we don't have to do it. Note that we
799801 // keep doing full LTO, if it is requested, as not to break the
800802 // assumption that the output will be a single module.
801803 let linker_does_lto = opts. cg . linker_plugin_lto . enabled ( ) ;
802804
805+ // When we're automatically doing ThinLTO for multi-codegen-unit
806+ // builds we don't actually want to LTO the allocator module if
807+ // it shows up. This is due to various linker shenanigans that
808+ // we'll encounter later.
809+ let is_allocator = module_kind == ModuleKind :: Allocator ;
810+
803811 // We ignore a request for full crate graph LTO if the crate type
804812 // is only an rlib, as there is no full crate graph to process,
805813 // that'll happen later.
@@ -811,7 +819,7 @@ pub(crate) fn compute_per_cgu_lto_type(
811819 let is_rlib = matches ! ( sess_crate_types, [ CrateType :: Rlib ] ) ;
812820
813821 match sess_lto {
814- Lto :: ThinLocal if !linker_does_lto => ComputedLtoType :: Thin ,
822+ Lto :: ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType :: Thin ,
815823 Lto :: Thin if !linker_does_lto && !is_rlib => ComputedLtoType :: Thin ,
816824 Lto :: Fat if !is_rlib => ComputedLtoType :: Fat ,
817825 _ => ComputedLtoType :: No ,
@@ -825,18 +833,23 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
825833 let dcx = cgcx. create_dcx ( ) ;
826834 let dcx = dcx. handle ( ) ;
827835
828- B :: optimize ( cgcx, dcx, & mut module, & cgcx. module_config ) ;
836+ let module_config = match module. kind {
837+ ModuleKind :: Regular => & cgcx. module_config ,
838+ ModuleKind :: Allocator => & cgcx. allocator_config ,
839+ } ;
840+
841+ B :: optimize ( cgcx, dcx, & mut module, module_config) ;
829842
830843 // After we've done the initial round of optimizations we need to
831844 // decide whether to synchronously codegen this module or ship it
832845 // back to the coordinator thread for further LTO processing (which
833846 // has to wait for all the initial modules to be optimized).
834847
835- let lto_type = compute_per_cgu_lto_type ( & cgcx. lto , & cgcx. opts , & cgcx. crate_types ) ;
848+ let lto_type = compute_per_cgu_lto_type ( & cgcx. lto , & cgcx. opts , & cgcx. crate_types , module . kind ) ;
836849
837850 // If we're doing some form of incremental LTO then we need to be sure to
838851 // save our module to disk first.
839- let bitcode = if cgcx . module_config . emit_pre_lto_bc {
852+ let bitcode = if module_config. emit_pre_lto_bc {
840853 let filename = pre_lto_bitcode_filename ( & module. name ) ;
841854 cgcx. incr_comp_session_dir . as_ref ( ) . map ( |path| path. join ( & filename) )
842855 } else {
@@ -845,7 +858,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
845858
846859 match lto_type {
847860 ComputedLtoType :: No => {
848- let module = B :: codegen ( cgcx, module, & cgcx . module_config ) ;
861+ let module = B :: codegen ( cgcx, module, module_config) ;
849862 WorkItemResult :: Finished ( module)
850863 }
851864 ComputedLtoType :: Thin => {
@@ -947,6 +960,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
947960
948961 WorkItemResult :: Finished ( CompiledModule {
949962 links_from_incr_cache,
963+ kind : ModuleKind :: Regular ,
950964 name : module. name ,
951965 object,
952966 dwarf_object,
@@ -1133,6 +1147,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
11331147 diag_emitter : shared_emitter. clone ( ) ,
11341148 output_filenames : Arc :: clone ( tcx. output_filenames ( ( ) ) ) ,
11351149 module_config : regular_config,
1150+ allocator_config,
11361151 tm_factory : backend. target_machine_factory ( tcx. sess , ol, backend_features) ,
11371152 msvc_imps_needed : msvc_imps_needed ( tcx) ,
11381153 is_pe_coff : tcx. sess . target . is_like_windows ,
@@ -1147,11 +1162,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
11471162 invocation_temp : sess. invocation_temp . clone ( ) ,
11481163 } ;
11491164
1150- let compiled_allocator_module = allocator_module. map ( |mut allocator_module| {
1151- B :: optimize ( & cgcx, tcx. sess . dcx ( ) , & mut allocator_module, & allocator_config) ;
1152- B :: codegen ( & cgcx, allocator_module, & allocator_config)
1153- } ) ;
1154-
11551165 // This is the "main loop" of parallel work happening for parallel codegen.
11561166 // It's here that we manage parallelism, schedule work, and work with
11571167 // messages coming from clients.
@@ -1331,6 +1341,17 @@ fn start_executing_work<B: ExtraBackendMethods>(
13311341
13321342 let mut llvm_start_time: Option < VerboseTimingGuard < ' _ > > = None ;
13331343
1344+ let compiled_allocator_module = allocator_module. and_then ( |allocator_module| {
1345+ match execute_optimize_work_item ( & cgcx, allocator_module) {
1346+ WorkItemResult :: Finished ( compiled_module) => return Some ( compiled_module) ,
1347+ WorkItemResult :: NeedsFatLto ( fat_lto_input) => needs_fat_lto. push ( fat_lto_input) ,
1348+ WorkItemResult :: NeedsThinLto ( name, thin_buffer) => {
1349+ needs_thin_lto. push ( ( name, thin_buffer) )
1350+ }
1351+ }
1352+ None
1353+ } ) ;
1354+
13341355 // Run the message loop while there's still anything that needs message
13351356 // processing. Note that as soon as codegen is aborted we simply want to
13361357 // wait for all existing work to finish, so many of the conditions here
0 commit comments