@@ -216,63 +216,85 @@ fn place_root_mono_items<'tcx, I>(tcx: TyCtxt<'tcx>, mono_items: I) -> PreInlini
216216where
217217 I : Iterator < Item = MonoItem < ' tcx > > ,
218218{
219- let mut roots = FxHashSet :: default ( ) ;
220- let mut codegen_units = FxHashMap :: default ( ) ;
221219 let is_incremental_build = tcx. sess . opts . incremental . is_some ( ) ;
222- let mut internalization_candidates = FxHashSet :: default ( ) ;
223220
224221 // Determine if monomorphizations instantiated in this crate will be made
225222 // available to downstream crates. This depends on whether we are in
226223 // share-generics mode and whether the current crate can even have
227224 // downstream crates.
228225 let export_generics = tcx. sess . opts . share_generics ( ) && tcx. local_crate_exports_generics ( ) ;
229226
230- let cgu_name_builder = & mut CodegenUnitNameBuilder :: new ( tcx) ;
231- let cgu_name_cache = & mut FxHashMap :: default ( ) ;
227+ let mono_items: Vec < _ > = mono_items. collect ( ) ;
232228
233- for mono_item in mono_items {
234- match mono_item. instantiation_mode ( tcx) {
235- InstantiationMode :: GloballyShared { .. } => { }
236- InstantiationMode :: LocalCopy => continue ,
237- }
229+ let _prof_timer = tcx. prof . generic_activity ( "place_root_mono_items_par" ) ;
238230
239- let characteristic_def_id = characteristic_def_id_of_mono_item ( tcx, mono_item) ;
240- let is_volatile = is_incremental_build && mono_item. is_generic_fn ( ) ;
231+ let chunks = sync:: par_partition ( & mono_items, 2 , |chunk| {
232+ let mut roots = Vec :: new ( ) ;
233+ let mut codegen_units = FxHashMap :: default ( ) ;
234+ let mut internalization_candidates = Vec :: new ( ) ;
241235
242- let codegen_unit_name = match characteristic_def_id {
243- Some ( def_id) => compute_codegen_unit_name (
244- tcx,
245- cgu_name_builder,
246- def_id,
247- is_volatile,
248- cgu_name_cache,
249- ) ,
250- None => fallback_cgu_name ( cgu_name_builder) ,
251- } ;
236+ let cgu_name_builder = & mut CodegenUnitNameBuilder :: new ( tcx) ;
237+ let cgu_name_cache = & mut FxHashMap :: default ( ) ;
252238
253- let codegen_unit = codegen_units
254- . entry ( codegen_unit_name)
255- . or_insert_with ( || CodegenUnit :: new ( codegen_unit_name) ) ;
239+ for & mono_item in chunk {
240+ match mono_item. instantiation_mode ( tcx) {
241+ InstantiationMode :: GloballyShared { .. } => { }
242+ InstantiationMode :: LocalCopy => continue ,
243+ }
256244
257- let mut can_be_internalized = true ;
258- let ( linkage, visibility) = mono_item_linkage_and_visibility (
259- tcx,
260- & mono_item,
261- & mut can_be_internalized,
262- export_generics,
263- ) ;
264- if visibility == Visibility :: Hidden && can_be_internalized {
265- internalization_candidates. insert ( mono_item) ;
245+ let characteristic_def_id = characteristic_def_id_of_mono_item ( tcx, mono_item) ;
246+ let is_volatile = is_incremental_build && mono_item. is_generic_fn ( ) ;
247+
248+ let codegen_unit_name = match characteristic_def_id {
249+ Some ( def_id) => compute_codegen_unit_name (
250+ tcx,
251+ cgu_name_builder,
252+ def_id,
253+ is_volatile,
254+ cgu_name_cache,
255+ ) ,
256+ None => fallback_cgu_name ( cgu_name_builder) ,
257+ } ;
258+
259+ let codegen_unit = codegen_units. entry ( codegen_unit_name) . or_insert_with ( || Vec :: new ( ) ) ;
260+
261+ let mut can_be_internalized = true ;
262+ let ( linkage, visibility) = mono_item_linkage_and_visibility (
263+ tcx,
264+ & mono_item,
265+ & mut can_be_internalized,
266+ export_generics,
267+ ) ;
268+ if visibility == Visibility :: Hidden && can_be_internalized {
269+ internalization_candidates. push ( mono_item) ;
270+ }
271+
272+ codegen_unit. push ( ( mono_item, ( linkage, visibility) ) ) ;
273+ roots. push ( mono_item) ;
266274 }
267275
268- codegen_unit. items_mut ( ) . insert ( mono_item, ( linkage, visibility) ) ;
269- roots. insert ( mono_item) ;
276+ ( roots, codegen_units, internalization_candidates)
277+ } ) ;
278+
279+ let _prof_timer = tcx. prof . generic_activity ( "place_root_mono_items_merge" ) ;
280+
281+ let mut roots = FxHashSet :: default ( ) ;
282+ let mut codegen_units: FxHashMap < Symbol , CodegenUnit < ' tcx > > = FxHashMap :: default ( ) ;
283+ let mut internalization_candidates = FxHashSet :: default ( ) ;
284+
285+ for ( chunk_roots, chunk_codegen_units, chunk_internalization_candidates) in chunks {
286+ roots. extend ( chunk_roots) ;
287+ internalization_candidates. extend ( chunk_internalization_candidates) ;
288+ for ( name, items) in chunk_codegen_units {
289+ let codegen_unit = codegen_units. entry ( name) . or_insert_with ( || CodegenUnit :: new ( name) ) ;
290+ codegen_unit. items_mut ( ) . extend ( items) ;
291+ }
270292 }
271293
272294 // Always ensure we have at least one CGU; otherwise, if we have a
273295 // crate with just types (for example), we could wind up with no CGU.
274296 if codegen_units. is_empty ( ) {
275- let codegen_unit_name = fallback_cgu_name ( cgu_name_builder ) ;
297+ let codegen_unit_name = fallback_cgu_name ( & mut CodegenUnitNameBuilder :: new ( tcx ) ) ;
276298 codegen_units. insert ( codegen_unit_name, CodegenUnit :: new ( codegen_unit_name) ) ;
277299 }
278300
0 commit comments