@@ -702,6 +702,7 @@ impl<B: WriteBackendMethods> WorkItem<B> {
702
702
703
703
enum WorkItemResult < B : WriteBackendMethods > {
704
704
Compiled ( CompiledModule ) ,
705
+ NeedsLink ( ModuleCodegen < B :: Module > ) ,
705
706
NeedsFatLTO ( FatLTOInput < B > ) ,
706
707
NeedsThinLTO ( String , B :: ThinBuffer ) ,
707
708
}
@@ -801,31 +802,28 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
801
802
None
802
803
} ;
803
804
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) ,
809
807
ComputedLtoType :: Thin => {
810
808
let ( name, thin_buffer) = B :: prepare_thin ( module) ;
811
809
if let Some ( path) = bitcode {
812
810
fs:: write ( & path, thin_buffer. data ( ) ) . unwrap_or_else ( |e| {
813
811
panic ! ( "Error writing pre-lto-bitcode file `{}`: {}" , path. display( ) , e) ;
814
812
} ) ;
815
813
}
816
- WorkItemResult :: NeedsThinLTO ( name, thin_buffer)
814
+ Ok ( WorkItemResult :: NeedsThinLTO ( name, thin_buffer) )
817
815
}
818
816
ComputedLtoType :: Fat => match bitcode {
819
817
Some ( path) => {
820
818
let ( name, buffer) = B :: serialize_module ( module) ;
821
819
fs:: write ( & path, buffer. data ( ) ) . unwrap_or_else ( |e| {
822
820
panic ! ( "Error writing pre-lto-bitcode file `{}`: {}" , path. display( ) , e) ;
823
821
} ) ;
824
- WorkItemResult :: NeedsFatLTO ( FatLTOInput :: Serialized { name, buffer } )
822
+ Ok ( WorkItemResult :: NeedsFatLTO ( FatLTOInput :: Serialized { name, buffer } ) )
825
823
}
826
- None => WorkItemResult :: NeedsFatLTO ( FatLTOInput :: InMemory ( module) ) ,
824
+ None => Ok ( WorkItemResult :: NeedsFatLTO ( FatLTOInput :: InMemory ( module) ) ) ,
827
825
} ,
828
- } )
826
+ }
829
827
}
830
828
831
829
fn execute_copy_from_cache_work_item < B : ExtraBackendMethods > (
@@ -870,13 +868,26 @@ fn execute_lto_work_item<B: ExtraBackendMethods>(
870
868
cgcx : & CodegenContext < B > ,
871
869
mut module : lto:: LtoModuleCodegen < B > ,
872
870
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 ,
873
880
) -> Result < WorkItemResult < B > , FatalError > {
874
881
let diag_handler = cgcx. create_diag_handler ( ) ;
875
882
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) ? } ;
879
888
Ok ( WorkItemResult :: Compiled ( module) )
889
+ } else {
890
+ Ok ( WorkItemResult :: NeedsLink ( module) )
880
891
}
881
892
}
882
893
@@ -891,6 +902,10 @@ pub enum Message<B: WriteBackendMethods> {
891
902
thin_buffer : B :: ThinBuffer ,
892
903
worker_id : usize ,
893
904
} ,
905
+ NeedsLink {
906
+ module : ModuleCodegen < B :: Module > ,
907
+ worker_id : usize ,
908
+ } ,
894
909
Done {
895
910
result : Result < CompiledModule , Option < WorkerFatalError > > ,
896
911
worker_id : usize ,
@@ -1178,6 +1193,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
1178
1193
let mut compiled_modules = vec ! [ ] ;
1179
1194
let mut compiled_metadata_module = None ;
1180
1195
let mut compiled_allocator_module = None ;
1196
+ let mut needs_link = Vec :: new ( ) ;
1181
1197
let mut needs_fat_lto = Vec :: new ( ) ;
1182
1198
let mut needs_thin_lto = Vec :: new ( ) ;
1183
1199
let mut lto_import_only_modules = Vec :: new ( ) ;
@@ -1434,6 +1450,10 @@ fn start_executing_work<B: ExtraBackendMethods>(
1434
1450
}
1435
1451
}
1436
1452
}
1453
+ Message :: NeedsLink { module, worker_id } => {
1454
+ free_worker ( worker_id) ;
1455
+ needs_link. push ( module) ;
1456
+ }
1437
1457
Message :: NeedsFatLTO { result, worker_id } => {
1438
1458
assert ! ( !started_lto) ;
1439
1459
free_worker ( worker_id) ;
@@ -1462,6 +1482,18 @@ fn start_executing_work<B: ExtraBackendMethods>(
1462
1482
}
1463
1483
}
1464
1484
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
+
1465
1497
// Drop to print timings
1466
1498
drop ( llvm_start_time) ;
1467
1499
@@ -1521,6 +1553,9 @@ fn spawn_work<B: ExtraBackendMethods>(cgcx: CodegenContext<B>, work: WorkItem<B>
1521
1553
Some ( Ok ( WorkItemResult :: Compiled ( m) ) ) => {
1522
1554
Message :: Done :: < B > { result : Ok ( m) , worker_id }
1523
1555
}
1556
+ Some ( Ok ( WorkItemResult :: NeedsLink ( m) ) ) => {
1557
+ Message :: NeedsLink :: < B > { module : m, worker_id }
1558
+ }
1524
1559
Some ( Ok ( WorkItemResult :: NeedsFatLTO ( m) ) ) => {
1525
1560
Message :: NeedsFatLTO :: < B > { result : m, worker_id }
1526
1561
}
0 commit comments