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