@@ -300,13 +300,6 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
300
300
let is_incremental_build = tcx. sess . opts . incremental . is_some ( ) ;
301
301
let mut internalization_candidates = FxHashSet ( ) ;
302
302
303
- // Determine if monomorphizations instantiated in this crate will be made
304
- // available to downstream crates. This depends on whether we are in
305
- // share-generics mode and whether the current crate can even have
306
- // downstream crates.
307
- let export_generics = tcx. sess . opts . share_generics ( ) &&
308
- tcx. local_crate_exports_generics ( ) ;
309
-
310
303
for mono_item in mono_items {
311
304
match mono_item. instantiation_mode ( tcx) {
312
305
InstantiationMode :: GloballyShared { .. } => { }
@@ -322,146 +315,38 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
322
315
None => fallback_cgu_name ( tcx) ,
323
316
} ;
324
317
325
- let make_codegen_unit = || {
326
- CodegenUnit :: new ( codegen_unit_name. clone ( ) )
327
- } ;
328
-
329
318
let codegen_unit = codegen_units. entry ( codegen_unit_name. clone ( ) )
330
- . or_insert_with ( make_codegen_unit ) ;
319
+ . or_insert_with ( || CodegenUnit :: new ( codegen_unit_name . clone ( ) ) ) ;
331
320
332
321
let mut can_be_internalized = true ;
333
- let default_visibility = |id : DefId , is_generic : bool | {
334
- if !tcx. sess . target . target . options . default_hidden_visibility {
335
- return Visibility :: Default
336
- }
322
+ let ( linkage, visibility) = mono_item_linkage_and_visibility (
323
+ tcx,
324
+ & mono_item,
325
+ & mut can_be_internalized,
326
+ & |id, is_generic| {
327
+ if !tcx. sess . target . target . options . default_hidden_visibility {
328
+ return Visibility :: Default
329
+ }
337
330
338
- // Generic functions never have export level C
339
- if is_generic {
340
- return Visibility :: Hidden
341
- }
331
+ // Generic functions never have export level C
332
+ if is_generic {
333
+ return Visibility :: Hidden
334
+ }
342
335
343
- // Things with export level C don't get instantiated in downstream
344
- // crates
345
- if !id. is_local ( ) {
346
- return Visibility :: Hidden
347
- }
336
+ // Things with export level C don't get instantiated in
337
+ // downstream crates
338
+ if !id. is_local ( ) {
339
+ return Visibility :: Hidden
340
+ }
348
341
349
- if let Some ( & SymbolExportLevel :: C ) = tcx. reachable_non_generics ( id. krate )
350
- . get ( & id) {
351
- Visibility :: Default
352
- } else {
353
- Visibility :: Hidden
354
- }
355
- } ;
356
- let ( linkage, visibility) = match mono_item. explicit_linkage ( tcx) {
357
- Some ( explicit_linkage) => ( explicit_linkage, Visibility :: Default ) ,
358
- None => {
359
- match mono_item {
360
- MonoItem :: Fn ( ref instance) => {
361
- let visibility = match instance. def {
362
- InstanceDef :: Item ( def_id) => {
363
- let is_generic = instance. substs
364
- . types ( )
365
- . next ( )
366
- . is_some ( ) ;
367
-
368
- // The `start_fn` lang item is actually a
369
- // monomorphized instance of a function in the
370
- // standard library, used for the `main`
371
- // function. We don't want to export it so we
372
- // tag it with `Hidden` visibility but this
373
- // symbol is only referenced from the actual
374
- // `main` symbol which we unfortunately don't
375
- // know anything about during
376
- // partitioning/collection. As a result we
377
- // forcibly keep this symbol out of the
378
- // `internalization_candidates` set.
379
- //
380
- // FIXME: eventually we don't want to always
381
- // force this symbol to have hidden
382
- // visibility, it should indeed be a candidate
383
- // for internalization, but we have to
384
- // understand that it's referenced from the
385
- // `main` symbol we'll generate later.
386
- if tcx. lang_items ( ) . start_fn ( ) == Some ( def_id) {
387
- can_be_internalized = false ;
388
- Visibility :: Hidden
389
- } else if def_id. is_local ( ) {
390
- if is_generic {
391
- if export_generics {
392
- if tcx. is_unreachable_local_definition ( def_id) {
393
- // This instance cannot be used
394
- // from another crate.
395
- Visibility :: Hidden
396
- } else {
397
- // This instance might be useful in
398
- // a downstream crate.
399
- can_be_internalized = false ;
400
- default_visibility ( def_id, true )
401
- }
402
- } else {
403
- // We are not exporting generics or
404
- // the definition is not reachable
405
- // for downstream crates, we can
406
- // internalize its instantiations.
407
- Visibility :: Hidden
408
- }
409
- } else {
410
- // This isn't a generic function.
411
- if tcx. is_reachable_non_generic ( def_id) {
412
- can_be_internalized = false ;
413
- debug_assert ! ( !is_generic) ;
414
- default_visibility ( def_id, false )
415
- } else {
416
- Visibility :: Hidden
417
- }
418
- }
419
- } else {
420
- // This is an upstream DefId.
421
- if export_generics && is_generic {
422
- // If it is a upstream monomorphization
423
- // and we export generics, we must make
424
- // it available to downstream crates.
425
- can_be_internalized = false ;
426
- default_visibility ( def_id, true )
427
- } else {
428
- Visibility :: Hidden
429
- }
430
- }
431
- }
432
- InstanceDef :: FnPtrShim ( ..) |
433
- InstanceDef :: Virtual ( ..) |
434
- InstanceDef :: Intrinsic ( ..) |
435
- InstanceDef :: ClosureOnceShim { .. } |
436
- InstanceDef :: DropGlue ( ..) |
437
- InstanceDef :: CloneShim ( ..) => {
438
- Visibility :: Hidden
439
- }
440
- } ;
441
- ( Linkage :: External , visibility)
442
- }
443
- MonoItem :: Static ( def_id) => {
444
- let visibility = if tcx. is_reachable_non_generic ( def_id) {
445
- can_be_internalized = false ;
446
- default_visibility ( def_id, false )
447
- } else {
448
- Visibility :: Hidden
449
- } ;
450
- ( Linkage :: External , visibility)
451
- }
452
- MonoItem :: GlobalAsm ( node_id) => {
453
- let def_id = tcx. hir . local_def_id ( node_id) ;
454
- let visibility = if tcx. is_reachable_non_generic ( def_id) {
455
- can_be_internalized = false ;
456
- default_visibility ( def_id, false )
457
- } else {
458
- Visibility :: Hidden
459
- } ;
460
- ( Linkage :: External , visibility)
461
- }
342
+ // C-export level items remain at `Default`, all other internal
343
+ // items become `Hidden`
344
+ match tcx. reachable_non_generics ( id. krate ) . get ( & id) {
345
+ Some ( SymbolExportLevel :: C ) => Visibility :: Default ,
346
+ _ => Visibility :: Hidden ,
462
347
}
463
- }
464
- } ;
348
+ } ,
349
+ ) ;
465
350
if visibility == Visibility :: Hidden && can_be_internalized {
466
351
internalization_candidates. insert ( mono_item) ;
467
352
}
@@ -487,6 +372,132 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
487
372
}
488
373
}
489
374
375
+ fn mono_item_linkage_and_visibility (
376
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
377
+ mono_item : & MonoItem < ' tcx > ,
378
+ can_be_internalized : & mut bool ,
379
+ default : & dyn Fn ( DefId , bool ) -> Visibility ,
380
+ ) -> ( Linkage , Visibility ) {
381
+ if let Some ( explicit_linkage) = mono_item. explicit_linkage ( tcx) {
382
+ return ( explicit_linkage, Visibility :: Default )
383
+ }
384
+ let vis = mono_item_visibility ( tcx, mono_item, can_be_internalized, default) ;
385
+ ( Linkage :: External , vis)
386
+ }
387
+
388
+ fn mono_item_visibility (
389
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
390
+ mono_item : & MonoItem < ' tcx > ,
391
+ can_be_internalized : & mut bool ,
392
+ default_visibility : & dyn Fn ( DefId , bool ) -> Visibility ,
393
+ ) -> Visibility {
394
+ let instance = match mono_item {
395
+ // This is pretty complicated, go below
396
+ MonoItem :: Fn ( instance) => instance,
397
+
398
+ // Misc handling for generics and such, but otherwise
399
+ MonoItem :: Static ( def_id) => {
400
+ return if tcx. is_reachable_non_generic ( * def_id) {
401
+ * can_be_internalized = false ;
402
+ default_visibility ( * def_id, false )
403
+ } else {
404
+ Visibility :: Hidden
405
+ } ;
406
+ }
407
+ MonoItem :: GlobalAsm ( node_id) => {
408
+ let def_id = tcx. hir . local_def_id ( * node_id) ;
409
+ return if tcx. is_reachable_non_generic ( def_id) {
410
+ * can_be_internalized = false ;
411
+ default_visibility ( def_id, false )
412
+ } else {
413
+ Visibility :: Hidden
414
+ } ;
415
+ }
416
+ } ;
417
+
418
+ let def_id = match instance. def {
419
+ InstanceDef :: Item ( def_id) => def_id,
420
+
421
+ // These are all compiler glue and such, never exported, always hidden.
422
+ InstanceDef :: FnPtrShim ( ..) |
423
+ InstanceDef :: Virtual ( ..) |
424
+ InstanceDef :: Intrinsic ( ..) |
425
+ InstanceDef :: ClosureOnceShim { .. } |
426
+ InstanceDef :: DropGlue ( ..) |
427
+ InstanceDef :: CloneShim ( ..) => {
428
+ return Visibility :: Hidden
429
+ }
430
+ } ;
431
+
432
+ // The `start_fn` lang item is actually a monomorphized instance of a
433
+ // function in the standard library, used for the `main` function. We don't
434
+ // want to export it so we tag it with `Hidden` visibility but this symbol
435
+ // is only referenced from the actual `main` symbol which we unfortunately
436
+ // don't know anything about during partitioning/collection. As a result we
437
+ // forcibly keep this symbol out of the `internalization_candidates` set.
438
+ //
439
+ // FIXME: eventually we don't want to always force this symbol to have
440
+ // hidden visibility, it should indeed be a candidate for
441
+ // internalization, but we have to understand that it's referenced
442
+ // from the `main` symbol we'll generate later.
443
+ if tcx. lang_items ( ) . start_fn ( ) == Some ( def_id) {
444
+ * can_be_internalized = false ;
445
+ return Visibility :: Hidden
446
+ }
447
+
448
+ // Determine if monomorphizations instantiated in this crate will be made
449
+ // available to downstream crates. This depends on whether we are in
450
+ // share-generics mode and whether the current crate can even have
451
+ // downstream crates.
452
+ let export_generics = tcx. sess . opts . share_generics ( ) &&
453
+ tcx. local_crate_exports_generics ( ) ;
454
+
455
+ let is_generic = instance. substs . types ( ) . next ( ) . is_some ( ) ;
456
+
457
+ // Upstream `DefId` instances get different handling than local ones
458
+ if !def_id. is_local ( ) {
459
+ return if export_generics && is_generic {
460
+ // If it is a upstream monomorphization
461
+ // and we export generics, we must make
462
+ // it available to downstream crates.
463
+ * can_be_internalized = false ;
464
+ default_visibility ( def_id, true )
465
+ } else {
466
+ Visibility :: Hidden
467
+ }
468
+ }
469
+
470
+ if is_generic {
471
+ if export_generics {
472
+ if tcx. is_unreachable_local_definition ( def_id) {
473
+ // This instance cannot be used
474
+ // from another crate.
475
+ Visibility :: Hidden
476
+ } else {
477
+ // This instance might be useful in
478
+ // a downstream crate.
479
+ * can_be_internalized = false ;
480
+ default_visibility ( def_id, true )
481
+ }
482
+ } else {
483
+ // We are not exporting generics or
484
+ // the definition is not reachable
485
+ // for downstream crates, we can
486
+ // internalize its instantiations.
487
+ Visibility :: Hidden
488
+ }
489
+ } else {
490
+ // This isn't a generic function.
491
+ if tcx. is_reachable_non_generic ( def_id) {
492
+ * can_be_internalized = false ;
493
+ debug_assert ! ( !is_generic) ;
494
+ default_visibility ( def_id, false )
495
+ } else {
496
+ Visibility :: Hidden
497
+ }
498
+ }
499
+ }
500
+
490
501
fn merge_codegen_units < ' tcx > ( initial_partitioning : & mut PreInliningPartitioning < ' tcx > ,
491
502
target_cgu_count : usize ,
492
503
crate_name : & str ) {
0 commit comments