@@ -218,7 +218,7 @@ use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
218218use rustc_hir:: lang_items:: LangItem ;
219219use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
220220use rustc_middle:: mir:: interpret:: { AllocId , ErrorHandled , GlobalAlloc , Scalar } ;
221- use rustc_middle:: mir:: mono:: { InstantiationMode , MonoItem } ;
221+ use rustc_middle:: mir:: mono:: { CollectionMode , InstantiationMode , MonoItem } ;
222222use rustc_middle:: mir:: visit:: Visitor as MirVisitor ;
223223use rustc_middle:: mir:: { self , Location , MentionedItem , traversal} ;
224224use rustc_middle:: query:: TyCtxtAt ;
@@ -268,24 +268,6 @@ struct SharedState<'tcx> {
268268 usage_map : MTLock < UsageMap < ' tcx > > ,
269269}
270270
271- /// See module-level docs on some contect for "mentioned" items.
272- #[ derive( Copy , Clone , Debug , PartialEq ) ]
273- enum CollectionMode {
274- /// Collect items that are used, i.e., actually needed for codegen.
275- ///
276- /// Which items are used can depend on optimization levels, as MIR optimizations can remove
277- /// uses.
278- UsedItems ,
279- /// Collect items that are mentioned. The goal of this mode is that it is independent of
280- /// optimizations: the set of "mentioned" items is computed before optimizations are run.
281- ///
282- /// The exact contents of this set are *not* a stable guarantee. (For instance, it is currently
283- /// computed after drop-elaboration. If we ever do some optimizations even in debug builds, we
284- /// might decide to run them before computing mentioned items.) The key property of this set is
285- /// that it is optimization-independent.
286- MentionedItems ,
287- }
288-
289271impl < ' tcx > UsageMap < ' tcx > {
290272 fn new ( ) -> UsageMap < ' tcx > {
291273 UsageMap { used_map : Default :: default ( ) , user_map : Default :: default ( ) }
@@ -447,13 +429,9 @@ fn collect_items_rec<'tcx>(
447429 ) ) ;
448430
449431 rustc_data_structures:: stack:: ensure_sufficient_stack ( || {
450- collect_items_of_instance (
451- tcx,
452- instance,
453- & mut used_items,
454- & mut mentioned_items,
455- mode,
456- )
432+ let ( used, mentioned) = tcx. items_of_instance ( ( instance, mode) ) ;
433+ used_items. extend ( used) ;
434+ mentioned_items. extend ( mentioned) ;
457435 } ) ;
458436 }
459437 MonoItem :: GlobalAsm ( item_id) => {
@@ -1199,14 +1177,12 @@ fn assoc_fn_of_type<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, fn_ident: Ident) ->
11991177/// Scans the MIR in order to find function calls, closures, and drop-glue.
12001178///
12011179/// Anything that's found is added to `output`. Furthermore the "mentioned items" of the MIR are returned.
1202- #[ instrument( skip( tcx, used_items , mentioned_items ) , level = "debug" ) ]
1180+ #[ instrument( skip( tcx) , level = "debug" ) ]
12031181fn collect_items_of_instance < ' tcx > (
12041182 tcx : TyCtxt < ' tcx > ,
12051183 instance : Instance < ' tcx > ,
1206- used_items : & mut MonoItems < ' tcx > ,
1207- mentioned_items : & mut MonoItems < ' tcx > ,
12081184 mode : CollectionMode ,
1209- ) {
1185+ ) -> ( MonoItems < ' tcx > , MonoItems < ' tcx > ) {
12101186 let body = tcx. instance_mir ( instance. def ) ;
12111187 // Naively, in "used" collection mode, all functions get added to *both* `used_items` and
12121188 // `mentioned_items`. Mentioned items processing will then notice that they have already been
@@ -1218,11 +1194,13 @@ fn collect_items_of_instance<'tcx>(
12181194 // mentioned item. So instead we collect all pre-monomorphized `MentionedItem` that were already
12191195 // added to `used_items` in a hash set, which can efficiently query in the
12201196 // `body.mentioned_items` loop below without even having to monomorphize the item.
1197+ let mut used_items = Default :: default ( ) ;
1198+ let mut mentioned_items = Default :: default ( ) ;
12211199 let mut used_mentioned_items = Default :: default ( ) ;
12221200 let mut collector = MirUsedCollector {
12231201 tcx,
12241202 body,
1225- used_items,
1203+ used_items : & mut used_items ,
12261204 used_mentioned_items : & mut used_mentioned_items,
12271205 instance,
12281206 visiting_call_terminator : false ,
@@ -1239,7 +1217,7 @@ fn collect_items_of_instance<'tcx>(
12391217 // them errors.
12401218 for const_op in body. required_consts ( ) {
12411219 if let Some ( val) = collector. eval_constant ( const_op) {
1242- collect_const_value ( tcx, val, mentioned_items) ;
1220+ collect_const_value ( tcx, val, & mut mentioned_items) ;
12431221 }
12441222 }
12451223
@@ -1248,9 +1226,19 @@ fn collect_items_of_instance<'tcx>(
12481226 for item in body. mentioned_items ( ) {
12491227 if !collector. used_mentioned_items . contains ( & item. node ) {
12501228 let item_mono = collector. monomorphize ( item. node ) ;
1251- visit_mentioned_item ( tcx, & item_mono, item. span , mentioned_items) ;
1229+ visit_mentioned_item ( tcx, & item_mono, item. span , & mut mentioned_items) ;
12521230 }
12531231 }
1232+
1233+ ( used_items, mentioned_items)
1234+ }
1235+
1236+ fn items_of_instance < ' tcx > (
1237+ tcx : TyCtxt < ' tcx > ,
1238+ ( instance, mode) : ( Instance < ' tcx > , CollectionMode ) ,
1239+ ) -> ( & ' tcx [ Spanned < MonoItem < ' tcx > > ] , & ' tcx [ Spanned < MonoItem < ' tcx > > ] ) {
1240+ let ( used_items, mentioned_items) = collect_items_of_instance ( tcx, instance, mode) ;
1241+ ( tcx. arena . alloc_slice ( & used_items) , tcx. arena . alloc_slice ( & mentioned_items) )
12541242}
12551243
12561244/// `item` must be already monomorphized.
@@ -1623,4 +1611,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
16231611
16241612pub ( crate ) fn provide ( providers : & mut Providers ) {
16251613 providers. hooks . should_codegen_locally = should_codegen_locally;
1614+ providers. items_of_instance = items_of_instance;
16261615}
0 commit comments