13
13
//!
14
14
15
15
use rustc_middle:: bug;
16
- use rustc_middle:: mir:: visit:: Visitor ;
16
+ use rustc_middle:: mir:: visit:: * ;
17
17
use rustc_middle:: mir:: * ;
18
18
use rustc_middle:: ty:: TyCtxt ;
19
19
use rustc_mir_dataflow:: debuginfo:: debuginfo_locals;
20
20
use rustc_mir_dataflow:: impls:: {
21
21
borrowed_locals, LivenessTransferFunction , MaybeTransitiveLiveLocals ,
22
22
} ;
23
23
use rustc_mir_dataflow:: Analysis ;
24
+ use rustc_session:: config:: DebugInfo ;
24
25
25
26
use crate :: util:: is_within_packed;
26
27
@@ -31,10 +32,15 @@ use crate::util::is_within_packed;
31
32
pub fn eliminate < ' tcx > ( tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
32
33
let borrowed_locals = borrowed_locals ( body) ;
33
34
34
- // If the user requests complete debuginfo, mark the locals that appear in it as live, so
35
- // we don't remove assignements to them.
36
- let mut always_live = debuginfo_locals ( body) ;
37
- always_live. union ( & borrowed_locals) ;
35
+ let always_live = if tcx. sess . opts . debuginfo == DebugInfo :: Full {
36
+ // If the user requests complete debuginfo, mark the locals that appear in it as live, so
37
+ // we don't remove assignements to them.
38
+ let mut always_live = debuginfo_locals ( body) ;
39
+ always_live. union ( & borrowed_locals) ;
40
+ always_live
41
+ } else {
42
+ borrowed_locals. clone ( )
43
+ } ;
38
44
39
45
let mut live = MaybeTransitiveLiveLocals :: new ( & always_live)
40
46
. into_engine ( tcx, body)
@@ -89,7 +95,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
89
95
if !place. is_indirect ( ) && !always_live. contains ( place. local ) {
90
96
live. seek_before_primary_effect ( loc) ;
91
97
if !live. get ( ) . contains ( place. local ) {
92
- patch. push ( loc) ;
98
+ patch. push ( ( place . local , loc) ) ;
93
99
}
94
100
}
95
101
}
@@ -114,8 +120,31 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
114
120
}
115
121
116
122
let bbs = body. basic_blocks . as_mut_preserves_cfg ( ) ;
117
- for Location { block, statement_index } in patch {
123
+ for ( local , Location { block, statement_index } ) in patch {
118
124
bbs[ block] . statements [ statement_index] . make_nop ( ) ;
125
+ if bbs[ block] . statements . iter ( ) . all ( |stmt| match stmt. kind {
126
+ StatementKind :: Assign ( box ( place, _) )
127
+ | StatementKind :: SetDiscriminant { place : box place, .. }
128
+ | StatementKind :: Deinit ( box place) => place. local != local,
129
+ _ => true ,
130
+ } ) {
131
+ if let Some ( storage_live_index) = bbs[ block]
132
+ . statements
133
+ . iter ( )
134
+ . take ( statement_index)
135
+ . position ( |stmt| stmt. kind == StatementKind :: StorageLive ( local) )
136
+ {
137
+ if let Some ( storage_dead_index) = bbs[ block]
138
+ . statements
139
+ . iter ( )
140
+ . skip ( statement_index)
141
+ . position ( |stmt| stmt. kind == StatementKind :: StorageDead ( local) )
142
+ {
143
+ bbs[ block] . statements [ storage_live_index] . make_nop ( ) ;
144
+ bbs[ block] . statements [ storage_dead_index + statement_index] . make_nop ( ) ;
145
+ }
146
+ }
147
+ }
119
148
}
120
149
for ( block, argument_index) in call_operands_to_move {
121
150
let TerminatorKind :: Call { ref mut args, .. } = bbs[ block] . terminator_mut ( ) . kind else {
0 commit comments