1313//!
1414
1515use crate :: util:: is_within_packed;
16- use rustc_index:: bit_set:: BitSet ;
1716use rustc_middle:: mir:: visit:: Visitor ;
1817use rustc_middle:: mir:: * ;
1918use rustc_middle:: ty:: TyCtxt ;
19+ use rustc_mir_dataflow:: debuginfo:: debuginfo_locals;
2020use rustc_mir_dataflow:: impls:: {
2121 borrowed_locals, LivenessTransferFunction , MaybeTransitiveLiveLocals ,
2222} ;
@@ -26,8 +26,15 @@ use rustc_mir_dataflow::Analysis;
2626///
2727/// The `borrowed` set must be a `BitSet` of all the locals that are ever borrowed in this body. It
2828/// can be generated via the [`borrowed_locals`] function.
29- pub fn eliminate < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > , borrowed : & BitSet < Local > ) {
30- let mut live = MaybeTransitiveLiveLocals :: new ( borrowed)
29+ pub fn eliminate < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
30+ let borrowed_locals = borrowed_locals ( body) ;
31+
32+ // If the user requests complete debuginfo, mark the locals that appear in it as live, so
33+ // we don't remove assignements to them.
34+ let mut always_live = debuginfo_locals ( body) ;
35+ always_live. union ( & borrowed_locals) ;
36+
37+ let mut live = MaybeTransitiveLiveLocals :: new ( & always_live)
3138 . into_engine ( tcx, body)
3239 . iterate_to_fixpoint ( )
3340 . into_results_cursor ( body) ;
@@ -48,7 +55,9 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
4855 for ( index, arg) in args. iter ( ) . enumerate ( ) . rev ( ) {
4956 if let Operand :: Copy ( place) = * arg
5057 && !place. is_indirect ( )
51- && !borrowed. contains ( place. local )
58+ // Do not skip the transformation if the local is in debuginfo, as we do
59+ // not really lose any information for this purpose.
60+ && !borrowed_locals. contains ( place. local )
5261 && !state. contains ( place. local )
5362 // If `place` is a projection of a disaligned field in a packed ADT,
5463 // the move may be codegened as a pointer to that field.
@@ -75,7 +84,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
7584 StatementKind :: Assign ( box ( place, _) )
7685 | StatementKind :: SetDiscriminant { place : box place, .. }
7786 | StatementKind :: Deinit ( box place) => {
78- if !place. is_indirect ( ) && !borrowed . contains ( place. local ) {
87+ if !place. is_indirect ( ) && !always_live . contains ( place. local ) {
7988 live. seek_before_primary_effect ( loc) ;
8089 if !live. get ( ) . contains ( place. local ) {
8190 patch. push ( loc) ;
@@ -126,7 +135,6 @@ impl<'tcx> MirPass<'tcx> for DeadStoreElimination {
126135 }
127136
128137 fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
129- let borrowed = borrowed_locals ( body) ;
130- eliminate ( tcx, body, & borrowed) ;
138+ eliminate ( tcx, body) ;
131139 }
132140}
0 commit comments