38
38
//! It must also not contain any indexing projections, since those take an arbitrary `Local` as
39
39
//! the index, and that local might only be initialized shortly before `dest` is used.
40
40
//!
41
- //! Subtle case: If `dest` is a, or projects through a union, then we have to make sure that there
42
- //! remains an assignment to it, since that sets the "active field" of the union. But if `src` is
43
- //! a ZST, it might not be initialized, so there might not be any use of it before the assignment,
44
- //! and performing the optimization would simply delete the assignment, leaving `dest`
45
- //! uninitialized.
46
- //!
47
41
//! * `src` must be a bare `Local` without any indirections or field projections (FIXME: Is this a
48
42
//! fundamental restriction or just current impl state?). It can be copied or moved by the
49
43
//! assignment.
@@ -103,7 +97,6 @@ use rustc_index::{
103
97
bit_set:: { BitMatrix , BitSet } ,
104
98
vec:: IndexVec ,
105
99
} ;
106
- use rustc_middle:: mir:: tcx:: PlaceTy ;
107
100
use rustc_middle:: mir:: visit:: { MutVisitor , PlaceContext , Visitor } ;
108
101
use rustc_middle:: mir:: { dump_mir, PassWhere } ;
109
102
use rustc_middle:: mir:: {
@@ -135,7 +128,7 @@ impl<'tcx> MirPass<'tcx> for DestinationPropagation {
135
128
fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
136
129
let def_id = body. source . def_id ( ) ;
137
130
138
- let candidates = find_candidates ( tcx , body) ;
131
+ let candidates = find_candidates ( body) ;
139
132
if candidates. is_empty ( ) {
140
133
debug ! ( "{:?}: no dest prop candidates, done" , def_id) ;
141
134
return ;
@@ -803,9 +796,8 @@ struct CandidateAssignment<'tcx> {
803
796
/// comment) and also throw out assignments that involve a local that has its address taken or is
804
797
/// otherwise ineligible (eg. locals used as array indices are ignored because we cannot propagate
805
798
/// arbitrary places into array indices).
806
- fn find_candidates < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & Body < ' tcx > ) -> Vec < CandidateAssignment < ' tcx > > {
799
+ fn find_candidates < ' tcx > ( body : & Body < ' tcx > ) -> Vec < CandidateAssignment < ' tcx > > {
807
800
let mut visitor = FindAssignments {
808
- tcx,
809
801
body,
810
802
candidates : Vec :: new ( ) ,
811
803
ever_borrowed_locals : ever_borrowed_locals ( body) ,
@@ -816,7 +808,6 @@ fn find_candidates<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> Vec<CandidateA
816
808
}
817
809
818
810
struct FindAssignments < ' a , ' tcx > {
819
- tcx : TyCtxt < ' tcx > ,
820
811
body : & ' a Body < ' tcx > ,
821
812
candidates : Vec < CandidateAssignment < ' tcx > > ,
822
813
ever_borrowed_locals : BitSet < Local > ,
@@ -845,10 +836,11 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
845
836
return ;
846
837
}
847
838
848
- // Can't optimize if both locals ever have their address taken (can introduce
849
- // aliasing).
850
- // FIXME: This can be smarter and take `StorageDead` into account (which
851
- // invalidates borrows).
839
+ // Can't optimize if either local ever has their address taken. This optimization does
840
+ // liveness analysis only based on assignments, and a local can be live even if its
841
+ // never assigned to again, because a reference to it might be live.
842
+ // FIXME: This can be smarter and take `StorageDead` into account (which invalidates
843
+ // borrows).
852
844
if self . ever_borrowed_locals . contains ( dest. local )
853
845
|| self . ever_borrowed_locals . contains ( src. local )
854
846
{
@@ -862,22 +854,11 @@ impl<'tcx> Visitor<'tcx> for FindAssignments<'_, 'tcx> {
862
854
return ;
863
855
}
864
856
865
- // Handle the "subtle case" described above by rejecting any `dest` that is or
866
- // projects through a union.
867
- let mut place_ty = PlaceTy :: from_ty ( self . body . local_decls [ dest. local ] . ty ) ;
868
- if place_ty. ty . is_union ( ) {
869
- return ;
870
- }
871
857
for elem in dest. projection {
872
858
if let PlaceElem :: Index ( _) = elem {
873
859
// `dest` contains an indexing projection.
874
860
return ;
875
861
}
876
-
877
- place_ty = place_ty. projection_ty ( self . tcx , elem) ;
878
- if place_ty. ty . is_union ( ) {
879
- return ;
880
- }
881
862
}
882
863
883
864
self . candidates . push ( CandidateAssignment {
0 commit comments