Skip to content

Commit ced813f

Browse files
committed
Auto merge of rust-lang#77466 - Aaron1011:reland-drop-tree, r=matthewjasper
Re-land PR rust-lang#71840 (Rework MIR drop tree lowering) PR rust-lang#71840 was reverted in rust-lang#72989 to fix an LLVM error (rust-lang#72470). That LLVM error no longer occurs with the recent upgrade to LLVM 11 (rust-lang#73526), so let's try re-landing this PR. I've cherry-picked the commits from the original PR (with the exception of the commit blessing test output), making as few modifications as possible. I addressed the rebase fallout in separate commits on top of those. r? `@matthewjasper`
2 parents beb5ae4 + ce8d757 commit ced813f

File tree

81 files changed

+2504
-2748
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+2504
-2748
lines changed

compiler/rustc_mir/src/dataflow/move_paths/builder.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -362,17 +362,18 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
362362
fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
363363
match term.kind {
364364
TerminatorKind::Goto { target: _ }
365+
| TerminatorKind::FalseEdge { .. }
366+
| TerminatorKind::FalseUnwind { .. }
367+
// In some sense returning moves the return place into the current
368+
// call's destination, however, since there are no statements after
369+
// this that could possibly access the return place, this doesn't
370+
// need recording.
371+
| TerminatorKind::Return
365372
| TerminatorKind::Resume
366373
| TerminatorKind::Abort
367374
| TerminatorKind::GeneratorDrop
368-
| TerminatorKind::FalseEdge { .. }
369-
| TerminatorKind::FalseUnwind { .. }
370375
| TerminatorKind::Unreachable => {}
371376

372-
TerminatorKind::Return => {
373-
self.gather_move(Place::return_place());
374-
}
375-
376377
TerminatorKind::Assert { ref cond, .. } => {
377378
self.gather_operand(cond);
378379
}

compiler/rustc_mir/src/util/elaborate_drops.rs

+11-35
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,6 @@ where
231231
.patch_terminator(bb, TerminatorKind::Goto { target: self.succ });
232232
}
233233
DropStyle::Static => {
234-
let loc = self.terminator_loc(bb);
235-
self.elaborator.clear_drop_flag(loc, self.path, DropFlagMode::Deep);
236234
self.elaborator.patch().patch_terminator(
237235
bb,
238236
TerminatorKind::Drop {
@@ -243,9 +241,7 @@ where
243241
);
244242
}
245243
DropStyle::Conditional => {
246-
let unwind = self.unwind; // FIXME(#43234)
247-
let succ = self.succ;
248-
let drop_bb = self.complete_drop(Some(DropFlagMode::Deep), succ, unwind);
244+
let drop_bb = self.complete_drop(self.succ, self.unwind);
249245
self.elaborator
250246
.patch()
251247
.patch_terminator(bb, TerminatorKind::Goto { target: drop_bb });
@@ -317,7 +313,7 @@ where
317313
// our own drop flag.
318314
path: self.path,
319315
}
320-
.complete_drop(None, succ, unwind)
316+
.complete_drop(succ, unwind)
321317
}
322318
}
323319

@@ -346,13 +342,7 @@ where
346342
// Clear the "master" drop flag at the end. This is needed
347343
// because the "master" drop protects the ADT's discriminant,
348344
// which is invalidated after the ADT is dropped.
349-
let (succ, unwind) = (self.succ, self.unwind); // FIXME(#43234)
350-
(
351-
self.drop_flag_reset_block(DropFlagMode::Shallow, succ, unwind),
352-
unwind.map(|unwind| {
353-
self.drop_flag_reset_block(DropFlagMode::Shallow, unwind, Unwind::InCleanup)
354-
}),
355-
)
345+
(self.drop_flag_reset_block(DropFlagMode::Shallow, self.succ, self.unwind), self.unwind)
356346
}
357347

358348
/// Creates a full drop ladder, consisting of 2 connected half-drop-ladders
@@ -884,11 +874,7 @@ where
884874
self.open_drop_for_adt(def, substs)
885875
}
886876
}
887-
ty::Dynamic(..) => {
888-
let unwind = self.unwind; // FIXME(#43234)
889-
let succ = self.succ;
890-
self.complete_drop(Some(DropFlagMode::Deep), succ, unwind)
891-
}
877+
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
892878
ty::Array(ety, size) => {
893879
let size = size.try_eval_usize(self.tcx(), self.elaborator.param_env());
894880
self.open_drop_for_array(ety, size)
@@ -899,20 +885,10 @@ where
899885
}
900886
}
901887

