Skip to content

Commit 26c37d7

Browse files
committed
Revert "Remove separation between generator_drop and unwind paths"
This reverts commit 26a7228f0fd5929f2134ac36180eb1e8ff5e16e3.
1 parent e2cde91 commit 26c37d7

File tree

1 file changed

+53
-28
lines changed

1 file changed

+53
-28
lines changed

src/librustc_mir/build/scope.rs

+53-28
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,7 @@ pub struct Scope<'tcx> {
124124
/// The cache for drop chain on "generator drop" exit.
125125
cached_generator_drop: Option<BasicBlock>,
126126

127-
/// The cache for drop chain on "unwind" exit. This block
128-
/// contains code to run the current drop and all the preceding
129-
/// drops (i.e., those having lower index in Drop’s Scope drop
130-
/// array)
127+
/// The cache for drop chain on "unwind" exit.
131128
cached_unwind: CachedBlock,
132129
}
133130

@@ -144,7 +141,21 @@ struct DropData<'tcx> {
144141
}
145142

146143
#[derive(Debug, Default, Clone, Copy)]
147-
pub(crate) struct CachedBlock(Option<BasicBlock>);
144+
pub(crate) struct CachedBlock {
145+
/// The cached block for the cleanups-on-diverge path. This block
146+
/// contains code to run the current drop and all the preceding
147+
/// drops (i.e., those having lower index in Drop’s Scope drop
148+
/// array)
149+
unwind: Option<BasicBlock>,
150+
151+
/// The cached block for unwinds during cleanups-on-generator-drop path
152+
///
153+
/// This is split from the standard unwind path here to prevent drop
154+
/// elaboration from creating drop flags that would have to be captured
155+
/// by the generator. I'm not sure how important this optimization is,
156+
/// but it is here.
157+
generator_drop: Option<BasicBlock>,
158+
}
148159

149160
#[derive(Debug)]
150161
pub(crate) enum DropKind {
@@ -170,15 +181,24 @@ pub struct BreakableScope<'tcx> {
170181

171182
impl CachedBlock {
172183
fn invalidate(&mut self) {
173-
self.0 = None;
184+
self.generator_drop = None;
185+
self.unwind = None;
174186
}
175187

176-
fn get(&self) -> Option<BasicBlock> {
177-
self.0
188+
fn get(&self, generator_drop: bool) -> Option<BasicBlock> {
189+
if generator_drop {
190+
self.generator_drop
191+
} else {
192+
self.unwind
193+
}
178194
}
179195

180-
fn ref_mut(&mut self) -> &mut Option<BasicBlock> {
181-
&mut self.0
196+
fn ref_mut(&mut self, generator_drop: bool) -> &mut Option<BasicBlock> {
197+
if generator_drop {
198+
&mut self.generator_drop
199+
} else {
200+
&mut self.unwind
201+
}
182202
}
183203
}
184204

@@ -358,7 +378,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
358378
assert_eq!(scope.region_scope, region_scope.0);
359379

360380
let unwind_to = self.scopes.last().and_then(|next_scope| {
361-
next_scope.cached_unwind.get()
381+
next_scope.cached_unwind.get(false)
362382
}).unwrap_or_else(|| self.resume_block());
363383

364384
unpack!(block = build_scope_drops(
@@ -367,6 +387,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
367387
block,
368388
unwind_to,
369389
self.arg_count,
390+
false,
370391
));
371392

372393
block.unit()
@@ -421,7 +442,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
421442
}
422443
};
423444

424-
let unwind_to = next_scope.cached_unwind.get().unwrap_or_else(|| {
445+
let unwind_to = next_scope.cached_unwind.get(false).unwrap_or_else(|| {
425446
debug_assert!(!may_panic, "cached block not present?");
426447
START_BLOCK
427448
});
@@ -432,6 +453,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
432453
block,
433454
unwind_to,
434455
self.arg_count,
456+
false,
435457
));
436458

437459
scope = next_scope;
@@ -448,7 +470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
448470
/// None indicates there’s no cleanup to do at this point.
449471
pub fn generator_drop_cleanup(&mut self) -> Option<BasicBlock> {
450472
// Fill in the cache for unwinds
451-
self.diverge_cleanup_gen();
473+
self.diverge_cleanup_gen(true);
452474

453475
let src_info = self.scopes[0].source_info(self.fn_span);
454476
let resume_block = self.resume_block();
@@ -474,7 +496,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
474496
};
475497

476498
let unwind_to = scopes.peek().as_ref().map(|scope| {
477-
scope.cached_unwind.get().unwrap_or_else(|| {
499+
scope.cached_unwind.get(true).unwrap_or_else(|| {
478500
span_bug!(src_info.span, "cached block not present?")
479501
})
480502
}).unwrap_or(resume_block);
@@ -485,6 +507,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
485507
block,
486508
unwind_to,
487509
self.arg_count,
510+
true,
488511
));
489512
}
490513

