Skip to content

Commit cc4dd6f

Browse files
committed
Auto merge of rust-lang#100089 - JakobDegen:no-invalidate-visitor, r=tmiasko
Add option to `mir::MutVisitor` to not invalidate CFG. This also applies that option to some uses of the visitor. I had considered a design more similar to rust-lang#100087 in which we detect if the CFG needs to be invalidated, but that is more difficult with the visitor API and so I decided against it. Another alternative to this design is to offer an API for "saving" and "restoring" CFG caches across arbitrary code. Such an API is more general, and so we may eventually want it anyway, but it seems overkill for this use case. r? `@tmiasko`
2 parents 5af97e8 + 7547084 commit cc4dd6f

File tree

8 files changed

+101
-72
lines changed

8 files changed

+101
-72
lines changed

compiler/rustc_middle/src/mir/visit.rs

+92-63
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ macro_rules! make_mir_visitor {
8080
self.super_body(body);
8181
}
8282

83+
extra_body_methods!($($mutability)?);
84+
8385
fn visit_basic_block_data(
8486
&mut self,
8587
block: BasicBlock,
@@ -287,63 +289,7 @@ macro_rules! make_mir_visitor {
287289
&mut self,
288290
body: &$($mutability)? Body<'tcx>,
289291
) {
290-
let span = body.span;
291-
if let Some(gen) = &$($mutability)? body.generator {
292-
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
293-
self.visit_ty(
294-
yield_ty,
295-
TyContext::YieldTy(SourceInfo::outermost(span))
296-
);
297-
}
298-
}
299-
300-
// for best performance, we want to use an iterator rather
301-
// than a for-loop, to avoid calling `body::Body::invalidate` for
302-
// each basic block.
303-
#[allow(unused_macro_rules)]
304-
macro_rules! basic_blocks {
305-
(mut) => (body.basic_blocks_mut().iter_enumerated_mut());
306-
() => (body.basic_blocks().iter_enumerated());
307-
}
308-
for (bb, data) in basic_blocks!($($mutability)?) {
309-
self.visit_basic_block_data(bb, data);
310-
}
311-
312-
for scope in &$($mutability)? body.source_scopes {
313-
self.visit_source_scope_data(scope);
314-
}
315-
316-
self.visit_ty(
317-
$(& $mutability)? body.return_ty(),
318-
TyContext::ReturnTy(SourceInfo::outermost(body.span))
319-
);
320-
321-
for local in body.local_decls.indices() {
322-
self.visit_local_decl(local, & $($mutability)? body.local_decls[local]);
323-
}
324-
325-
#[allow(unused_macro_rules)]
326-
macro_rules! type_annotations {
327-
(mut) => (body.user_type_annotations.iter_enumerated_mut());
328-
() => (body.user_type_annotations.iter_enumerated());
329-
}
330-
331-
for (index, annotation) in type_annotations!($($mutability)?) {
332-
self.visit_user_type_annotation(
333-
index, annotation
334-
);
335-
}
336-
337-
for var_debug_info in &$($mutability)? body.var_debug_info {
338-
self.visit_var_debug_info(var_debug_info);
339-
}
340-
341-
self.visit_span($(& $mutability)? body.span);
342-
343-
for const_ in &$($mutability)? body.required_consts {
344-
let location = START_BLOCK.start_location();
345-
self.visit_constant(const_, location);
346-
}
292+
super_body!(self, body, $($mutability, true)?);
347293
}
348294

349295
fn super_basic_block_data(&mut self,
@@ -982,12 +928,7 @@ macro_rules! make_mir_visitor {
982928
body: &$($mutability)? Body<'tcx>,
983929
location: Location
984930
) {
985-
#[allow(unused_macro_rules)]
986-
macro_rules! basic_blocks {
987-
(mut) => (body.basic_blocks_mut());
988-
() => (body.basic_blocks());
989-
}
990-
let basic_block = & $($mutability)? basic_blocks!($($mutability)?)[location.block];
931+
let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block];
991932
if basic_block.statements.len() == location.statement_index {
992933
if let Some(ref $($mutability)? terminator) = basic_block.terminator {
993934
self.visit_terminator(terminator, location)
@@ -1002,6 +943,94 @@ macro_rules! make_mir_visitor {
1002943
}
1003944
}
1004945

946+
macro_rules! basic_blocks {
947+
($body:ident, mut, true) => {
948+
$body.basic_blocks.as_mut()
949+
};
950+
($body:ident, mut, false) => {
951+
$body.basic_blocks.as_mut_preserves_cfg()
952+
};
953+
($body:ident,) => {
954+
$body.basic_blocks()
955+
};
956+
}
957+
958+
macro_rules! basic_blocks_iter {
959+
($body:ident, mut, $invalidate:tt) => {
960+
basic_blocks!($body, mut, $invalidate).iter_enumerated_mut()
961+
};
962+
($body:ident,) => {
963+
basic_blocks!($body,).iter_enumerated()
964+
};
965+
}
966+
967+
macro_rules! extra_body_methods {
968+
(mut) => {
969+
fn visit_body_preserves_cfg(&mut self, body: &mut Body<'tcx>) {
970+
self.super_body_preserves_cfg(body);
971+
}
972+
973+
fn super_body_preserves_cfg(&mut self, body: &mut Body<'tcx>) {
974+
super_body!(self, body, mut, false);
975+
}
976+
};
977+
() => {};
978+
}
979+
980+
macro_rules! super_body {
981+
($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => {
982+
let span = $body.span;
983+
if let Some(gen) = &$($mutability)? $body.generator {
984+
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
985+
$self.visit_ty(
986+
yield_ty,
987+
TyContext::YieldTy(SourceInfo::outermost(span))
988+
);
989+
}
990+
}
991+
992+
for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) {
993+
$self.visit_basic_block_data(bb, data);
994+
}
995+
996+
for scope in &$($mutability)? $body.source_scopes {
997+
$self.visit_source_scope_data(scope);
998+
}
999+
1000+
$self.visit_ty(
1001+
$(& $mutability)? $body.return_ty(),
1002+
TyContext::ReturnTy(SourceInfo::outermost($body.span))
1003+
);
1004+
1005+
for local in $body.local_decls.indices() {
1006+
$self.visit_local_decl(local, & $($mutability)? $body.local_decls[local]);
1007+
}
1008+
1009+
#[allow(unused_macro_rules)]
1010+
macro_rules! type_annotations {
1011+
(mut) => ($body.user_type_annotations.iter_enumerated_mut());
1012+
() => ($body.user_type_annotations.iter_enumerated());
1013+
}
1014+
1015+
for (index, annotation) in type_annotations!($($mutability)?) {
1016+
$self.visit_user_type_annotation(
1017+
index, annotation
1018+
);
1019+
}
1020+
1021+
for var_debug_info in &$($mutability)? $body.var_debug_info {
1022+
$self.visit_var_debug_info(var_debug_info);
1023+
}
1024+
1025+
$self.visit_span($(& $mutability)? $body.span);
1026+
1027+
for const_ in &$($mutability)? $body.required_consts {
1028+
let location = START_BLOCK.start_location();
1029+
$self.visit_constant(const_, location);
1030+
}
1031+
}
1032+
}
1033+
10051034
macro_rules! visit_place_fns {
10061035
(mut) => {
10071036
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;

compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub struct DeleteNonCodegenStatements<'tcx> {
3333
impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
3434
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
3535
let mut delete = DeleteNonCodegenStatements { tcx };
36-
delete.visit_body(body);
36+
delete.visit_body_preserves_cfg(body);
3737
body.user_type_annotations.raw.clear();
3838

3939
for decl in &mut body.local_decls {

compiler/rustc_mir_transform/src/const_prop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
951951
}
952952

953953
fn visit_body(&mut self, body: &mut Body<'tcx>) {
954-
for (bb, data) in body.basic_blocks_mut().iter_enumerated_mut() {
954+
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
955955
self.visit_basic_block_data(bb, data);
956956
}
957957
}

compiler/rustc_mir_transform/src/deref_separator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
9090
let patch = MirPatch::new(body);
9191
let mut checker = DerefChecker { tcx, patcher: patch, local_decls: body.local_decls.clone() };
9292

93-
for (bb, data) in body.basic_blocks_mut().iter_enumerated_mut() {
93+
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
9494
checker.visit_basic_block_data(bb, data);
9595
}
9696

compiler/rustc_mir_transform/src/elaborate_box_derefs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
116116
ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };
117117

118118
for (block, BasicBlockData { statements, terminator, .. }) in
119-
body.basic_blocks.as_mut().iter_enumerated_mut()
119+
body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut()
120120
{
121121
let mut index = 0;
122122
for statement in statements {

compiler/rustc_mir_transform/src/nrvo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
5353
def_id, returned_local
5454
);
5555

56-
RenameToReturnPlace { tcx, to_rename: returned_local }.visit_body(body);
56+
RenameToReturnPlace { tcx, to_rename: returned_local }.visit_body_preserves_cfg(body);
5757

5858
// Clean up the `NOP`s we inserted for statements made useless by our renaming.
59-
for block_data in body.basic_blocks_mut() {
59+
for block_data in body.basic_blocks.as_mut_preserves_cfg() {
6060
block_data.statements.retain(|stmt| stmt.kind != mir::StatementKind::Nop);
6161
}
6262

compiler/rustc_mir_transform/src/reveal_all.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ impl<'tcx> MirPass<'tcx> for RevealAll {
1919
}
2020

2121
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
22-
RevealAllVisitor { tcx, param_env }.visit_body(body);
22+
RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
2323
}
2424
}
2525

compiler/rustc_mir_transform/src/simplify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ pub fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
412412
if map.iter().any(Option::is_none) {
413413
// Update references to all vars and tmps now
414414
let mut updater = LocalUpdater { map, tcx };
415-
updater.visit_body(body);
415+
updater.visit_body_preserves_cfg(body);
416416

417417
body.local_decls.shrink_to_fit();
418418
}
@@ -548,7 +548,7 @@ fn remove_unused_definitions(used_locals: &mut UsedLocals, body: &mut Body<'_>)
548548
while modified {
549549
modified = false;
550550

551-
for data in body.basic_blocks_mut() {
551+
for data in body.basic_blocks.as_mut_preserves_cfg() {
552552
// Remove unnecessary StorageLive and StorageDead annotations.
553553
data.statements.retain(|statement| {
554554
let keep = match &statement.kind {

0 commit comments

Comments
 (0)