Make MIR basic blocks field public
This makes it possible to mutably borrow different fields of the MIR body without resorting to methods like `basic_blocks_local_decls_mut_and_var_debug_info`. To preserve validity of control flow graph caches in the presence of modifications, a new struct `BasicBlocks` wraps together basic blocks and control flow graph caches. The `BasicBlocks` dereferences to `IndexVec<BasicBlock, BasicBlockData>`. On the other hand a mutable access requires explicit `as_mut()` call.
This commit is contained in:
parent
fac8fa5672
commit
c9dd1d9983
21 changed files with 213 additions and 195 deletions
|
@ -91,7 +91,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
|
|||
super::add_call_guards::AllCallEdges.run_pass(tcx, body);
|
||||
|
||||
let (span, arg_count) = (body.span, body.arg_count);
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
let basic_blocks = body.basic_blocks.as_mut();
|
||||
let local_decls = &body.local_decls;
|
||||
let needs_retag = |place: &Place<'tcx>| {
|
||||
// FIXME: Instead of giving up for unstable places, we should introduce
|
||||
// a temporary and retag on that.
|
||||
|
|
|
@ -80,7 +80,7 @@ impl CoverageGraph {
|
|||
IndexVec<BasicCoverageBlock, BasicCoverageBlockData>,
|
||||
IndexVec<BasicBlock, Option<BasicCoverageBlock>>,
|
||||
) {
|
||||
let num_basic_blocks = mir_body.num_nodes();
|
||||
let num_basic_blocks = mir_body.basic_blocks.len();
|
||||
let mut bcbs = IndexVec::with_capacity(num_basic_blocks);
|
||||
let mut bb_to_bcb = IndexVec::from_elem_n(None, num_basic_blocks);
|
||||
|
||||
|
|
|
@ -321,7 +321,8 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn mir_to_initial_sorted_coverage_spans(&self) -> Vec<CoverageSpan> {
|
||||
let mut initial_spans = Vec::<CoverageSpan>::with_capacity(self.mir_body.num_nodes() * 2);
|
||||
let mut initial_spans =
|
||||
Vec::<CoverageSpan>::with_capacity(self.mir_body.basic_blocks.len() * 2);
|
||||
for (bcb, bcb_data) in self.basic_coverage_blocks.iter_enumerated() {
|
||||
initial_spans.extend(self.bcb_to_initial_coverage_spans(bcb, bcb_data));
|
||||
}
|
||||
|
|
|
@ -222,6 +222,7 @@ fn print_mir_graphviz(name: &str, mir_body: &Body<'_>) {
|
|||
bb,
|
||||
debug::term_type(&data.terminator().kind),
|
||||
mir_body
|
||||
.basic_blocks
|
||||
.successors(bb)
|
||||
.map(|successor| { format!(" {:?} -> {:?};", bb, successor) })
|
||||
.join("\n")
|
||||
|
|
|
@ -66,7 +66,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
|
|||
return;
|
||||
}
|
||||
|
||||
let bbs = body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate().0;
|
||||
let bbs = body.basic_blocks.as_mut_preserves_cfg();
|
||||
for Location { block, statement_index } in patch {
|
||||
bbs[block].statements[statement_index].make_nop();
|
||||
}
|
||||
|
|
|
@ -11,9 +11,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
|
|||
}
|
||||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let (basic_blocks, local_decls, _) =
|
||||
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
|
||||
let local_decls = &*local_decls;
|
||||
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
|
||||
for bb in basic_blocks {
|
||||
bb.expand_statements(|stmt| {
|
||||
// FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL).
|
||||
|
@ -38,7 +36,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
|
|||
Some(expand_aggregate(
|
||||
lhs,
|
||||
operands.into_iter().map(|op| {
|
||||
let ty = op.ty(local_decls, tcx);
|
||||
let ty = op.ty(&body.local_decls, tcx);
|
||||
(op, ty)
|
||||
}),
|
||||
*kind,
|
||||
|
|
|
@ -110,13 +110,13 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
|
|||
|
||||
let patch = MirPatch::new(body);
|
||||
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
let local_decls = &mut body.local_decls;
|
||||
|
||||
let mut visitor =
|
||||
ElaborateBoxDerefVisitor { tcx, unique_did, nonnull_did, local_decls, patch };
|
||||
|
||||
for (block, BasicBlockData { statements, terminator, .. }) in
|
||||
basic_blocks.iter_enumerated_mut()
|
||||
body.basic_blocks.as_mut().iter_enumerated_mut()
|
||||
{
|
||||
let mut index = 0;
|
||||
for statement in statements {
|
||||
|
|
|
@ -16,9 +16,8 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
|
|||
}
|
||||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
let ctx = InstCombineContext { tcx, local_decls };
|
||||
for block in basic_blocks.iter_mut() {
|
||||
let ctx = InstCombineContext { tcx, local_decls: &body.local_decls };
|
||||
for block in body.basic_blocks.as_mut() {
|
||||
for statement in block.statements.iter_mut() {
|
||||
match statement.kind {
|
||||
StatementKind::Assign(box (_place, ref mut rvalue)) => {
|
||||
|
|
|
@ -11,8 +11,8 @@ pub struct LowerIntrinsics;
|
|||
|
||||
impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
for block in basic_blocks {
|
||||
let local_decls = &body.local_decls;
|
||||
for block in body.basic_blocks.as_mut() {
|
||||
let terminator = block.terminator.as_mut().unwrap();
|
||||
if let TerminatorKind::Call { func, args, destination, target, .. } =
|
||||
&mut terminator.kind
|
||||
|
|
|
@ -27,12 +27,10 @@ pub fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
|||
};
|
||||
|
||||
// The one successor remains unchanged, so no need to invalidate
|
||||
let (basic_blocks, local_decls, _) =
|
||||
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
|
||||
|
||||
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
|
||||
for block in basic_blocks {
|
||||
// lower `<[_]>::len` calls
|
||||
lower_slice_len_call(tcx, block, &*local_decls, slice_len_fn_item_def_id);
|
||||
lower_slice_len_call(tcx, block, &body.local_decls, slice_len_fn_item_def_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
|
|||
let def_id = body.source.def_id();
|
||||
let param_env = tcx.param_env(def_id);
|
||||
|
||||
let (bbs, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
let bbs = body.basic_blocks.as_mut();
|
||||
let mut should_cleanup = false;
|
||||
'outer: for bb_idx in bbs.indices() {
|
||||
if !tcx.consider_optimizing(|| format!("MatchBranchSimplification {:?} ", def_id)) {
|
||||
|
@ -108,7 +108,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
|
|||
|
||||
// Introduce a temporary for the discriminant value.
|
||||
let source_info = bbs[bb_idx].terminator().source_info;
|
||||
let discr_local = local_decls.push(LocalDecl::new(switch_ty, source_info.span));
|
||||
let discr_local = body.local_decls.push(LocalDecl::new(switch_ty, source_info.span));
|
||||
|
||||
// We already checked that first and second are different blocks,
|
||||
// and bb_idx has a different terminator from both of them.
|
||||
|
|
|
@ -33,8 +33,8 @@ impl<'tcx> MirPass<'tcx> for NormalizeArrayLen {
|
|||
|
||||
pub fn normalize_array_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
// We don't ever touch terminators, so no need to invalidate the CFG cache
|
||||
let (basic_blocks, local_decls, _) =
|
||||
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
|
||||
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
|
||||
let local_decls = &mut body.local_decls;
|
||||
|
||||
// do a preliminary analysis to see if we ever have locals of type `[T;N]` or `&[T;N]`
|
||||
let mut interesting_locals = BitSet::new_empty(local_decls.len());
|
||||
|
|
|
@ -17,7 +17,7 @@ impl<'tcx> MirPass<'tcx> for RemoveStorageMarkers {
|
|||
}
|
||||
|
||||
trace!("Running RemoveStorageMarkers on {:?}", body.source);
|
||||
for data in body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate().0 {
|
||||
for data in body.basic_blocks.as_mut_preserves_cfg() {
|
||||
data.statements.retain(|statement| match statement.kind {
|
||||
StatementKind::StorageLive(..)
|
||||
| StatementKind::StorageDead(..)
|
||||
|
|
|
@ -20,11 +20,10 @@ impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
|
|||
let param_env = tcx.param_env_reveal_all_normalized(did);
|
||||
let mut should_simplify = false;
|
||||
|
||||
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
|
||||
for block in basic_blocks {
|
||||
for block in body.basic_blocks.as_mut() {
|
||||
let terminator = block.terminator_mut();
|
||||
if let TerminatorKind::Drop { place, target, .. } = terminator.kind {
|
||||
let ty = place.ty(local_decls, tcx);
|
||||
let ty = place.ty(&body.local_decls, tcx);
|
||||
if ty.ty.needs_drop(tcx, param_env) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts {
|
|||
return;
|
||||
}
|
||||
let param_env = tcx.param_env(body.source.def_id());
|
||||
let (basic_blocks, local_decls, _) =
|
||||
body.basic_blocks_local_decls_mut_and_var_debug_info_no_invalidate();
|
||||
for block in basic_blocks.iter_mut() {
|
||||
let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
|
||||
let local_decls = &body.local_decls;
|
||||
for block in basic_blocks {
|
||||
for statement in block.statements.iter_mut() {
|
||||
if let StatementKind::Assign(box (place, _)) | StatementKind::Deinit(box place) =
|
||||
statement.kind
|
||||
|
|
|
@ -386,14 +386,17 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
|
|||
trace!("running SimplifyArmIdentity on {:?}", source);
|
||||
|
||||
let local_uses = LocalUseCounter::get_local_uses(body);
|
||||
let (basic_blocks, local_decls, debug_info) =
|
||||
body.basic_blocks_local_decls_mut_and_var_debug_info();
|
||||
for bb in basic_blocks {
|
||||
for bb in body.basic_blocks.as_mut() {
|
||||
if let Some(opt_info) =
|
||||
get_arm_identity_info(&bb.statements, local_decls.len(), debug_info)
|
||||
get_arm_identity_info(&bb.statements, body.local_decls.len(), &body.var_debug_info)
|
||||
{
|
||||
trace!("got opt_info = {:#?}", opt_info);
|
||||
if !optimization_applies(&opt_info, local_decls, &local_uses, &debug_info) {
|
||||
if !optimization_applies(
|
||||
&opt_info,
|
||||
&body.local_decls,
|
||||
&local_uses,
|
||||
&body.var_debug_info,
|
||||
) {
|
||||
debug!("optimization skipped for {:?}", source);
|
||||
continue;
|
||||
}
|
||||
|
@ -431,7 +434,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyArmIdentity {
|
|||
|
||||
// Fix the debug info to point to the right local
|
||||
for dbg_index in opt_info.dbg_info_to_adjust {
|
||||
let dbg_info = &mut debug_info[dbg_index];
|
||||
let dbg_info = &mut body.var_debug_info[dbg_index];
|
||||
assert!(
|
||||
matches!(dbg_info.value, VarDebugInfoContents::Place(_)),
|
||||
"value was not a Place"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue