@@ -67,25 +67,24 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
67
67
} ;
68
68
let un_derefer = UnDerefer { tcx : tcx, derefer_sidetable : side_table } ;
69
69
let elaborate_patch = {
70
- let body = & * body;
71
70
let env = MoveDataParamEnv { move_data, param_env } ;
72
- let dead_unwinds = find_dead_unwinds ( tcx, body, & env, & un_derefer) ;
71
+ remove_dead_unwinds ( tcx, body, & env, & un_derefer) ;
73
72
74
73
let inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
75
74
. into_engine ( tcx, body)
76
- . dead_unwinds ( & dead_unwinds)
77
75
. pass_name ( "elaborate_drops" )
78
76
. iterate_to_fixpoint ( )
79
77
. into_results_cursor ( body) ;
80
78
81
79
let uninits = MaybeUninitializedPlaces :: new ( tcx, body, & env)
82
80
. mark_inactive_variants_as_uninit ( )
83
81
. into_engine ( tcx, body)
84
- . dead_unwinds ( & dead_unwinds)
85
82
. pass_name ( "elaborate_drops" )
86
83
. iterate_to_fixpoint ( )
87
84
. into_results_cursor ( body) ;
88
85
86
+ let reachable = traversal:: reachable_as_bitset ( body) ;
87
+
89
88
ElaborateDropsCtxt {
90
89
tcx,
91
90
body,
@@ -94,6 +93,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
94
93
drop_flags : Default :: default ( ) ,
95
94
patch : MirPatch :: new ( body) ,
96
95
un_derefer : un_derefer,
96
+ reachable,
97
97
}
98
98
. elaborate ( )
99
99
} ;
@@ -102,22 +102,21 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
102
102
}
103
103
}
104
104
105
- /// Returns the set of basic blocks whose unwind edges are known
106
- /// to not be reachable, because they are `drop` terminators
105
+ /// Removes unwind edges which are known to be unreachable, because they are in `drop` terminators
107
106
/// that can't drop anything.
108
- fn find_dead_unwinds < ' tcx > (
107
+ fn remove_dead_unwinds < ' tcx > (
109
108
tcx : TyCtxt < ' tcx > ,
110
- body : & Body < ' tcx > ,
109
+ body : & mut Body < ' tcx > ,
111
110
env : & MoveDataParamEnv < ' tcx > ,
112
111
und : & UnDerefer < ' tcx > ,
113
- ) -> BitSet < BasicBlock > {
114
- debug ! ( "find_dead_unwinds ({:?})" , body. span) ;
112
+ ) {
113
+ debug ! ( "remove_dead_unwinds ({:?})" , body. span) ;
115
114
// We only need to do this pass once, because unwind edges can only
116
115
// reach cleanup blocks, which can't have unwind edges themselves.
117
- let mut dead_unwinds = BitSet :: new_empty ( body . basic_blocks . len ( ) ) ;
116
+ let mut dead_unwinds = Vec :: new ( ) ;
118
117
let mut flow_inits = MaybeInitializedPlaces :: new ( tcx, body, & env)
119
118
. into_engine ( tcx, body)
120
- . pass_name ( "find_dead_unwinds " )
119
+ . pass_name ( "remove_dead_unwinds " )
121
120
. iterate_to_fixpoint ( )
122
121
. into_results_cursor ( body) ;
123
122
for ( bb, bb_data) in body. basic_blocks . iter_enumerated ( ) {
@@ -129,16 +128,16 @@ fn find_dead_unwinds<'tcx>(
129
128
_ => continue ,
130
129
} ;
131
130
132
- debug ! ( "find_dead_unwinds @ {:?}: {:?}" , bb, bb_data) ;
131
+ debug ! ( "remove_dead_unwinds @ {:?}: {:?}" , bb, bb_data) ;
133
132
134
133
let LookupResult :: Exact ( path) = env. move_data . rev_lookup . find ( place. as_ref ( ) ) else {
135
- debug ! ( "find_dead_unwinds : has parent; skipping" ) ;
134
+ debug ! ( "remove_dead_unwinds : has parent; skipping" ) ;
136
135
continue ;
137
136
} ;
138
137
139
138
flow_inits. seek_before_primary_effect ( body. terminator_loc ( bb) ) ;
140
139
debug ! (
141
- "find_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}" ,
140
+ "remove_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}" ,
142
141
bb,
143
142
place,
144
143
path,
@@ -150,13 +149,22 @@ fn find_dead_unwinds<'tcx>(
150
149
maybe_live |= flow_inits. contains ( child) ;
151
150
} ) ;
152
151
153
- debug ! ( "find_dead_unwinds @ {:?}: maybe_live={}" , bb, maybe_live) ;
152
+ debug ! ( "remove_dead_unwinds @ {:?}: maybe_live={}" , bb, maybe_live) ;
154
153
if !maybe_live {
155
- dead_unwinds. insert ( bb) ;
154
+ dead_unwinds. push ( bb) ;
156
155
}
157
156
}
158
157
159
- dead_unwinds
158
+ if dead_unwinds. is_empty ( ) {
159
+ return ;
160
+ }
161
+
162
+ let basic_blocks = body. basic_blocks . as_mut ( ) ;
163
+ for & bb in dead_unwinds. iter ( ) {
164
+ if let Some ( unwind) = basic_blocks[ bb] . terminator_mut ( ) . unwind_mut ( ) {
165
+ * unwind = None ;
166
+ }
167
+ }
160
168
}
161
169
162
170
struct InitializationData < ' mir , ' tcx > {
@@ -290,6 +298,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
290
298
drop_flags : FxHashMap < MovePathIndex , Local > ,
291
299
patch : MirPatch < ' tcx > ,
292
300
un_derefer : UnDerefer < ' tcx > ,
301
+ reachable : BitSet < BasicBlock > ,
293
302
}
294
303
295
304
impl < ' b , ' tcx > ElaborateDropsCtxt < ' b , ' tcx > {
@@ -329,6 +338,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
329
338
330
339
fn collect_drop_flags ( & mut self ) {
331
340
for ( bb, data) in self . body . basic_blocks . iter_enumerated ( ) {
341
+ if !self . reachable . contains ( bb) {
342
+ continue ;
343
+ }
332
344
let terminator = data. terminator ( ) ;
333
345
let place = match terminator. kind {
334
346
TerminatorKind :: Drop { ref place, .. }
@@ -384,6 +396,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
384
396
385
397
fn elaborate_drops ( & mut self ) {
386
398
for ( bb, data) in self . body . basic_blocks . iter_enumerated ( ) {
399
+ if !self . reachable . contains ( bb) {
400
+ continue ;
401
+ }
387
402
let loc = Location { block : bb, statement_index : data. statements . len ( ) } ;
388
403
let terminator = data. terminator ( ) ;
389
404
@@ -541,6 +556,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
541
556
542
557
fn drop_flags_for_fn_rets ( & mut self ) {
543
558
for ( bb, data) in self . body . basic_blocks . iter_enumerated ( ) {
559
+ if !self . reachable . contains ( bb) {
560
+ continue ;
561
+ }
544
562
if let TerminatorKind :: Call {
545
563
destination, target : Some ( tgt) , cleanup : Some ( _) , ..
546
564
} = data. terminator ( ) . kind
@@ -576,6 +594,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
576
594
// clobbered before they are read.
577
595
578
596
for ( bb, data) in self . body . basic_blocks . iter_enumerated ( ) {
597
+ if !self . reachable . contains ( bb) {
598
+ continue ;
599
+ }
579
600
debug ! ( "drop_flags_for_locs({:?})" , data) ;
580
601
for i in 0 ..( data. statements . len ( ) + 1 ) {
581
602
debug ! ( "drop_flag_for_locs: stmt {}" , i) ;
0 commit comments