Skip to content

Commit afe8a41

Browse files
committed
Temp: Cleanup 6 (Separate exit trees)
1 parent d88faaa commit afe8a41

File tree

2 files changed

+35
-31
lines changed

2 files changed

+35
-31
lines changed

src/librustc_mir/build/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
719719
fn_span: span,
720720
arg_count,
721721
is_generator,
722-
scopes: scope::Scopes::new(is_generator),
722+
scopes: scope::Scopes::new(),
723723
block_context: BlockContext::new(),
724724
source_scopes: IndexVec::new(),
725725
source_scope: OUTERMOST_SOURCE_SCOPE,

src/librustc_mir/build/scope.rs

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,10 @@ struct BreakableScope<'tcx> {
153153
/// The destination of the loop/block expression itself (i.e., where to put
154154
/// the result of a `break` or `return` expression)
155155
break_destination: Place<'tcx>,
156-
/// Drops that happen on the
157-
drops: DropTree,
156+
/// Drops that happen on the `break`/`return` path.
157+
break_drops: DropTree,
158+
/// Drops that happen on the `continue` path.
159+
continue_drops: Option<DropTree>,
158160
}
159161

160162
/// The target of an expression that breaks out of a scope
@@ -170,10 +172,8 @@ rustc_index::newtype_index! {
170172
}
171173

172174
const ROOT_NODE: DropIdx = DropIdx::from_u32_const(0);
173-
const CONTINUE_NODE: DropIdx = DropIdx::from_u32_const(1);
174175

175-
/// A tree (usually, sometimes this is a forest of two trees) of drops that we
176-
/// have deferred lowering. It's used for:
176+
/// A tree of drops that we have deferred lowering. It's used for:
177177
///
178178
/// * Drops on unwind paths
179179
/// * Drops on generator drop paths (when a suspended generator is dropped)
@@ -187,12 +187,10 @@ struct DropTree {
187187
drops: IndexVec<DropIdx, (DropData, DropIdx)>,
188188
/// Map for finding the inverse of the `next_drop` relation:
189189
///
190-
/// `previous_drops[(next_drop[i], drops[i].local, drops[i].kind] == i`
190+
/// `previous_drops[(drops[i].1, drops[i].0.local, drops[i].0.kind] == i`
191191
previous_drops: FxHashMap<(DropIdx, Local, DropKind), DropIdx>,
192192
/// Edges into the `DropTree` that need to be added once it's lowered.
193193
entry_points: Vec<(DropIdx, BasicBlock)>,
194-
/// The first non-root nodes in the forest.
195-
first_non_root: DropIdx,
196194
}
197195

198196
impl Scope {
@@ -223,18 +221,17 @@ trait DropTreeBuilder<'tcx> {
223221
}
224222