@@ -737,7 +760,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
737760
/// This path terminates in Resume. Returns the start of the path.
738761
/// See module comment for more details.
739762
pub fn diverge_cleanup(&mut self) -> BasicBlock {
740-
self.diverge_cleanup_gen()
763+
self.diverge_cleanup_gen(false)
741764
}
742765

743766
fn resume_block(&mut self) -> BasicBlock {
@@ -756,7 +779,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
756779
}
757780
}
758781

759-
fn diverge_cleanup_gen(&mut self) -> BasicBlock {
782+
fn diverge_cleanup_gen(&mut self, generator_drop: bool) -> BasicBlock {
760783
// Build up the drops in **reverse** order. The end result will
761784
// look like:
762785
//
@@ -770,15 +793,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
770793

771794
// Find the last cached block
772795
let (mut target, first_uncached) = if let Some(cached_index) = self.scopes.iter()
773-
.rposition(|scope| scope.cached_unwind.get().is_some()) {
774-
(self.scopes[cached_index].cached_unwind.get().unwrap(), cached_index + 1)
796+
.rposition(|scope| scope.cached_unwind.get(generator_drop).is_some()) {
797+
(self.scopes[cached_index].cached_unwind.get(generator_drop).unwrap(), cached_index + 1)
775798
} else {
776799
(self.resume_block(), 0)
777800
};
778801

779802
for scope in self.scopes[first_uncached..].iter_mut() {
780803
target = build_diverge_scope(&mut self.cfg, scope.region_scope_span,
781-
scope, target, self.is_generator);
804+
scope, target, generator_drop, self.is_generator);
782805
}
783806

784807
target
@@ -858,6 +881,7 @@ fn build_scope_drops<'tcx>(
858881
mut block: BasicBlock,
859882
last_unwind_to: BasicBlock,
860883
arg_count: usize,
884+
generator_drop: bool,
861885
) -> BlockAnd<()> {
862886
debug!("build_scope_drops({:?} -> {:?}", block, scope);
863887

@@ -878,7 +902,7 @@ fn build_scope_drops<'tcx>(
878902

879903
let mut unwind_blocks = scope.drops.iter().rev().filter_map(|drop_data| {
880904
if let DropKind::Value { cached_block } = drop_data.kind {
881-
Some(cached_block.get().unwrap_or_else(|| {
905+
Some(cached_block.get(generator_drop).unwrap_or_else(|| {
882906
span_bug!(drop_data.span, "cached block not present?")
883907
}))
884908
} else {
@@ -922,12 +946,13 @@ fn build_scope_drops<'tcx>(
922946
block.unit()
923947
}
924948

925-
fn build_diverge_scope(cfg: &mut CFG<'tcx>,
926-
span: Span,
927-
scope: &mut Scope<'tcx>,
928-
mut target: BasicBlock,
929-
is_generator: bool)
930-
-> BasicBlock
949+
fn build_diverge_scope<'tcx>(cfg: &mut CFG<'tcx>,
950+
span: Span,
951+
scope: &mut Scope<'tcx>,
952+
mut target: BasicBlock,
953+
generator_drop: bool,
954+
is_generator: bool)
955+
-> BasicBlock
931956
{
932957
// Build up the drops in **reverse** order. The end result will
933958
// look like:
@@ -979,7 +1004,7 @@ fn build_diverge_scope(cfg: &mut CFG<'tcx>,
9791004
}
9801005
DropKind::Storage => {}
9811006
DropKind::Value { ref mut cached_block } => {
982-
let cached_block = cached_block.ref_mut();
1007+
let cached_block = cached_block.ref_mut(generator_drop);
9831008
target = if let Some(cached_block) = *cached_block {
9841009
storage_deads.clear();
9851010
target_built_by_us = false;
@@ -1002,7 +1027,7 @@ fn build_diverge_scope(cfg: &mut CFG<'tcx>,
10021027
};
10031028
}
10041029
push_storage_deads(cfg, &mut target, &mut storage_deads, target_built_by_us, source_scope);
1005-
*scope.cached_unwind.ref_mut() = Some(target);
1030+
*scope.cached_unwind.ref_mut(generator_drop) = Some(target);
10061031

10071032
assert!(storage_deads.is_empty());
10081033
debug!("build_diverge_scope({:?}, {:?}) = {:?}", scope, span, target);

0 commit comments

Comments
 (0)