@@ -702,6 +702,7 @@ impl<B: WriteBackendMethods> WorkItem<B> {
702702
703703enum  WorkItemResult < B :  WriteBackendMethods >  { 
704704    Compiled ( CompiledModule ) , 
705+     NeedsLink ( ModuleCodegen < B :: Module > ) , 
705706    NeedsFatLTO ( FatLTOInput < B > ) , 
706707    NeedsThinLTO ( String ,  B :: ThinBuffer ) , 
707708} 
@@ -801,31 +802,28 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
801802        None 
802803    } ; 
803804
804-     Ok ( match  lto_type { 
805-         ComputedLtoType :: No  => { 
806-             let  module = unsafe  {  B :: codegen ( cgcx,  & diag_handler,  module,  module_config) ? } ; 
807-             WorkItemResult :: Compiled ( module) 
808-         } 
805+     match  lto_type { 
806+         ComputedLtoType :: No  => finish_intra_module_work ( cgcx,  module,  module_config) , 
809807        ComputedLtoType :: Thin  => { 
810808            let  ( name,  thin_buffer)  = B :: prepare_thin ( module) ; 
811809            if  let  Some ( path)  = bitcode { 
812810                fs:: write ( & path,  thin_buffer. data ( ) ) . unwrap_or_else ( |e| { 
813811                    panic ! ( "Error writing pre-lto-bitcode file `{}`: {}" ,  path. display( ) ,  e) ; 
814812                } ) ; 
815813            } 
816-             WorkItemResult :: NeedsThinLTO ( name,  thin_buffer) 
814+             Ok ( WorkItemResult :: NeedsThinLTO ( name,  thin_buffer) ) 
817815        } 
818816        ComputedLtoType :: Fat  => match  bitcode { 
819817            Some ( path)  => { 
820818                let  ( name,  buffer)  = B :: serialize_module ( module) ; 
821819                fs:: write ( & path,  buffer. data ( ) ) . unwrap_or_else ( |e| { 
822820                    panic ! ( "Error writing pre-lto-bitcode file `{}`: {}" ,  path. display( ) ,  e) ; 
823821                } ) ; 
824-                 WorkItemResult :: NeedsFatLTO ( FatLTOInput :: Serialized  {  name,  buffer } ) 
822+                 Ok ( WorkItemResult :: NeedsFatLTO ( FatLTOInput :: Serialized  {  name,  buffer } ) ) 
825823            } 
826-             None  => WorkItemResult :: NeedsFatLTO ( FatLTOInput :: InMemory ( module) ) , 
824+             None  => Ok ( WorkItemResult :: NeedsFatLTO ( FatLTOInput :: InMemory ( module) ) ) , 
827825        } , 
828-     } ) 
826+     } 
829827} 
830828
831829fn  execute_copy_from_cache_work_item < B :  ExtraBackendMethods > ( 
@@ -870,13 +868,26 @@ fn execute_lto_work_item<B: ExtraBackendMethods>(
870868    cgcx :  & CodegenContext < B > , 
871869    mut  module :  lto:: LtoModuleCodegen < B > , 
872870    module_config :  & ModuleConfig , 
871+ )  -> Result < WorkItemResult < B > ,  FatalError >  { 
872+     let  module = unsafe  {  module. optimize ( cgcx) ? } ; 
873+     finish_intra_module_work ( cgcx,  module,  module_config) 
874+ } 
875+ 
876+ fn  finish_intra_module_work < B :  ExtraBackendMethods > ( 
877+     cgcx :  & CodegenContext < B > , 
878+     module :  ModuleCodegen < B :: Module > , 
879+     module_config :  & ModuleConfig , 
873880)  -> Result < WorkItemResult < B > ,  FatalError >  { 
874881    let  diag_handler = cgcx. create_diag_handler ( ) ; 
875882
876-     unsafe  { 
877-         let  module = module. optimize ( cgcx) ?; 
878-         let  module = B :: codegen ( cgcx,  & diag_handler,  module,  module_config) ?; 
883+     if  !cgcx. opts . debugging_opts . combine_cgu 
884+         || module. kind  == ModuleKind :: Metadata 
885+         || module. kind  == ModuleKind :: Allocator 
886+     { 
887+         let  module = unsafe  {  B :: codegen ( cgcx,  & diag_handler,  module,  module_config) ? } ; 
879888        Ok ( WorkItemResult :: Compiled ( module) ) 
889+     }  else  { 
890+         Ok ( WorkItemResult :: NeedsLink ( module) ) 
880891    } 
881892} 
882893
@@ -891,6 +902,10 @@ pub enum Message<B: WriteBackendMethods> {
891902        thin_buffer :  B :: ThinBuffer , 
892903        worker_id :  usize , 
893904    } , 
905+     NeedsLink  { 
906+         module :  ModuleCodegen < B :: Module > , 
907+         worker_id :  usize , 
908+     } , 
894909    Done  { 
895910        result :  Result < CompiledModule ,  Option < WorkerFatalError > > , 
896911        worker_id :  usize , 
@@ -1178,6 +1193,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
11781193        let  mut  compiled_modules = vec ! [ ] ; 
11791194        let  mut  compiled_metadata_module = None ; 
11801195        let  mut  compiled_allocator_module = None ; 
1196+         let  mut  needs_link = Vec :: new ( ) ; 
11811197        let  mut  needs_fat_lto = Vec :: new ( ) ; 
11821198        let  mut  needs_thin_lto = Vec :: new ( ) ; 
11831199        let  mut  lto_import_only_modules = Vec :: new ( ) ; 
@@ -1434,6 +1450,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
14341450                        } 
14351451                    } 
14361452                } 
1453+                 Message :: NeedsLink  {  module,  worker_id }  => { 
1454+                     free_worker ( worker_id) ; 
1455+                     needs_link. push ( module) ; 
1456+                 } 
14371457                Message :: NeedsFatLTO  {  result,  worker_id }  => { 
14381458                    assert ! ( !started_lto) ; 
14391459                    free_worker ( worker_id) ; 
@@ -1462,6 +1482,18 @@ fn start_executing_work<B: ExtraBackendMethods>(
14621482            } 
14631483        } 
14641484
1485+         let  needs_link = mem:: take ( & mut  needs_link) ; 
1486+         if  !needs_link. is_empty ( )  { 
1487+             assert ! ( compiled_modules. is_empty( ) ) ; 
1488+             let  diag_handler = cgcx. create_diag_handler ( ) ; 
1489+             let  module = B :: run_link ( & cgcx,  & diag_handler,  needs_link) . map_err ( |_| ( ) ) ?; 
1490+             let  module = unsafe  { 
1491+                 B :: codegen ( & cgcx,  & diag_handler,  module,  cgcx. config ( ModuleKind :: Regular ) ) 
1492+                     . map_err ( |_| ( ) ) ?
1493+             } ; 
1494+             compiled_modules. push ( module) ; 
1495+         } 
1496+ 
14651497        // Drop to print timings 
14661498        drop ( llvm_start_time) ; 
14671499
@@ -1521,6 +1553,9 @@ fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B>
15211553                    Some ( Ok ( WorkItemResult :: Compiled ( m) ) )  => { 
15221554                        Message :: Done :: < B >  {  result :  Ok ( m) ,  worker_id } 
15231555                    } 
1556+                     Some ( Ok ( WorkItemResult :: NeedsLink ( m) ) )  => { 
1557+                         Message :: NeedsLink :: < B >  {  module :  m,  worker_id } 
1558+                     } 
15241559                    Some ( Ok ( WorkItemResult :: NeedsFatLTO ( m) ) )  => { 
15251560                        Message :: NeedsFatLTO :: < B >  {  result :  m,  worker_id } 
15261561                    } 
0 commit comments