@@ -125,7 +125,7 @@ struct PartitioningCx<'a, 'tcx> {
125125 usage_map : & ' a UsageMap < ' tcx > ,
126126}
127127
128- struct PlacedRootMonoItems < ' tcx > {
128+ struct PlacedMonoItems < ' tcx > {
129129 /// The codegen units, sorted by name to make things deterministic.
130130 codegen_units : Vec < CodegenUnit < ' tcx > > ,
131131
@@ -150,36 +150,20 @@ where
150150
151151 let cx = & PartitioningCx { tcx, usage_map } ;
152152
153- // In the first step, we place all regular monomorphizations into their
154- // respective 'home' codegen unit. Regular monomorphizations are all
155- // functions and statics defined in the local crate.
156- let PlacedRootMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = {
157- let _prof_timer = tcx. prof . generic_activity ( "cgu_partitioning_place_roots" ) ;
158- let mut placed = place_root_mono_items ( cx, mono_items) ;
153+ // Place all mono items into a codegen unit.
154+ let PlacedMonoItems { mut codegen_units, internalization_candidates, unique_inlined_stats } = {
155+ let _prof_timer = tcx. prof . generic_activity ( "cgu_partitioning_place_items" ) ;
156+ let mut placed = place_mono_items ( cx, mono_items) ;
159157
160158 for cgu in & mut placed. codegen_units {
161159 cgu. create_size_estimate ( tcx) ;
162160 }
163161
164- debug_dump ( tcx, "ROOTS " , & placed. codegen_units , placed. unique_inlined_stats ) ;
162+ debug_dump ( tcx, "PLACE " , & placed. codegen_units , placed. unique_inlined_stats ) ;
165163
166164 placed
167165 } ;
168166
169- // Use the usage map to put additional mono items in each codegen unit:
170- // drop-glue, functions from external crates, and local functions the
171- // definition of which is marked with `#[inline]`.
172- {
173- let _prof_timer = tcx. prof . generic_activity ( "cgu_partitioning_place_inline_items" ) ;
174- place_inlined_mono_items ( cx, & mut codegen_units) ;
175-
176- for cgu in & mut codegen_units {
177- cgu. create_size_estimate ( tcx) ;
178- }
179-
180- debug_dump ( tcx, "INLINE" , & codegen_units, unique_inlined_stats) ;
181- }
182-
183167 // Merge until we have at most `max_cgu_count` codegen units.
184168 // `merge_codegen_units` is responsible for updating the CGU size
185169 // estimates.
@@ -211,10 +195,7 @@ where
211195 codegen_units
212196}
213197
214- fn place_root_mono_items < ' tcx , I > (
215- cx : & PartitioningCx < ' _ , ' tcx > ,
216- mono_items : I ,
217- ) -> PlacedRootMonoItems < ' tcx >
198+ fn place_mono_items < ' tcx , I > ( cx : & PartitioningCx < ' _ , ' tcx > , mono_items : I ) -> PlacedMonoItems < ' tcx >
218199where
219200 I : Iterator < Item = MonoItem < ' tcx > > ,
220201{
@@ -235,6 +216,8 @@ where
235216 let mut num_unique_inlined_items = 0 ;
236217 let mut unique_inlined_items_size = 0 ;
237218 for mono_item in mono_items {
219+ // Handle only root items directly here. Inlined items are handled at
220+ // the bottom of the loop based on reachability.
238221 match mono_item. instantiation_mode ( cx. tcx ) {
239222 InstantiationMode :: GloballyShared { .. } => { }
240223 InstantiationMode :: LocalCopy => {
@@ -247,7 +230,7 @@ where
247230 let characteristic_def_id = characteristic_def_id_of_mono_item ( cx. tcx , mono_item) ;
248231 let is_volatile = is_incremental_build && mono_item. is_generic_fn ( ) ;
249232
250- let codegen_unit_name = match characteristic_def_id {
233+ let cgu_name = match characteristic_def_id {
251234 Some ( def_id) => compute_codegen_unit_name (
252235 cx. tcx ,
253236 cgu_name_builder,
@@ -258,9 +241,7 @@ where
258241 None => fallback_cgu_name ( cgu_name_builder) ,
259242 } ;
260243
261- let codegen_unit = codegen_units
262- . entry ( codegen_unit_name)
263- . or_insert_with ( || CodegenUnit :: new ( codegen_unit_name) ) ;
244+ let cgu = codegen_units. entry ( cgu_name) . or_insert_with ( || CodegenUnit :: new ( cgu_name) ) ;
264245
265246 let mut can_be_internalized = true ;
266247 let ( linkage, visibility) = mono_item_linkage_and_visibility (
@@ -273,23 +254,52 @@ where
273254 internalization_candidates. insert ( mono_item) ;
274255 }
275256
276- codegen_unit. items_mut ( ) . insert ( mono_item, ( linkage, visibility) ) ;
257+ cgu. items_mut ( ) . insert ( mono_item, ( linkage, visibility) ) ;
258+
259+ // Get all inlined items that are reachable from `mono_item` without
260+ // going via another root item. This includes drop-glue, functions from
261+ // external crates, and local functions the definition of which is
262+ // marked with `#[inline]`.
263+ let mut reachable_inlined_items = FxHashSet :: default ( ) ;
264+ get_reachable_inlined_items ( cx. tcx , mono_item, cx. usage_map , & mut reachable_inlined_items) ;
265+
266+ // Add those inlined items. It's possible an inlined item is reachable
267+ // from multiple root items within a CGU, which is fine, it just means
268+ // the `insert` will be a no-op.
269+ for inlined_item in reachable_inlined_items {
270+ // This is a CGU-private copy.
271+ cgu. items_mut ( ) . insert ( inlined_item, ( Linkage :: Internal , Visibility :: Default ) ) ;
272+ }
277273 }
278274
279275 // Always ensure we have at least one CGU; otherwise, if we have a
280276 // crate with just types (for example), we could wind up with no CGU.
281277 if codegen_units. is_empty ( ) {
282- let codegen_unit_name = fallback_cgu_name ( cgu_name_builder) ;
283- codegen_units. insert ( codegen_unit_name , CodegenUnit :: new ( codegen_unit_name ) ) ;
278+ let cgu_name = fallback_cgu_name ( cgu_name_builder) ;
279+ codegen_units. insert ( cgu_name , CodegenUnit :: new ( cgu_name ) ) ;
284280 }
285281
286282 let mut codegen_units: Vec < _ > = codegen_units. into_values ( ) . collect ( ) ;
287283 codegen_units. sort_by ( |a, b| a. name ( ) . as_str ( ) . cmp ( b. name ( ) . as_str ( ) ) ) ;
288284
289- PlacedRootMonoItems {
285+ return PlacedMonoItems {
290286 codegen_units,
291287 internalization_candidates,
292288 unique_inlined_stats : ( num_unique_inlined_items, unique_inlined_items_size) ,
289+ } ;
290+
291+ fn get_reachable_inlined_items < ' tcx > (
292+ tcx : TyCtxt < ' tcx > ,
293+ item : MonoItem < ' tcx > ,
294+ usage_map : & UsageMap < ' tcx > ,
295+ visited : & mut FxHashSet < MonoItem < ' tcx > > ,
296+ ) {
297+ usage_map. for_each_inlined_used_item ( tcx, item, |inlined_item| {
298+ let is_new = visited. insert ( inlined_item) ;
299+ if is_new {
300+ get_reachable_inlined_items ( tcx, inlined_item, usage_map, visited) ;
301+ }
302+ } ) ;
293303 }
294304}
295305
@@ -407,43 +417,6 @@ fn merge_codegen_units<'tcx>(
407417 codegen_units. sort_by ( |a, b| a. name ( ) . as_str ( ) . cmp ( b. name ( ) . as_str ( ) ) ) ;
408418}
409419
410- fn place_inlined_mono_items < ' tcx > (
411- cx : & PartitioningCx < ' _ , ' tcx > ,
412- codegen_units : & mut [ CodegenUnit < ' tcx > ] ,
413- ) {
414- for cgu in codegen_units. iter_mut ( ) {
415- // Collect all inlined items that need to be available in this codegen unit.
416- let mut reachable_inlined_items = FxHashSet :: default ( ) ;
417- for root in cgu. items ( ) . keys ( ) {
418- // Get all inlined items that are reachable from it without going
419- // via another root item.
420- get_reachable_inlined_items ( cx. tcx , * root, cx. usage_map , & mut reachable_inlined_items) ;
421- }
422-
423- // Add all monomorphizations that are not already there.
424- for inlined_item in reachable_inlined_items {
425- assert ! ( !cgu. items( ) . contains_key( & inlined_item) ) ;
426-
427- // This is a CGU-private copy.
428- cgu. items_mut ( ) . insert ( inlined_item, ( Linkage :: Internal , Visibility :: Default ) ) ;
429- }
430- }
431-
432- fn get_reachable_inlined_items < ' tcx > (
433- tcx : TyCtxt < ' tcx > ,
434- item : MonoItem < ' tcx > ,
435- usage_map : & UsageMap < ' tcx > ,
436- visited : & mut FxHashSet < MonoItem < ' tcx > > ,
437- ) {
438- usage_map. for_each_inlined_used_item ( tcx, item, |inlined_item| {
439- let is_new = visited. insert ( inlined_item) ;
440- if is_new {
441- get_reachable_inlined_items ( tcx, inlined_item, usage_map, visited) ;
442- }
443- } ) ;
444- }
445- }
446-
447420fn internalize_symbols < ' tcx > (
448421 cx : & PartitioningCx < ' _ , ' tcx > ,
449422 codegen_units : & mut [ CodegenUnit < ' tcx > ] ,
0 commit comments