@@ -145,6 +145,10 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
145
145
state. visit_basic_block_data ( bb, data) ;
146
146
}
147
147
148
+ for var_debug_info in body. var_debug_info . iter_mut ( ) {
149
+ state. visit_var_debug_info ( var_debug_info) ;
150
+ }
151
+
148
152
// For each local that is reused (`y` above), we remove its storage statements do avoid any
149
153
// difficulty. Those locals are SSA, so should be easy to optimize by LLVM without storage
150
154
// statements.
@@ -865,10 +869,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
865
869
866
870
/// Simplify the projection chain if we know better.
867
871
#[ instrument( level = "trace" , skip( self ) ) ]
868
- fn simplify_place_projection ( & mut self , place : & mut Place < ' tcx > , location : Location ) {
872
+ fn simplify_place_projection ( & mut self , place : & mut Place < ' tcx > , location : Option < Location > ) {
869
873
// If the projection is indirect, we treat the local as a value, so can replace it with
870
874
// another local.
871
- if place. is_indirect_first_projection ( )
875
+ if let Some ( location) = location
876
+ && place. is_indirect_first_projection ( )
872
877
&& let Some ( base) = self . locals [ place. local ]
873
878
&& let Some ( new_local) = self . try_as_local ( base, location)
874
879
&& place. local != new_local
@@ -890,7 +895,8 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
890
895
{
891
896
projection. to_mut ( ) [ i] =
892
897
ProjectionElem :: ConstantIndex { offset, min_length, from_end : false } ;
893
- } else if let Some ( new_idx_local) = self . try_as_local ( idx, location)
898
+ } else if let Some ( location) = location
899
+ && let Some ( new_idx_local) = self . try_as_local ( idx, location)
894
900
&& idx_local != new_idx_local
895
901
{
896
902
projection. to_mut ( ) [ i] = ProjectionElem :: Index ( new_idx_local) ;
@@ -912,7 +918,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
912
918
fn compute_place_value (
913
919
& mut self ,
914
920
place : Place < ' tcx > ,
915
- location : Location ,
921
+ location : Option < Location > ,
916
922
) -> Result < VnIndex , PlaceRef < ' tcx > > {
917
923
// Invariant: `place` and `place_ref` point to the same value, even if they point to
918
924
// different memory locations.
@@ -923,7 +929,9 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
923
929
// Invariant: `value` has type `place_ty`, with optional downcast variant if needed.
924
930
let mut place_ty = PlaceTy :: from_ty ( self . local_decls [ place. local ] . ty ) ;
925
931
for ( index, proj) in place. projection . iter ( ) . enumerate ( ) {
926
- if let Some ( local) = self . try_as_local ( value, location) {
932
+ if let Some ( location) = location
933
+ && let Some ( local) = self . try_as_local ( value, location)
934
+ {
927
935
// Both `local` and `Place { local: place.local, projection: projection[..index] }`
928
936
// hold the same value. Therefore, following place holds the value in the original
929
937
// `place`.
@@ -948,13 +956,14 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
948
956
fn simplify_place_value (
949
957
& mut self ,
950
958
place : & mut Place < ' tcx > ,
951
- location : Location ,
959
+ location : Option < Location > ,
952
960
) -> Option < VnIndex > {
953
961
self . simplify_place_projection ( place, location) ;
954
962
955
963
match self . compute_place_value ( * place, location) {
956
964
Ok ( value) => {
957
- if let Some ( new_place) = self . try_as_place ( value, location, true )
965
+ if let Some ( location) = location
966
+ && let Some ( new_place) = self . try_as_place ( value, location, true )
958
967
&& ( new_place. local != place. local
959
968
|| new_place. projection . len ( ) < place. projection . len ( ) )
960
969
{
@@ -985,7 +994,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
985
994
let value = match * operand {
986
995
Operand :: Constant ( ref constant) => self . insert_constant ( constant. const_ ) ,
987
996
Operand :: Copy ( ref mut place) | Operand :: Move ( ref mut place) => {
988
- self . simplify_place_value ( place, location) ?
997
+ self . simplify_place_value ( place, Some ( location) ) ?
989
998
}
990
999
} ;
991
1000
if let Some ( const_) = self . try_as_constant ( value) {
@@ -1019,11 +1028,11 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
1019
1028
Rvalue :: NullaryOp ( op, ty) => Value :: NullaryOp ( op, ty) ,
1020
1029
Rvalue :: Aggregate ( ..) => return self . simplify_aggregate ( lhs, rvalue, location) ,
1021
1030
Rvalue :: Ref ( _, borrow_kind, ref mut place) => {
1022
- self . simplify_place_projection ( place, location) ;
1031
+ self . simplify_place_projection ( place, Some ( location) ) ;
1023
1032
return self . new_pointer ( * place, AddressKind :: Ref ( borrow_kind) ) ;
1024
1033
}
1025
1034
Rvalue :: RawPtr ( mutbl, ref mut place) => {
1026
- self . simplify_place_projection ( place, location) ;
1035
+ self . simplify_place_projection ( place, Some ( location) ) ;
1027
1036
return self . new_pointer ( * place, AddressKind :: Address ( mutbl) ) ;
1028
1037
}
1029
1038
Rvalue :: WrapUnsafeBinder ( ref mut op, _) => {
@@ -1042,7 +1051,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> {
1042
1051
return self . simplify_unary ( op, arg_op, location) ;
1043
1052
}
1044
1053
Rvalue :: Discriminant ( ref mut place) => {
1045
- let place = self . simplify_place_value ( place, location) ?;
1054
+ let place = self . simplify_place_value ( place, Some ( location) ) ?;
1046
1055
if let Some ( discr) = self . simplify_discriminant ( place) {
1047
1056
return Some ( discr) ;
1048
1057
}
@@ -1852,8 +1861,21 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
1852
1861
self . tcx
1853
1862
}
1854
1863
1864
+ fn visit_var_debug_info ( & mut self , var_debug_info : & mut VarDebugInfo < ' tcx > ) {
1865
+ match & mut var_debug_info. value {
1866
+ VarDebugInfoContents :: Const ( _) => { }
1867
+ VarDebugInfoContents :: Place ( place) => {
1868
+ if let Some ( value) = self . simplify_place_value ( place, None )
1869
+ && let Some ( constant) = self . try_as_constant ( value)
1870
+ {
1871
+ var_debug_info. value = VarDebugInfoContents :: Const ( constant) ;
1872
+ }
1873
+ }
1874
+ }
1875
+ }
1876
+
1855
1877
fn visit_place ( & mut self , place : & mut Place < ' tcx > , context : PlaceContext , location : Location ) {
1856
- self . simplify_place_projection ( place, location) ;
1878
+ self . simplify_place_projection ( place, Some ( location) ) ;
1857
1879
if context. is_mutating_use ( ) && place. is_indirect ( ) {
1858
1880
// Non-local mutation maybe invalidate deref.
1859
1881
self . invalidate_derefs ( ) ;
@@ -1872,7 +1894,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_, 'tcx> {
1872
1894
rvalue : & mut Rvalue < ' tcx > ,
1873
1895
location : Location ,
1874
1896
) {
1875
- self . simplify_place_projection ( lhs, location) ;
1897
+ self . simplify_place_projection ( lhs, Some ( location) ) ;
1876
1898
1877
1899
let value = self . simplify_rvalue ( lhs, rvalue, location) ;
1878
1900
if let Some ( value) = value {
0 commit comments