@@ -201,7 +201,6 @@ use rustc_session::lint::builtin::LARGE_ASSIGNMENTS;
201
201
use rustc_session:: Limit ;
202
202
use rustc_span:: source_map:: { dummy_spanned, respan, Span , Spanned , DUMMY_SP } ;
203
203
use rustc_target:: abi:: Size ;
204
- use smallvec:: SmallVec ;
205
204
use std:: iter;
206
205
use std:: ops:: Range ;
207
206
use std:: path:: PathBuf ;
@@ -226,6 +225,44 @@ pub struct InliningMap<'tcx> {
226
225
inlines : GrowableBitSet < usize > ,
227
226
}
228
227
228
+ /// Struct to store mono items in each collecting and if they should
229
+ /// be inlined. We call `instantiation_mode` to get their inlining
230
+ /// status when inserting new elements, which avoids calling it in
231
+ /// `inlining_map.lock_mut()`. See the `collect_items_rec` implementation
232
+ /// below.
233
+ struct MonoItems < ' tcx > {
234
+ // If this is false, we do not need to compute whether items
235
+ // will need to be inlined.
236
+ compute_inlining : bool ,
237
+
238
+ // The TyCtxt used to determine whether the a item should
239
+ // be inlined.
240
+ tcx : TyCtxt < ' tcx > ,
241
+
242
+ // The collected mono items. The bool field in each element
243
+ // indicates whether this element should be inlined.
244
+ items : Vec < ( Spanned < MonoItem < ' tcx > > , bool /*inlined*/ ) > ,
245
+ }
246
+
247
+ impl < ' tcx > MonoItems < ' tcx > {
248
+ #[ inline]
249
+ fn push ( & mut self , item : Spanned < MonoItem < ' tcx > > ) {
250
+ self . extend ( [ item] ) ;
251
+ }
252
+
253
+ #[ inline]
254
+ fn extend < T : IntoIterator < Item = Spanned < MonoItem < ' tcx > > > > ( & mut self , iter : T ) {
255
+ self . items . extend ( iter. into_iter ( ) . map ( |mono_item| {
256
+ let inlined = if !self . compute_inlining {
257
+ false
258
+ } else {
259
+ mono_item. node . instantiation_mode ( self . tcx ) == InstantiationMode :: LocalCopy
260
+ } ;
261
+ ( mono_item, inlined)
262
+ } ) )
263
+ }
264
+ }
265
+
229
266
impl < ' tcx > InliningMap < ' tcx > {
230
267
fn new ( ) -> InliningMap < ' tcx > {
231
268
InliningMap {
@@ -235,17 +272,23 @@ impl<'tcx> InliningMap<'tcx> {
235
272
}
236
273
}
237
274
238
- fn record_accesses ( & mut self , source : MonoItem < ' tcx > , new_targets : & [ ( MonoItem < ' tcx > , bool ) ] ) {
275
+ fn record_accesses < ' a > (
276
+ & mut self ,
277
+ source : MonoItem < ' tcx > ,
278
+ new_targets : & ' a [ ( Spanned < MonoItem < ' tcx > > , bool ) ] ,
279
+ ) where
280
+ ' tcx : ' a ,
281
+ {
239
282
let start_index = self . targets . len ( ) ;
240
283
let new_items_count = new_targets. len ( ) ;
241
284
let new_items_count_total = new_items_count + self . targets . len ( ) ;
242
285
243
286
self . targets . reserve ( new_items_count) ;
244
287
self . inlines . ensure ( new_items_count_total) ;
245
288
246
- for ( i, ( target , inline ) ) in new_targets. iter ( ) . enumerate ( ) {
247
- self . targets . push ( * target ) ;
248
- if * inline {
289
+ for ( i, ( Spanned { node : mono_item , .. } , inlined ) ) in new_targets. into_iter ( ) . enumerate ( ) {
290
+ self . targets . push ( * mono_item ) ;
291
+ if * inlined {
249
292
self . inlines . insert ( i + start_index) ;
250
293
}
251
294
}
@@ -321,7 +364,7 @@ pub fn collect_crate_mono_items(
321
364
// start monomorphizing from.
322
365
fn collect_roots ( tcx : TyCtxt < ' _ > , mode : MonoItemCollectionMode ) -> Vec < MonoItem < ' _ > > {
323
366
debug ! ( "collecting roots" ) ;
324
- let mut roots = Vec :: new ( ) ;
367
+ let mut roots = MonoItems { compute_inlining : false , tcx , items : Vec :: new ( ) } ;
325
368
326
369
{
327
370
let entry_fn = tcx. entry_fn ( ( ) ) ;
@@ -347,8 +390,11 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
347
390
// whose predicates hold. Luckily, items that aren't instantiable
348
391
// can't actually be used, so we can just skip codegenning them.
349
392
roots
393
+ . items
350
394
. into_iter ( )
351
- . filter_map ( |root| root. node . is_instantiable ( tcx) . then_some ( root. node ) )
395
+ . filter_map ( |( Spanned { node : mono_item, .. } , _) | {
396
+ mono_item. is_instantiable ( tcx) . then_some ( mono_item)
397
+ } )
352
398
. collect ( )
353
399
}
354
400
@@ -368,7 +414,7 @@ fn collect_items_rec<'tcx>(
368
414
}
369
415
debug ! ( "BEGIN collect_items_rec({})" , starting_point. node) ;
370
416
371
- let mut neighbors = Vec :: new ( ) ;
417
+ let mut neighbors = MonoItems { compute_inlining : true , tcx , items : Vec :: new ( ) } ;
372
418
let recursion_depth_reset;
373
419
374
420
//
@@ -483,10 +529,9 @@ fn collect_items_rec<'tcx>(
483
529
& format ! ( "the above error was encountered while instantiating `{}`" , formatted_item) ,
484
530
) ;
485
531
}
532
+ inlining_map. lock_mut ( ) . record_accesses ( starting_point. node , & neighbors. items ) ;
486
533
487
- record_accesses ( tcx, starting_point. node , neighbors. iter ( ) . map ( |i| & i. node ) , inlining_map) ;
488
-
489
- for neighbour in neighbors {
534
+ for ( neighbour, _) in neighbors. items {
490
535
collect_items_rec ( tcx, neighbour, visited, recursion_depths, recursion_limit, inlining_map) ;
491
536
}
492
537
@@ -497,25 +542,6 @@ fn collect_items_rec<'tcx>(
497
542
debug ! ( "END collect_items_rec({})" , starting_point. node) ;
498
543
}
499
544
500
- fn record_accesses < ' a , ' tcx : ' a > (
501
- tcx : TyCtxt < ' tcx > ,
502
- caller : MonoItem < ' tcx > ,
503
- callees : impl Iterator < Item = & ' a MonoItem < ' tcx > > ,
504
- inlining_map : MTRef < ' _ , MTLock < InliningMap < ' tcx > > > ,
505
- ) {
506
- let is_inlining_candidate = |mono_item : & MonoItem < ' tcx > | {
507
- mono_item. instantiation_mode ( tcx) == InstantiationMode :: LocalCopy
508
- } ;
509
-
510
- // We collect this into a `SmallVec` to avoid calling `is_inlining_candidate` in the lock.
511
- // FIXME: Call `is_inlining_candidate` when pushing to `neighbors` in `collect_items_rec`
512
- // instead to avoid creating this `SmallVec`.
513
- let accesses: SmallVec < [ _ ; 128 ] > =
514
- callees. map ( |mono_item| ( * mono_item, is_inlining_candidate ( mono_item) ) ) . collect ( ) ;
515
-
516
- inlining_map. lock_mut ( ) . record_accesses ( caller, & accesses) ;
517
- }
518
-
519
545
/// Format instance name that is already known to be too long for rustc.
520
546
/// Show only the first and last 32 characters to avoid blasting
521
547
/// the user's terminal with thousands of lines of type-name.
@@ -627,7 +653,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
627
653
struct MirNeighborCollector < ' a , ' tcx > {
628
654
tcx : TyCtxt < ' tcx > ,
629
655
body : & ' a mir:: Body < ' tcx > ,
630
- output : & ' a mut Vec < Spanned < MonoItem < ' tcx > > > ,
656
+ output : & ' a mut MonoItems < ' tcx > ,
631
657
instance : Instance < ' tcx > ,
632
658
}
633
659
@@ -905,7 +931,7 @@ fn visit_drop_use<'tcx>(
905
931
ty : Ty < ' tcx > ,
906
932
is_direct_call : bool ,
907
933
source : Span ,
908
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
934
+ output : & mut MonoItems < ' tcx > ,
909
935
) {
910
936
let instance = Instance :: resolve_drop_in_place ( tcx, ty) ;
911
937
visit_instance_use ( tcx, instance, is_direct_call, source, output) ;
@@ -916,7 +942,7 @@ fn visit_fn_use<'tcx>(
916
942
ty : Ty < ' tcx > ,
917
943
is_direct_call : bool ,
918
944
source : Span ,
919
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
945
+ output : & mut MonoItems < ' tcx > ,
920
946
) {
921
947
if let ty:: FnDef ( def_id, substs) = * ty. kind ( ) {
922
948
let instance = if is_direct_call {
@@ -934,7 +960,7 @@ fn visit_instance_use<'tcx>(
934
960
instance : ty:: Instance < ' tcx > ,
935
961
is_direct_call : bool ,
936
962
source : Span ,
937
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
963
+ output : & mut MonoItems < ' tcx > ,
938
964
) {
939
965
debug ! ( "visit_item_use({:?}, is_direct_call={:?})" , instance, is_direct_call) ;
940
966
if !should_codegen_locally ( tcx, & instance) {
@@ -1117,7 +1143,7 @@ fn create_mono_items_for_vtable_methods<'tcx>(
1117
1143
trait_ty : Ty < ' tcx > ,
1118
1144
impl_ty : Ty < ' tcx > ,
1119
1145
source : Span ,
1120
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
1146
+ output : & mut MonoItems < ' tcx > ,
1121
1147
) {
1122
1148
assert ! ( !trait_ty. has_escaping_bound_vars( ) && !impl_ty. has_escaping_bound_vars( ) ) ;
1123
1149
@@ -1159,7 +1185,7 @@ fn create_mono_items_for_vtable_methods<'tcx>(
1159
1185
struct RootCollector < ' a , ' tcx > {
1160
1186
tcx : TyCtxt < ' tcx > ,
1161
1187
mode : MonoItemCollectionMode ,
1162
- output : & ' a mut Vec < Spanned < MonoItem < ' tcx > > > ,
1188
+ output : & ' a mut MonoItems < ' tcx > ,
1163
1189
entry_fn : Option < ( DefId , EntryFnType ) > ,
1164
1190
}
1165
1191
@@ -1305,7 +1331,7 @@ fn item_requires_monomorphization(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
1305
1331
fn create_mono_items_for_default_impls < ' tcx > (
1306
1332
tcx : TyCtxt < ' tcx > ,
1307
1333
item : & ' tcx hir:: Item < ' tcx > ,
1308
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
1334
+ output : & mut MonoItems < ' tcx > ,
1309
1335
) {
1310
1336
match item. kind {
1311
1337
hir:: ItemKind :: Impl ( ref impl_) => {
@@ -1361,11 +1387,7 @@ fn create_mono_items_for_default_impls<'tcx>(
1361
1387
}
1362
1388
1363
1389
/// Scans the miri alloc in order to find function calls, closures, and drop-glue.
1364
- fn collect_miri < ' tcx > (
1365
- tcx : TyCtxt < ' tcx > ,
1366
- alloc_id : AllocId ,
1367
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
1368
- ) {
1390
+ fn collect_miri < ' tcx > ( tcx : TyCtxt < ' tcx > , alloc_id : AllocId , output : & mut MonoItems < ' tcx > ) {
1369
1391
match tcx. global_alloc ( alloc_id) {
1370
1392
GlobalAlloc :: Static ( def_id) => {
1371
1393
assert ! ( !tcx. is_thread_local_static( def_id) ) ;
@@ -1396,7 +1418,7 @@ fn collect_miri<'tcx>(
1396
1418
fn collect_neighbours < ' tcx > (
1397
1419
tcx : TyCtxt < ' tcx > ,
1398
1420
instance : Instance < ' tcx > ,
1399
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
1421
+ output : & mut MonoItems < ' tcx > ,
1400
1422
) {
1401
1423
debug ! ( "collect_neighbours: {:?}" , instance. def_id( ) ) ;
1402
1424
let body = tcx. instance_mir ( instance. def ) ;
@@ -1407,7 +1429,7 @@ fn collect_neighbours<'tcx>(
1407
1429
fn collect_const_value < ' tcx > (
1408
1430
tcx : TyCtxt < ' tcx > ,
1409
1431
value : ConstValue < ' tcx > ,
1410
- output : & mut Vec < Spanned < MonoItem < ' tcx > > > ,
1432
+ output : & mut MonoItems < ' tcx > ,
1411
1433
) {
1412
1434
match value {
1413
1435
ConstValue :: Scalar ( Scalar :: Ptr ( ptr, _size) ) => collect_miri ( tcx, ptr. provenance , output) ,
0 commit comments