902-
fn complete_drop(
903-
&mut self,
904-
drop_mode: Option<DropFlagMode>,
905-
succ: BasicBlock,
906-
unwind: Unwind,
907-
) -> BasicBlock {
908-
debug!("complete_drop({:?},{:?})", self, drop_mode);
888+
fn complete_drop(&mut self, succ: BasicBlock, unwind: Unwind) -> BasicBlock {
889+
debug!("complete_drop(succ={:?}, unwind={:?})", succ, unwind);
909890

910891
let drop_block = self.drop_block(succ, unwind);
911-
let drop_block = if let Some(mode) = drop_mode {
912-
self.drop_flag_reset_block(mode, drop_block, unwind)
913-
} else {
914-
drop_block
915-
};
916892

917893
self.drop_flag_test_block(drop_block, succ, unwind)
918894
}
@@ -927,6 +903,11 @@ where
927903
) -> BasicBlock {
928904
debug!("drop_flag_reset_block({:?},{:?})", self, mode);
929905

906+
if unwind.is_cleanup() {
907+
// The drop flag isn't read again on the unwind path, so don't
908+
// bother setting it.
909+
return succ;
910+
}
930911
let block = self.new_block(unwind, TerminatorKind::Goto { target: succ });
931912
let block_start = Location { block, statement_index: 0 };
932913
self.elaborator.clear_drop_flag(block_start, self.path, mode);
@@ -1044,11 +1025,6 @@ where
10441025
self.elaborator.patch().new_temp(ty, self.source_info.span)
10451026
}
10461027

1047-
fn terminator_loc(&mut self, bb: BasicBlock) -> Location {
1048-
let body = self.elaborator.body();
1049-
self.elaborator.patch().terminator_loc(body, bb)
1050-
}
1051-
10521028
fn constant_usize(&self, val: u16) -> Operand<'tcx> {
10531029
Operand::Constant(box Constant {
10541030
span: self.source_info.span,

compiler/rustc_mir/src/util/graphviz.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,19 @@ where
111111
write!(w, r#"<table border="0" cellborder="1" cellspacing="0">"#)?;
112112

113113
// Basic block number at the top.
114+
let (blk, bgcolor) = if data.is_cleanup {
115+
(format!("{} (cleanup)", block.index()), "lightblue")
116+
} else {
117+
let color = if dark_mode { "dimgray" } else { "gray" };
118+
(format!("{}", block.index()), color)
119+
};
114120
write!(
115121
w,
116122
r#"<tr><td bgcolor="{bgcolor}" {attrs} colspan="{colspan}">{blk}</td></tr>"#,
117-
bgcolor = if dark_mode { "dimgray" } else { "gray" },
118123
attrs = r#"align="center""#,
119124
colspan = num_cols,
120-
blk = block.index()
125+
blk = blk,
126+
bgcolor = bgcolor
121127
)?;
122128

123129
init(w)?;

compiler/rustc_mir_build/src/build/block.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2828
self.in_opt_scope(opt_destruction_scope.map(|de| (de, source_info)), move |this| {
2929
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
3030
if targeted_by_break {
31-
// This is a `break`-able block
32-
let exit_block = this.cfg.start_new_block();
33-
let block_exit =
34-
this.in_breakable_scope(None, exit_block, destination, |this| {
35-
this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode)
36-
});
37-
this.cfg.goto(unpack!(block_exit), source_info, exit_block);
38-
exit_block.unit()
31+
this.in_breakable_scope(None, destination, span, |this| {
32+
Some(this.ast_block_stmts(
33+
destination,
34+
block,
35+
span,
36+
stmts,
37+
expr,
38+
safety_mode,
39+
))
40+
})
3941
} else {
4042
this.ast_block_stmts(destination, block, span, stmts, expr, safety_mode)
4143
}

compiler/rustc_mir_build/src/build/expr/into.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -140,32 +140,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
140140
// body, even when the exact code in the body cannot unwind
141141

142142
let loop_block = this.cfg.start_new_block();
143-
let exit_block = this.cfg.start_new_block();
144143

145144
// Start the loop.
146145
this.cfg.goto(block, source_info, loop_block);
147146

148-
this.in_breakable_scope(Some(loop_block), exit_block, destination, move |this| {
147+
this.in_breakable_scope(Some(loop_block), destination, expr_span, move |this| {
149148
// conduct the test, if necessary
150149
let body_block = this.cfg.start_new_block();
151-
let diverge_cleanup = this.diverge_cleanup();
152150
this.cfg.terminate(
153151
loop_block,
154152
source_info,
155-
TerminatorKind::FalseUnwind {
156-
real_target: body_block,
157-
unwind: Some(diverge_cleanup),
158-
},
153+
TerminatorKind::FalseUnwind { real_target: body_block, unwind: None },
159154
);
155+
this.diverge_from(loop_block);
160156

161157
// The “return” value of the loop body must always be an unit. We therefore
162158
// introduce a unit temporary as the destination for the loop body.
163159
let tmp = this.get_unit_temp();
164160
// Execute the body, branching back to the test.
165161
let body_block_end = unpack!(this.into(tmp, body_block, body));
166162
this.cfg.goto(body_block_end, source_info, loop_block);
167-
});
168-
exit_block.unit()
163+
164+
// Loops are only exited by `break` expressions.
165+
None
166+
})
169167
}
170168
ExprKind::Call { ty, fun, args, from_hir_call, fn_span } => {
171169
let intrinsic = match *ty.kind() {
@@ -206,7 +204,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
206204
.collect();
207205

208206
let success = this.cfg.start_new_block();
209-
let cleanup = this.diverge_cleanup();
210207

211208
this.record_operands_moved(&args);
212209

@@ -218,7 +215,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
218215
TerminatorKind::Call {
219216
func: fun,
220217
args,
221-
cleanup: Some(cleanup),
218+
cleanup: None,
222219
// FIXME(varkor): replace this with an uninhabitedness-based check.
223220
// This requires getting access to the current module to call
224221
// `tcx.is_ty_uninhabited_from`, which is currently tricky to do.
@@ -231,6 +228,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
231228
fn_span,
232229
},
233230
);
231+
this.diverge_from(block);
234232
success.unit()
235233
}
236234
}
@@ -437,12 +435,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
437435
let scope = this.local_scope();
438436
let value = unpack!(block = this.as_operand(block, scope, value));
439437
let resume = this.cfg.start_new_block();
440-
let cleanup = this.generator_drop_cleanup();
441438
this.cfg.terminate(
442439
block,
443440
source_info,
444-
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: cleanup },
441+
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
445442
);
443+
this.generator_drop_cleanup(block);
446444
resume.unit()
447445
}
448446

