Skip to content

Commit a707b15

Browse files
committed
Auto merge of #66703 - matthewjasper:drop-trees, r=<try>
[PERF] further drop changes r? @ghost
2 parents b56b239 + f09a177 commit a707b15

Some content is hidden

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

48 files changed

+1709
-1403
lines changed

src/librustc/mir/mod.rs

+26-6
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,18 @@ pub enum TerminatorKind<'tcx> {
10881088
/// Indicates a terminator that can never be reached.
10891089
Unreachable,
10901090

1091-
/// Drop the `Place`.
1092-
Drop { location: Place<'tcx>, target: BasicBlock, unwind: Option<BasicBlock> },
1091+
/// Drop the `Place`, possibly conditioned on a flag being true.
1092+
Drop {
1093+
location: Place<'tcx>,
1094+
/// Whether to drop the value.
1095+
///
1096+
/// Before drop elaboration this is always `None. After drop elaboration
1097+
/// If this is `None` then the drop is unconditional, otherwise the drop
1098+
/// is only evaluated when the flag is true.
1099+
flag: Option<Place<'tcx>>,
1100+
target: BasicBlock,
1101+
unwind: Option<BasicBlock>,
1102+
},
10931103

10941104
/// Drop the `Place` and assign the new value over it. This ensures
10951105
/// that the assignment to `P` occurs *even if* the destructor for
@@ -1464,7 +1474,10 @@ impl<'tcx> TerminatorKind<'tcx> {
14641474
Abort => write!(fmt, "abort"),
14651475
Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value),
14661476
Unreachable => write!(fmt, "unreachable"),
1467-
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
1477+
Drop { ref location, flag: Some(ref flag), .. } => {
1478+
write!(fmt, "if {:?} drop({:?})", flag, location)
1479+
}
1480+
Drop { ref location, flag: None, .. } => write!(fmt, "drop({:?})", location),
14681481
DropAndReplace { ref location, ref value, .. } => {
14691482
write!(fmt, "replace({:?} <- {:?})", location, value)
14701483
}
@@ -2967,8 +2980,13 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
29672980
values: values.clone(),
29682981
targets: targets.clone(),
29692982
},
2970-
Drop { ref location, target, unwind } => {
2971-
Drop { location: location.fold_with(folder), target, unwind }
2983+
Drop { ref location, ref flag, target, unwind } => {
2984+
Drop {
2985+
location: location.fold_with(folder),
2986+
flag: flag.fold_with(folder),
2987+
target,
2988+
unwind,
2989+
}
29722990
}
29732991
DropAndReplace { ref location, ref value, target, unwind } => DropAndReplace {
29742992
location: location.fold_with(folder),
@@ -3025,7 +3043,9 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
30253043
SwitchInt { ref discr, switch_ty, .. } => {
30263044
discr.visit_with(visitor) || switch_ty.visit_with(visitor)
30273045
}
3028-
Drop { ref location, .. } => location.visit_with(visitor),
3046+
Drop { ref location, ref flag, .. } => {
3047+
location.visit_with(visitor) || flag.visit_with(visitor)
3048+
},
30293049
DropAndReplace { ref location, ref value, .. } => {
30303050
location.visit_with(visitor) || value.visit_with(visitor)
30313051
}

src/librustc/mir/visit.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -432,14 +432,22 @@ macro_rules! make_mir_visitor {
432432

433433
TerminatorKind::Drop {
434434
location,
435+
flag,
435436
target: _,
436437
unwind: _,
437438
} => {
438439
self.visit_place(
439440
location,
440441
PlaceContext::MutatingUse(MutatingUseContext::Drop),
441-
source_location
442+
source_location,
442443
);
444+
if let Some(flag) = flag {
445+
self.visit_place(
446+
flag,
447+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
448+
source_location,
449+
);
450+
}
443451
}
444452

445453
TerminatorKind::DropAndReplace {

src/librustc/ty/instance.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,14 @@ impl<'tcx> InstanceDef<'tcx> {
166166
return true
167167
}
168168
if let ty::InstanceDef::DropGlue(..) = *self {
169-
// Drop glue wants to be instantiated at every codegen
169+
// Drop glue generally wants to be instantiated at every codegen
170170
// unit, but without an #[inline] hint. We should make this
171171
// available to normal end-users.
172-
return true
172+
//
173+
// When compiling with incremental, we can generate a lot of
174+
// codegen units. Including drop glue into all of them has a
175+
// considerable compile time cost.
176+
return tcx.sess.opts.incremental.is_none();
173177
}
174178
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
175179
}

src/librustc_codegen_ssa/mir/block.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -321,8 +321,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
321321
helper: TerminatorCodegenHelper<'b, 'tcx>,
322322
mut bx: Bx,
323323
location: &mir::Place<'tcx>,
324+
flag: &Option<mir::Place<'tcx>>,
324325
target: mir::BasicBlock,
325326
unwind: Option<mir::BasicBlock>,
327+
source_info: mir::SourceInfo,
326328
) {
327329
let ty = location.ty(self.mir, bx.tcx()).ty;
328330
let ty = self.monomorphize(&ty);
@@ -335,6 +337,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
335337
return
336338
}
337339

340+
if let Some(flag) = flag {
341+
let flag = self.codegen_consume(&mut bx, &flag.as_ref()).immediate();
342+
let lltarget = helper.llblock(self, target);
343+
let drop_block = self.new_block("drop");
344+
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
345+
bx.cond_br(flag, drop_block.llbb(), lltarget);
346+
bx = drop_block;
347+
self.set_debug_loc(&mut bx, source_info);
348+
}
349+
338350
let place = self.codegen_place(&mut bx, &location.as_ref());
339351
let (args1, args2);
340352
let mut args = if let Some(llextra) = place.llextra {
@@ -854,8 +866,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
854866
bx.unreachable();
855867
}
856868

857-
mir::TerminatorKind::Drop { ref location, target, unwind } => {
858-
self.codegen_drop_terminator(helper, bx, location, target, unwind);
869+
mir::TerminatorKind::Drop { ref location, ref flag, target, unwind } => {
870+
self.codegen_drop_terminator(
871+
helper,
872+
bx,
873+
location,
874+
flag,
875+
target,
876+
unwind,
877+
terminator.source_info,
878+
);
859879
}
860880

861881
mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => {

src/librustc_mir/borrow_check/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
618618
}
619619
TerminatorKind::Drop {
620620
location: ref drop_place,
621+
flag: _,
621622
target: _,
622623
unwind: _,
623624
} => {

src/librustc_mir/borrow_check/nll/invalidation.rs

+1
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
155155
}
156156
TerminatorKind::Drop {
157157
location: ref drop_place,
158+
flag: _,
158159
target: _,
159160
unwind: _,
160161
} => {

src/librustc_mir/build/block.rs

+45-29
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder};
22
use crate::build::ForGuard::OutsideGuard;
33
use crate::build::matches::ArmHasGuard;
44
use crate::hair::*;
5+
use rustc::middle::region;
56
use rustc::mir::*;
67
use rustc::hir;
78
use syntax_pos::Span;
89

910
impl<'a, 'tcx> Builder<'a, 'tcx> {
10-
pub fn ast_block(&mut self,
11-
destination: &Place<'tcx>,
12-
block: BasicBlock,
13-
ast_block: &'tcx hir::Block,
14-
source_info: SourceInfo)
15-
-> BlockAnd<()> {
11+
pub fn ast_block(
12+
&mut self,
13+
destination: &Place<'tcx>,
14+
scope: Option<region::Scope>,
15+
block: BasicBlock,
16+
ast_block: &'tcx hir::Block,
17+
source_info: SourceInfo,
18+
) -> BlockAnd<()> {
1619
let Block {
1720
region_scope,
1821
opt_destruction_scope,
@@ -21,37 +24,50 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
2124
expr,
2225
targeted_by_break,
2326
safety_mode
24-
} =
25-
self.hir.mirror(ast_block);
27+
} = self.hir.mirror(ast_block);
2628
self.in_opt_scope(opt_destruction_scope.map(|de|(de, source_info)), move |this| {
2729
this.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
2830
if targeted_by_break {
29-
// This is a `break`-able block
30-
let exit_block = this.cfg.start_new_block();
31-
let block_exit = this.in_breakable_scope(
32-
None, exit_block, destination.clone(), |this| {
33-
this.ast_block_stmts(destination, block, span, stmts, expr,
34-
safety_mode)
35-
});
36-
this.cfg.terminate(unpack!(block_exit), source_info,
37-
TerminatorKind::Goto { target: exit_block });
38-
exit_block.unit()
31+
this.in_breakable_scope(
32+
None,
33+
destination.clone(),
34+
scope,
35+
span,
36+
|this| Some(this.ast_block_stmts(
37+
destination,
38+
scope,
39+
block,
40+
span,
41+
stmts,
42+
expr,
43+
safety_mode,
44+
)),
45+
)
3946
} else {
40-
this.ast_block_stmts(destination, block, span, stmts, expr,
41-
safety_mode)
47+
this.ast_block_stmts(
48+
destination,
49+
scope,
50+
block,
51+
span,
52+
stmts,
53+
expr,
54+
safety_mode,
55+
)
4256
}
4357
})
4458
})
4559
}
4660

47-
fn ast_block_stmts(&mut self,
48-
destination: &Place<'tcx>,
49-
mut block: BasicBlock,
50-
span: Span,
51-
stmts: Vec<StmtRef<'tcx>>,
52-
expr: Option<ExprRef<'tcx>>,
53-
safety_mode: BlockSafety)
54-
-> BlockAnd<()> {
61+
fn ast_block_stmts(
62+
&mut self,
63+
destination: &Place<'tcx>,
64+
scope: Option<region::Scope>,
65+
mut block: BasicBlock,
66+
span: Span,
67+
stmts: Vec<StmtRef<'tcx>>,
68+
expr: Option<ExprRef<'tcx>>,
69+
safety_mode: BlockSafety,
70+
) -> BlockAnd<()> {
5571
let this = self;
5672

5773
// This convoluted structure is to avoid using recursion as we walk down a list
@@ -177,7 +193,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
177193
this.block_context.currently_ignores_tail_results();
178194
this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored });
179195

180-
unpack!(block = this.into(destination, block, expr));
196+
unpack!(block = this.into(destination, scope, block, expr));
181197
let popped = this.block_context.pop();
182198

183199
assert!(popped.map_or(false, |bf|bf.is_tail_expr()));

src/librustc_mir/build/expr/as_rvalue.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
130130
this.cfg
131131
.push_assign(block, source_info, &Place::from(result), box_);
132132

133-
// initialize the box contents:
133+
// Initialize the box contents. No scope is needed since the
134+
// `Box` is already scheduled to be dropped.
134135
unpack!(
135136
block = this.into(
136137
&this.hir.tcx().mk_place_deref(Place::from(result)),
137-
block, value
138+
None,
139+
block,
140+
value,
138141
)
139142
);
140143
block.and(Rvalue::Use(Operand::Move(Place::from(result))))
@@ -257,14 +260,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
257260
ExprKind::Yield { value } => {
258261
let value = unpack!(block = this.as_operand(block, scope, value));
259262
let resume = this.cfg.start_new_block();
260-
let cleanup = this.generator_drop_cleanup();
263+
this.generator_drop_cleanup(block);
261264
this.cfg.terminate(
262265
block,
263266
source_info,
264267
TerminatorKind::Yield {
265268
value: value,
266269
resume: resume,
267-
drop: cleanup,
270+
drop: None,
268271
},
269272
);
270273
resume.and(this.unit_rvalue())

src/librustc_mir/build/expr/as_temp.rs

+1-10
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
114114
}
115115
}
116116

117-
unpack!(block = this.into(temp_place, block, expr));
118-
119-
if let Some(temp_lifetime) = temp_lifetime {
120-
this.schedule_drop(
121-
expr_span,
122-
temp_lifetime,
123-
temp,
124-
DropKind::Value,
125-
);
126-
}
117+
unpack!(block = this.into(temp_place, temp_lifetime, block, expr));
127118

128119
block.and(temp)
129120
}

0 commit comments

Comments
 (0)