34
34
35
35
use std:: fmt:: { Debug , Formatter } ;
36
36
37
- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
37
+ use rustc_data_structures:: fx:: FxHashMap ;
38
38
use rustc_index:: vec:: IndexVec ;
39
39
use rustc_middle:: mir:: visit:: { MutatingUseContext , PlaceContext , Visitor } ;
40
40
use rustc_middle:: mir:: * ;
@@ -587,7 +587,8 @@ impl Map {
587
587
filter : impl FnMut ( Ty < ' tcx > ) -> bool ,
588
588
) -> Self {
589
589
let mut map = Self :: new ( ) ;
590
- map. register_with_filter ( tcx, body, filter, & escaped_places ( body) ) ;
590
+ let exclude = excluded_locals ( body) ;
591
+ map. register_with_filter ( tcx, body, filter, & exclude) ;
591
592
debug ! ( "registered {} places ({} nodes in total)" , map. value_count, map. places. len( ) ) ;
592
593
map
593
594
}
@@ -598,19 +599,14 @@ impl Map {
598
599
tcx : TyCtxt < ' tcx > ,
599
600
body : & Body < ' tcx > ,
600
601
mut filter : impl FnMut ( Ty < ' tcx > ) -> bool ,
601
- exclude : & FxHashSet < Place < ' tcx > > ,
602
+ exclude : & IndexVec < Local , bool > ,
602
603
) {
603
604
// We use this vector as stack, pushing and popping projections.
604
605
let mut projection = Vec :: new ( ) ;
605
606
for ( local, decl) in body. local_decls . iter_enumerated ( ) {
606
- self . register_with_filter_rec (
607
- tcx,
608
- local,
609
- & mut projection,
610
- decl. ty ,
611
- & mut filter,
612
- exclude,
613
- ) ;
607
+ if !exclude[ local] {
608
+ self . register_with_filter_rec ( tcx, local, & mut projection, decl. ty , & mut filter) ;
609
+ }
614
610
}
615
611
}
616
612
@@ -624,17 +620,10 @@ impl Map {
624
620
projection : & mut Vec < PlaceElem < ' tcx > > ,
625
621
ty : Ty < ' tcx > ,
626
622
filter : & mut impl FnMut ( Ty < ' tcx > ) -> bool ,
627
- exclude : & FxHashSet < Place < ' tcx > > ,
628
623
) {
629
- let place = Place { local, projection : tcx. intern_place_elems ( projection) } ;
630
- if exclude. contains ( & place) {
631
- // This will also exclude all projections of the excluded place.
632
- return ;
633
- }
634
-
635
624
// Note: The framework supports only scalars for now.
636
625
if filter ( ty) && ty. is_scalar ( ) {
637
- trace ! ( "registering place: {:?}" , place ) ;
626
+ // trace!("registering place {:?}", PlaceRef { local, projection: &*projection } );
638
627
639
628
// We know that the projection only contains trackable elements.
640
629
let place = self . make_place ( local, projection) . unwrap ( ) ;
@@ -653,7 +642,7 @@ impl Map {
653
642
return ;
654
643
}
655
644
projection. push ( PlaceElem :: Field ( field, ty) ) ;
656
- self . register_with_filter_rec ( tcx, local, projection, ty, filter, exclude ) ;
645
+ self . register_with_filter_rec ( tcx, local, projection, ty, filter) ;
657
646
projection. pop ( ) ;
658
647
} ) ;
659
648
}
@@ -835,27 +824,27 @@ fn iter_fields<'tcx>(
835
824
}
836
825
}
837
826
838
- /// Returns all places, that have their reference or address taken.
839
- ///
840
- /// This includes shared references, and also drops and `InlineAsm` out parameters.
841
- fn escaped_places < ' tcx > ( body : & Body < ' tcx > ) -> FxHashSet < Place < ' tcx > > {
842
- struct Collector < ' tcx > {
843
- result : FxHashSet < Place < ' tcx > > ,
827
+ /// Returns all locals with projections that have their reference or address taken.
828
+ fn excluded_locals < ' tcx > ( body : & Body < ' tcx > ) -> IndexVec < Local , bool > {
829
+ struct Collector {
830
+ result : IndexVec < Local , bool > ,
844
831
}
845
832
846
- impl < ' tcx > Visitor < ' tcx > for Collector < ' tcx > {
833
+ impl < ' tcx > Visitor < ' tcx > for Collector {
847
834
fn visit_place ( & mut self , place : & Place < ' tcx > , context : PlaceContext , _location : Location ) {
848
835
if context. is_borrow ( )
849
836
|| context. is_address_of ( )
850
837
|| context. is_drop ( )
851
838
|| context == PlaceContext :: MutatingUse ( MutatingUseContext :: AsmOutput )
852
839
{
853
- self . result . insert ( * place) ;
840
+ // A pointer to a place could be used to access other places with the same local,
841
+ // hence we have to exclude the local completely.
842
+ self . result [ place. local ] = true ;
854
843
}
855
844
}
856
845
}
857
846
858
- let mut collector = Collector { result : FxHashSet :: default ( ) } ;
847
+ let mut collector = Collector { result : IndexVec :: from_elem ( false , & body . local_decls ) } ;
859
848
collector. visit_body ( body) ;
860
849
collector. result
861
850
}
0 commit comments