@@ -125,7 +125,7 @@ struct PartitioningCx<'a, 'tcx> {
125
125
usage_map : & ' a UsageMap < ' tcx > ,
126
126
}
127
127
128
- struct PlacedRootMonoItems < ' tcx > {
128
+ struct PlacedMonoItems < ' tcx > {
129
129
/// The codegen units, sorted by name to make things deterministic.
130
130
codegen_units : Vec < CodegenUnit < ' tcx > > ,
131
131
@@ -150,36 +150,20 @@ where
150
150
151
151
let cx = & PartitioningCx { tcx, usage_map } ;
152
152
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) ;
159
157
160
158
for cgu in & mut placed. codegen_units {
161
159
cgu. create_size_estimate ( tcx) ;
162
160
}
163
161
164
- debug_dump ( tcx, "ROOTS " , & placed. codegen_units , placed. unique_inlined_stats ) ;
162
+ debug_dump ( tcx, "PLACE " , & placed. codegen_units , placed. unique_inlined_stats ) ;
165
163
166
164
placed
167
165
} ;
168
166
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
-
183
167
// Merge until we have at most `max_cgu_count` codegen units.
184
168
// `merge_codegen_units` is responsible for updating the CGU size
185
169
// estimates.
@@ -211,10 +195,7 @@ where
211
195
codegen_units
212
196
}
213
197
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 >
218
199
where
219
200
I : Iterator < Item = MonoItem < ' tcx > > ,
220
201
{
@@ -235,6 +216,8 @@ where
235
216
let mut num_unique_inlined_items = 0 ;
236
217
let mut unique_inlined_items_size = 0 ;
237
218
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.
238
221
match mono_item. instantiation_mode ( cx. tcx ) {
239
222
InstantiationMode :: GloballyShared { .. } => { }
240
223
InstantiationMode :: LocalCopy => {
@@ -247,7 +230,7 @@ where
247
230
let characteristic_def_id = characteristic_def_id_of_mono_item ( cx. tcx , mono_item) ;
248
231
let is_volatile = is_incremental_build && mono_item. is_generic_fn ( ) ;
249
232
250
- let codegen_unit_name = match characteristic_def_id {
233
+ let cgu_name = match characteristic_def_id {
251
234
Some ( def_id) => compute_codegen_unit_name (
252
235
cx. tcx ,
253
236
cgu_name_builder,
@@ -258,9 +241,7 @@ where
258
241
None => fallback_cgu_name ( cgu_name_builder) ,
259
242
} ;
260
243
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) ) ;
264
245
265
246
let mut can_be_internalized = true ;
266
247
let ( linkage, visibility) = mono_item_linkage_and_visibility (
@@ -273,23 +254,52 @@ where
273
254
internalization_candidates. insert ( mono_item) ;
274
255
}
275
256
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
+ }
277
273
}
278
274
279
275
// Always ensure we have at least one CGU; otherwise, if we have a
280
276
// crate with just types (for example), we could wind up with no CGU.
281
277
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 ) ) ;
284
280
}
285
281
286
282
let mut codegen_units: Vec < _ > = codegen_units. into_values ( ) . collect ( ) ;
287
283
codegen_units. sort_by ( |a, b| a. name ( ) . as_str ( ) . cmp ( b. name ( ) . as_str ( ) ) ) ;
288
284
289
- PlacedRootMonoItems {
285
+ return PlacedMonoItems {
290
286
codegen_units,
291
287
internalization_candidates,
292
288
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
+ } ) ;
293
303
}
294
304
}
295
305
@@ -407,43 +417,6 @@ fn merge_codegen_units<'tcx>(
407
417
codegen_units. sort_by ( |a, b| a. name ( ) . as_str ( ) . cmp ( b. name ( ) . as_str ( ) ) ) ;
408
418
}
409
419
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
-
447
420
fn internalize_symbols < ' tcx > (
448
421
cx : & PartitioningCx < ' _ , ' tcx > ,
449
422
codegen_units : & mut [ CodegenUnit < ' tcx > ] ,
0 commit comments