Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 7 additions & 14 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ use std::fmt;

use rustc_data_structures::fx::FxIndexMap;
use rustc_index::bit_set::{DenseBitSet, MixedBitSet};
use rustc_middle::mir::{
self, BasicBlock, Body, CallReturnPlaces, Location, Place, TerminatorEdges,
};
use rustc_middle::mir::{self, BasicBlock, Body, CallReturnPlaces, Location, Place};
use rustc_middle::ty::{RegionVid, TyCtxt};
use rustc_mir_dataflow::fmt::DebugWithContext;
use rustc_mir_dataflow::impls::{
Expand Down Expand Up @@ -76,19 +74,15 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
self.ever_inits.apply_early_terminator_effect(&mut state.ever_inits, term, loc);
}

fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
term: &'mir mir::Terminator<'tcx>,
term: &mir::Terminator<'tcx>,
loc: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
self.borrows.apply_primary_terminator_effect(&mut state.borrows, term, loc);
self.uninits.apply_primary_terminator_effect(&mut state.uninits, term, loc);
self.ever_inits.apply_primary_terminator_effect(&mut state.ever_inits, term, loc);

// This return value doesn't matter. It's only used by `iterate_to_fixpoint`, which this
// analysis doesn't use.
TerminatorEdges::None
}

fn apply_call_return_effect(
Expand Down Expand Up @@ -598,12 +592,12 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
self.kill_loans_out_of_scope_at_location(state, location);
}

fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
terminator: &mir::Terminator<'tcx>,
_location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
if let mir::TerminatorKind::InlineAsm { operands, .. } = &terminator.kind {
for op in operands {
if let mir::InlineAsmOperand::Out { place: Some(place), .. }
Expand All @@ -613,7 +607,6 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
}
}
}
terminator.edges()
}
}

Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_const_eval/src/check_consts/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::marker::PhantomData;
use rustc_index::bit_set::MixedBitSet;
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{
self, BasicBlock, CallReturnPlaces, Local, Location, Statement, StatementKind, TerminatorEdges,
self, BasicBlock, CallReturnPlaces, Local, Location, Statement, StatementKind,
};
use rustc_mir_dataflow::fmt::DebugWithContext;
use rustc_mir_dataflow::{Analysis, JoinSemiLattice};
Expand Down Expand Up @@ -351,14 +351,13 @@ where
self.transfer_function(state).visit_statement(statement, location);
}

fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
terminator: &mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
self.transfer_function(state).visit_terminator(terminator, location);
terminator.edges()
}

fn apply_call_return_effect(
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir_dataflow/src/framework/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ impl Direction for Forward {
let terminator = block_data.terminator();
let location = Location { block, statement_index: block_data.statements.len() };
analysis.apply_early_terminator_effect(state, terminator, location);
let edges = analysis.apply_primary_terminator_effect(state, terminator, location);
// Edges are obtained *before* calling `apply_primary_terminator_effect`.
let edges = analysis.get_terminator_edges(state, terminator, location);
analysis.apply_primary_terminator_effect(state, terminator, location);

let exit_state = state;
match edges {
Expand Down
19 changes: 15 additions & 4 deletions compiler/rustc_mir_dataflow/src/framework/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,30 @@ pub trait Analysis<'tcx> {
) {
}

/// Gets the terminator edges. Used by forward analyses only. Called *before*
/// `apply_primary_terminator_effect` is applied; this might seem strange but in practice
/// `MaybeInitializedPlaces` needs that ordering and other analyses work with either ordering.
fn get_terminator_edges<'mir>(
&self,
_state: &Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
_location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
terminator.edges()
}

/// Updates the current dataflow state with the effect of evaluating a terminator.
///
/// The effect of a successful return from a `Call` terminator should **not** be accounted for
/// in this function. That should go in `apply_call_return_effect`. For example, in the
/// `InitializedPlaces` analyses, the return place for a function call is not marked as
/// initialized here.
fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
_state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
terminator.edges()
) {
}

/* Edge-specific effects */
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_mir_dataflow/src/framework/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,14 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
assert!(state.insert(idx));
}

fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
let idx = self.effect(Effect::Primary.at_index(location.statement_index));
assert!(state.insert(idx));
terminator.edges()
}
}

Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,13 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
Self::transfer_function(state).visit_statement(statement, location);
}

fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'mir Terminator<'tcx>,
terminator: &Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
Self::transfer_function(state).visit_terminator(terminator, location);
terminator.edges()
}
}

Expand Down
48 changes: 32 additions & 16 deletions compiler/rustc_mir_dataflow/src/impls/initialized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,14 +391,15 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
}
}

fn apply_primary_terminator_effect<'mir>(
fn get_terminator_edges<'mir>(
&self,
state: &mut Self::Domain,
state: &Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
_location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
// Note: `edges` must be computed first because `drop_flag_effects_for_location` can change
// the result of `is_unwind_dead`.
// Note: this relies on `get_terminator_edges` being called before
// `apply_primary_terminator_effect` because the result of `is_unwind_dead` is affected by
// the `drop_flag_effects_for_location` in `apply_primary_terminator_effect`.
let mut edges = terminator.edges();
if self.skip_unreachable_unwind
&& let mir::TerminatorKind::Drop { target, unwind, place, replace: _, drop: _ } =
Expand All @@ -408,10 +409,18 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
{
edges = TerminatorEdges::Single(target);
}
edges
}

fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) {
drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
Self::update_bits(state, path, s)
});
edges
}

fn apply_call_return_effect(
Expand Down Expand Up @@ -514,15 +523,12 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
// mutable borrow occurs. Places cannot become uninitialized through a mutable reference.
}

fn apply_primary_terminator_effect<'mir>(
fn get_terminator_edges<'mir>(
&self,
state: &mut Self::Domain,
_state: &Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
Self::update_bits(state, path, s)
});
if self.skip_unreachable_unwind.contains(location.block) {
let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { bug!() };
assert_matches!(unwind, mir::UnwindAction::Cleanup(_));
Expand All @@ -532,6 +538,17 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
}
}

fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) {
drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
Self::update_bits(state, path, s)
});
}

fn apply_call_return_effect(
&self,
state: &mut Self::Domain,
Expand Down Expand Up @@ -633,13 +650,13 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
}
}

#[instrument(skip(self, state, terminator), level = "debug")]
fn apply_primary_terminator_effect<'mir>(
#[instrument(skip(self, state, _terminator), level = "debug")]
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
let move_data = self.move_data();
let init_loc_map = &move_data.init_loc_map;

Expand All @@ -652,7 +669,6 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
None
}
}));
terminator.edges()
}

fn apply_call_return_effect(
Expand Down
18 changes: 7 additions & 11 deletions compiler/rustc_mir_dataflow/src/impls/liveness.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use rustc_index::bit_set::DenseBitSet;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::{
self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges,
};
use rustc_middle::mir::{self, CallReturnPlaces, Local, Location, Place, StatementKind};

use crate::{Analysis, Backward, GenKill};

Expand Down Expand Up @@ -55,14 +53,13 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
TransferFunction(state).visit_statement(statement, location);
}

fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
terminator: &mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
TransferFunction(state).visit_terminator(terminator, location);
terminator.edges()
}

fn apply_call_return_effect(
Expand Down Expand Up @@ -301,14 +298,13 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
TransferFunction(state).visit_statement(statement, location);
}

fn apply_primary_terminator_effect<'mir>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
terminator: &mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
) {
TransferFunction(state).visit_terminator(terminator, location);
terminator.edges()
}

fn apply_call_return_effect(
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,12 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage {
}
}

fn apply_primary_terminator_effect<'t>(
fn apply_primary_terminator_effect(
&self,
state: &mut Self::Domain,
terminator: &'t Terminator<'tcx>,
terminator: &Terminator<'tcx>,
loc: Location,
) -> TerminatorEdges<'t, 'tcx> {
) {
match terminator.kind {
// For call terminators the destination requires storage for the call
// and after the call returns successfully, but not after a panic.
Expand Down Expand Up @@ -333,7 +333,6 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage {
}

self.check_for_move(state, loc);
terminator.edges()
}

fn apply_call_return_effect(
Expand Down
Loading
Loading