225223
impl DropTree {
226-
fn new(num_roots: usize) -> Self {
224+
fn new() -> Self {
227225
let fake_source_info = SourceInfo { span: DUMMY_SP, scope: OUTERMOST_SOURCE_SCOPE };
228226
let fake_data = DropData {
229227
source_info: fake_source_info,
230228
local: Local::MAX,
231229
kind: DropKind::Storage,
232230
};
233231
let drop_idx = DropIdx::MAX;
234-
let drops = IndexVec::from_elem_n((fake_data, drop_idx), num_roots);
232+
let drops = IndexVec::from_elem_n((fake_data, drop_idx), 1);
235233
Self {
236234
drops,
237-
first_non_root: DropIdx::from_usize(num_roots),
238235
entry_points: Vec::new(),
239236
previous_drops: FxHashMap::default(),
240237
}
@@ -248,6 +245,7 @@ impl DropTree {
248245
}
249246

250247
fn add_entry(&mut self, from: BasicBlock, to: DropIdx) {
248+
debug_assert!(to < self.drops.next_index());
251249
self.entry_points.push((to, from));
252250
}
253251

@@ -285,9 +283,11 @@ impl DropTree {
285283
}
286284

287285
let mut needs_block = IndexVec::from_elem(Block::None, &self.drops);
288-
if self.first_non_root > CONTINUE_NODE {
289-
// `continue` already has its own node.
290-
needs_block[CONTINUE_NODE] = Block::Own;
286+
if blocks[ROOT_NODE].is_some() {
287+
// In some cases (such as drops for `continue`) the root node
288+
// already has a block. In this case, make sure that we don't
289+
// override it.
290+
needs_block[ROOT_NODE] = Block::Own;
291291
}
292292

293293
// Sort so that we only need to check the last
@@ -315,7 +315,7 @@ impl DropTree {
315315
if let DropKind::Value = drop_data.0.kind {
316316
needs_block[drop_data.1] = Block::Own;
317317
} else {
318-
if drop_idx >= self.first_non_root {
318+
if drop_idx != ROOT_NODE {
319319
match &mut needs_block[drop_data.1] {
320320
pred @ Block::None => *pred = Block::Shares(drop_idx),
321321
pred @ Block::Shares(_) => *pred = Block::Own,
@@ -351,7 +351,7 @@ impl DropTree {
351351
);
352352
}
353353
// Root nodes don't correspond to a drop.
354-
DropKind::Storage if drop_idx < self.first_non_root => {}
354+
DropKind::Storage if drop_idx == ROOT_NODE => {}
355355
DropKind::Storage => {
356356
let stmt = Statement {
357357
source_info: drop_data.0.source_info,
@@ -370,12 +370,12 @@ impl DropTree {
370370
}
371371

372372
impl<'tcx> Scopes<'tcx> {
373-
pub(crate) fn new(is_generator: bool) -> Self {
373+
pub(crate) fn new() -> Self {
374374
Self {
375375
scopes: Vec::new(),
376376
breakable_scopes: Vec::new(),
377-
unwind_drops: DropTree::new(1),
378-
generator_drops: DropTree::new(is_generator as usize),
377+
unwind_drops: DropTree::new(),
378+
generator_drops: DropTree::new(),
379379
}
380380
}
381381

@@ -436,13 +436,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
436436
let scope = BreakableScope {
437437
region_scope,
438438
break_destination,
439-
drops: DropTree::new(1 + loop_block.is_some() as usize),
439+
break_drops: DropTree::new(),
440+
continue_drops: loop_block.map(|_| DropTree::new()),
440441
};
441442
self.scopes.breakable_scopes.push(scope);
442443
let normal_exit_block = f(self);
443444
let breakable_scope = self.scopes.breakable_scopes.pop().unwrap();
444445
assert!(breakable_scope.region_scope == region_scope);
445-
let break_block = self.build_exit_tree(breakable_scope.drops, loop_block);
446+
let break_block = self.build_exit_tree(breakable_scope.break_drops, None);
447+
breakable_scope.continue_drops.map(|drops| {
448+
self.build_exit_tree(drops, loop_block);
449+
});
446450
match (normal_exit_block, break_block) {
447451
(Some(block), None) | (None, Some(block)) => block,
448452
(None, None) => self.cfg.start_new_block().unit(),
@@ -602,10 +606,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
602606

603607
let region_scope = self.scopes.breakable_scopes[break_index].region_scope;
604608
let scope_index = self.scopes.scope_index(region_scope, span);
605-
let exited_scopes = &self.scopes.scopes[scope_index + 1..];
606-
let scope_drops = exited_scopes.iter().flat_map(|scope| &scope.drops);
609+
let drops = if destination.is_some() {
610+
&mut self.scopes.breakable_scopes[break_index].break_drops
611+
} else {
612+
self.scopes.breakable_scopes[break_index].continue_drops.as_mut().unwrap()
613+
};
607614

608-
let drops = &mut self.scopes.breakable_scopes[break_index].drops;
609615
let mut drop_idx = DropIdx::from_u32(destination.is_none() as u32);
610616
for drop in scope_drops {
611617
drop_idx = drops.add_drop(*drop, drop_idx);
@@ -1103,15 +1109,13 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
11031109
continue_block: Option<BasicBlock>,
11041110
) -> Option<BlockAnd<()>> {
11051111
let mut blocks = IndexVec::from_elem(None, &drops.drops);
1106-
if continue_block.is_some() {
1107-
blocks[CONTINUE_NODE] = continue_block;
1108-
}
1112+
blocks[ROOT_NODE] = continue_block;
1113+
11091114
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
11101115
if drops.drops.iter().any(|(drop, _)| drop.kind == DropKind::Value) {
11111116
let unwind_target = self.diverge_cleanup();
1112-
let num_roots = drops.first_non_root.index();
1113-
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, num_roots);
1114-
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(num_roots) {
1117+
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
1118+
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) {
11151119
match drop_data.0.kind {
11161120
DropKind::Storage => {
11171121
if self.is_generator {

0 commit comments

Comments
 (0)