summaryrefslogtreecommitdiff
path: root/compiler/rustc_mir_dataflow
diff options
context:
space:
mode:
authorTomasz Miąsko <tomasz.miasko@gmail.com>2023-01-05 10:15:33 +0100
committerTomasz Miąsko <tomasz.miasko@gmail.com>2023-02-23 14:05:03 +0100
commit23e3840014e17cd20f6ebe5e268133b3ce5ab1a6 (patch)
treeb93649562063a9b4f68ccb6186aa1aba4c778542 /compiler/rustc_mir_dataflow
parent00eec854f167c546cedd0911f4cc302a54ed0be9 (diff)
downloadrust-23e3840014e17cd20f6ebe5e268133b3ce5ab1a6.tar.gz
Remove dead unwinds before drop elaboration
As a part of drop elaboration, we identify dead unwinds, i.e., unwind edges on a drop terminators which are known to be unreachable, because there is no need to drop anything. Previously, the data flow framework was informed about the dead unwinds, and it assumed those edges are absent from MIR. Unfortunately, the data flow framework wasn't consistent in maintaining this assumption. In particular, if a block was reachable only through a dead unwind edge, its state was propagated to other blocks still. This became an issue in the context of change removes DropAndReplace terminator, since it introduces initialization into cleanup blocks. To avoid this issue, remove unreachable unwind edges before the drop elaboration, and elaborate only blocks that remain reachable.
Diffstat (limited to 'compiler/rustc_mir_dataflow')
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs31
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs32
2 files changed, 5 insertions, 58 deletions
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 077a21fc8af..2ae3ae02fcc 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -1,4 +1,3 @@
-use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets};
use rustc_middle::ty::TyCtxt;
use std::ops::RangeInclusive;
@@ -54,7 +53,6 @@ pub trait Direction {
analysis: &A,
tcx: TyCtxt<'tcx>,
body: &mir::Body<'tcx>,
- dead_unwinds: Option<&BitSet<BasicBlock>>,
exit_state: &mut A::Domain,
block: (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -221,7 +219,6 @@ impl Direction for Backward {
analysis: &A,
_tcx: TyCtxt<'tcx>,
body: &mir::Body<'tcx>,
- dead_unwinds: Option<&BitSet<BasicBlock>>,
exit_state: &mut A::Domain,
(bb, _bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
mut propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -278,20 +275,6 @@ impl Direction for Backward {
}
}
- // Ignore dead unwinds.
- mir::TerminatorKind::Call { cleanup: Some(unwind), .. }
- | mir::TerminatorKind::Assert { cleanup: Some(unwind), .. }
- | mir::TerminatorKind::Drop { unwind: Some(unwind), .. }
- | mir::TerminatorKind::DropAndReplace { unwind: Some(unwind), .. }
- | mir::TerminatorKind::FalseUnwind { unwind: Some(unwind), .. }
- | mir::TerminatorKind::InlineAsm { cleanup: Some(unwind), .. }
- if unwind == bb =>
- {
- if dead_unwinds.map_or(true, |dead| !dead.contains(pred)) {
- propagate(pred, exit_state);
- }
- }
-
_ => propagate(pred, exit_state),
}
}
@@ -304,7 +287,6 @@ struct BackwardSwitchIntEdgeEffectsApplier<'a, 'tcx, D, F> {
exit_state: &'a mut D,
bb: BasicBlock,
propagate: &'a mut F,
-
effects_applied: bool,
}
@@ -484,7 +466,6 @@ impl Direction for Forward {
analysis: &A,
_tcx: TyCtxt<'tcx>,
_body: &mir::Body<'tcx>,
- dead_unwinds: Option<&BitSet<BasicBlock>>,
exit_state: &mut A::Domain,
(bb, bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>),
mut propagate: impl FnMut(BasicBlock, &A::Domain),
@@ -502,9 +483,7 @@ impl Direction for Forward {
| DropAndReplace { target, unwind, value: _, place: _ }
| FalseUnwind { real_target: target, unwind } => {
if let Some(unwind) = unwind {
- if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
- propagate(unwind, exit_state);
- }
+ propagate(unwind, exit_state);
}
propagate(target, exit_state);
@@ -534,9 +513,7 @@ impl Direction for Forward {
fn_span: _,
} => {
if let Some(unwind) = cleanup {
- if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
- propagate(unwind, exit_state);
- }
+ propagate(unwind, exit_state);
}
if let Some(target) = target {
@@ -560,9 +537,7 @@ impl Direction for Forward {
cleanup,
} => {
if let Some(unwind) = cleanup {
- if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) {
- propagate(unwind, exit_state);
- }
+ propagate(unwind, exit_state);
}
if let Some(target) = destination {
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index 6ddbe69e17e..91c3bf0ad21 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -12,7 +12,6 @@ use rustc_ast as ast;
use rustc_data_structures::work_queue::WorkQueue;
use rustc_graphviz as dot;
use rustc_hir::def_id::DefId;
-use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::{self, traversal, BasicBlock};
use rustc_middle::mir::{create_dump_file, dump_enabled};
@@ -78,7 +77,6 @@ where
{
tcx: TyCtxt<'tcx>,
body: &'a mir::Body<'tcx>,
- dead_unwinds: Option<&'a BitSet<BasicBlock>>,
entry_sets: IndexVec<BasicBlock, A::Domain>,
pass_name: Option<&'static str>,
analysis: A,
@@ -154,25 +152,7 @@ where
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
}
- Engine {
- analysis,
- tcx,
- body,
- dead_unwinds: None,
- pass_name: None,
- entry_sets,
- apply_trans_for_block,
- }
- }
-
- /// Signals that we do not want dataflow state to propagate across unwind edges for these
- /// `BasicBlock`s.
- ///
- /// You must take care that `dead_unwinds` does not contain a `BasicBlock` that *can* actually
- /// unwind during execution. Otherwise, your dataflow results will not be correct.
- pub fn dead_unwinds(mut self, dead_unwinds: &'a BitSet<BasicBlock>) -> Self {
- self.dead_unwinds = Some(dead_unwinds);
- self
+ Engine { analysis, tcx, body, pass_name: None, entry_sets, apply_trans_for_block }
}
/// Adds an identifier to the graphviz output for this particular run of a dataflow analysis.
@@ -190,14 +170,7 @@ where
A::Domain: DebugWithContext<A>,
{
let Engine {
- analysis,
- body,
- dead_unwinds,
- mut entry_sets,
- tcx,
- apply_trans_for_block,
- pass_name,
- ..
+ analysis, body, mut entry_sets, tcx, apply_trans_for_block, pass_name, ..
} = self;
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks.len());
@@ -236,7 +209,6 @@ where
&analysis,
tcx,
body,
- dead_unwinds,
&mut state,
(bb, bb_data),
|target: BasicBlock, state: &A::Domain| {