Skip to content

Commit 7547084

Browse files
committed
Add option to mir::MutVisitor to not invalidate CFG.
This also applies that option to some uses of the visitor
1 parent 9ee22ff commit 7547084

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)