compiler/rustc_mir_build/src/build/matches/mod.rs

+5-12
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
228228
outer_source_info: SourceInfo,
229229
fake_borrow_temps: Vec<(Place<'tcx>, Local)>,
230230
) -> BlockAnd<()> {
231-
let match_scope = self.scopes.topmost();
232-
233231
let arm_end_blocks: Vec<_> = arm_candidates
234232
.into_iter()
235233
.map(|(arm, candidate)| {
@@ -250,7 +248,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
250248
let arm_block = this.bind_pattern(
251249
outer_source_info,
252250
candidate,
253-
arm.guard.as_ref().map(|g| (g, match_scope)),
251+
arm.guard.as_ref(),
254252
&fake_borrow_temps,
255253
scrutinee_span,
256254
Some(arm.scope),
@@ -287,7 +285,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
287285
&mut self,
288286
outer_source_info: SourceInfo,
289287
candidate: Candidate<'_, 'tcx>,
290-
guard: Option<(&Guard<'tcx>, region::Scope)>,
288+
guard: Option<&Guard<'tcx>>,
291289
fake_borrow_temps: &Vec<(Place<'tcx>, Local)>,
292290
scrutinee_span: Span,
293291
arm_scope: Option<region::Scope>,
@@ -1592,7 +1590,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
15921590
&mut self,
15931591
candidate: Candidate<'pat, 'tcx>,
15941592
parent_bindings: &[(Vec<Binding<'tcx>>, Vec<Ascription<'tcx>>)],
1595-
guard: Option<(&Guard<'tcx>, region::Scope)>,
1593+
guard: Option<&Guard<'tcx>>,
15961594
fake_borrows: &Vec<(Place<'tcx>, Local)>,
15971595
scrutinee_span: Span,
15981596
schedule_drops: bool,
@@ -1704,7 +1702,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17041702
// the reference that we create for the arm.
17051703
// * So we eagerly create the reference for the arm and then take a
17061704
// reference to that.
1707-
if let Some((guard, region_scope)) = guard {
1705+
if let Some(guard) = guard {
17081706
let tcx = self.hir.tcx();
17091707
let bindings = parent_bindings
17101708
.iter()
@@ -1748,12 +1746,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
17481746
unreachable
17491747
});
17501748
let outside_scope = self.cfg.start_new_block();
1751-
self.exit_scope(
1752-
source_info.span,
1753-
region_scope,
1754-
otherwise_post_guard_block,
1755-
outside_scope,
1756-
);
1749+
self.exit_top_scope(otherwise_post_guard_block, outside_scope, source_info);
17571750
self.false_edges(
17581751
outside_scope,
17591752
otherwise_block,

compiler/rustc_mir_build/src/build/matches/test.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
418418
let bool_ty = self.hir.bool_ty();
419419
let eq_result = self.temp(bool_ty, source_info.span);
420420
let eq_block = self.cfg.start_new_block();
421-
let cleanup = self.diverge_cleanup();
422421
self.cfg.terminate(
423422
block,
424423
source_info,
@@ -436,11 +435,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
436435
}),
437436
args: vec![val, expect],
438437
destination: Some((eq_result, eq_block)),
439-
cleanup: Some(cleanup),
438+
cleanup: None,
440439
from_hir_call: false,
441440
fn_span: source_info.span,
442441
},
443442
);
443+
self.diverge_from(block);
444444

445445
if let [success_block, fail_block] = *make_target_blocks(self) {
446446
// check the result

0 commit comments

Comments
 (0)