@@ -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