Skip to content

Commit

Permalink
Auto merge of #42924 - pnkfelix:mir-dataflow, r=arielb1
Browse files Browse the repository at this point in the history
Shift mir-dataflow from `rustc_borrowck` to `rustc_mir` crate.

Shift mir-dataflow from `rustc_borrowck` to `rustc_mir` crate.

Turn `elaborate_drops` and `rustc_peek` implementations into MIR passes that also live in `rustc_mir` crate.

Rewire things so `rustc_driver` uses the `ElaborateDrops` from `rustc_mir` crate.

(This PR is another baby step for mir-borrowck; it is a piece of work that other people want to rebase their stuff on top of, namely developers who are doing other dataflow analyses on top of MIR.)

I have deliberately architected this PR in an attempt to minimize the number of actual code changes. The majority of the diff should be little more than changes to mod and use declarations, as well as a few visibility promotions to pub(crate) when a declaration was moved downward in the module hierarchy.

(I have no problem with other PR's that move declarations around to try to clean this up; my goal was to ensure that the diff here was as small as possible, to make the review nearly trivial.)
  • Loading branch information
bors committed Jun 30, 2017
2 parents 5eef7c7 + 13cd022 commit a4c68c6
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 206 deletions.
27 changes: 9 additions & 18 deletions src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ pub use self::bckerr_code::*;
pub use self::AliasableViolationKind::*;
pub use self::MovedValueUseKind::*;

pub use self::mir::elaborate_drops::ElaborateDrops;

use self::InteriorKind::*;

use rustc::hir::map as hir_map;
Expand Down Expand Up @@ -55,8 +53,6 @@ pub mod gather_loans;

pub mod move_data;

mod mir;

#[derive(Clone, Copy)]
pub struct LoanDataFlowOperator;

Expand Down Expand Up @@ -100,26 +96,21 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId) {
}

let body_id = tcx.hir.body_owned_by(owner_id);
let attributes = tcx.get_attrs(owner_def_id);
let tables = tcx.typeck_tables_of(owner_def_id);
let region_maps = tcx.region_maps(owner_def_id);
let mut bccx = &mut BorrowckCtxt { tcx, tables, region_maps, owner_def_id };

let body = bccx.tcx.hir.body(body_id);

if bccx.tcx.has_attr(owner_def_id, "rustc_mir_borrowck") {
mir::borrowck_mir(bccx, owner_id, &attributes);
} else {
// Eventually, borrowck will always read the MIR, but at the
// moment we do not. So, for now, we always force MIR to be
// constructed for a given fn, since this may result in errors
// being reported and we want that to happen.
//
// Note that `mir_validated` is a "stealable" result; the
// thief, `optimized_mir()`, forces borrowck, so we know that
// is not yet stolen.
tcx.mir_validated(owner_def_id).borrow();
}
// Eventually, borrowck will always read the MIR, but at the
// moment we do not. So, for now, we always force MIR to be
// constructed for a given fn, since this may result in errors
// being reported and we want that to happen.
//
// Note that `mir_validated` is a "stealable" result; the
// thief, `optimized_mir()`, forces borrowck, so we know that
// is not yet stolen.
tcx.mir_validated(owner_def_id).borrow();

let cfg = cfg::CFG::new(bccx.tcx, &body);
let AnalysisData { all_loans,
Expand Down
3 changes: 1 addition & 2 deletions src/librustc_borrowck/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(associated_consts)]
#![feature(nonzero)]

#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
Expand All @@ -39,7 +38,7 @@ extern crate core; // for NonZero

pub use borrowck::check_crate;
pub use borrowck::build_borrowck_dataflow_data_for_fn;
pub use borrowck::{AnalysisData, BorrowckCtxt, ElaborateDrops};
pub use borrowck::{AnalysisData, BorrowckCtxt};

// NB: This module needs to be declared first so diagnostics are
// registered before they are used.
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// What we need to do constant evaluation.
passes.push_pass(MIR_CONST, mir::transform::simplify::SimplifyCfg::new("initial"));
passes.push_pass(MIR_CONST, mir::transform::type_check::TypeckMir);
passes.push_pass(MIR_CONST, mir::transform::rustc_peek::SanityCheck);

// What we need to run borrowck etc.
passes.push_pass(MIR_VALIDATED, mir::transform::qualify_consts::QualifyAndPromoteConstants);
Expand All @@ -934,7 +935,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// From here on out, regions are gone.
passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
passes.push_pass(MIR_OPTIMIZED, borrowck::ElaborateDrops);
passes.push_pass(MIR_OPTIMIZED, mir::transform::elaborate_drops::ElaborateDrops);
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -8,33 +8,24 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use borrowck::BorrowckCtxt;

use syntax::ast::{self, MetaItem};
use syntax_pos::DUMMY_SP;

use rustc::mir::{self, BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};

use rustc::mir::{self, Mir, BasicBlock, Location};
use rustc::session::Session;
use rustc::ty::{self, TyCtxt};
use rustc_mir::util::elaborate_drops::DropFlagState;
use rustc_data_structures::indexed_set::{IdxSet, IdxSetBuf};

mod abs_domain;
pub mod elaborate_drops;
mod dataflow;
mod gather_moves;
// mod graphviz;

use self::dataflow::{BitDenotation};
use self::dataflow::{DataflowOperator};
use self::dataflow::{Dataflow, DataflowAnalysis, DataflowResults};
use self::dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals};
use self::dataflow::{DefinitelyInitializedLvals};
use self::gather_moves::{HasMoveData, MoveData, MovePathIndex, LookupResult};
use util::elaborate_drops::DropFlagState;
use rustc_data_structures::indexed_set::{IdxSet};

use std::fmt;

fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
use super::{Dataflow, DataflowBuilder, DataflowAnalysis};
use super::{BitDenotation, DataflowOperator, DataflowResults};
use super::indexes::MovePathIndex;
use super::move_paths::{MoveData, LookupResult};

pub(crate) fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem> {
for attr in attrs {
if attr.check_name("rustc_mir") {
let items = attr.meta_item_list();
Expand All @@ -50,69 +41,11 @@ fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<MetaItem>
}

pub struct MoveDataParamEnv<'tcx> {
move_data: MoveData<'tcx>,
param_env: ty::ParamEnv<'tcx>,
pub(crate) move_data: MoveData<'tcx>,
pub(crate) param_env: ty::ParamEnv<'tcx>,
}

pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
id: ast::NodeId,
attributes: &[ast::Attribute]) {
let tcx = bcx.tcx;
let def_id = tcx.hir.local_def_id(id);
debug!("borrowck_mir({:?}) UNIMPLEMENTED", def_id);

// It is safe for us to borrow `mir_validated()`: `optimized_mir`
// steals it, but it forces the `borrowck` query.
let mir = &tcx.mir_validated(def_id).borrow();

let param_env = tcx.param_env(def_id);
let move_data = MoveData::gather_moves(mir, tcx, param_env);
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
let flow_inits =
do_dataflow(tcx, mir, id, attributes, &dead_unwinds,
MaybeInitializedLvals::new(tcx, mir, &mdpe),
|bd, i| &bd.move_data().move_paths[i]);
let flow_uninits =
do_dataflow(tcx, mir, id, attributes, &dead_unwinds,
MaybeUninitializedLvals::new(tcx, mir, &mdpe),
|bd, i| &bd.move_data().move_paths[i]);
let flow_def_inits =
do_dataflow(tcx, mir, id, attributes, &dead_unwinds,
DefinitelyInitializedLvals::new(tcx, mir, &mdpe),
|bd, i| &bd.move_data().move_paths[i]);

if has_rustc_mir_with(attributes, "rustc_peek_maybe_init").is_some() {
dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &flow_inits);
}
if has_rustc_mir_with(attributes, "rustc_peek_maybe_uninit").is_some() {
dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &flow_uninits);
}
if has_rustc_mir_with(attributes, "rustc_peek_definite_init").is_some() {
dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &flow_def_inits);
}

if has_rustc_mir_with(attributes, "stop_after_dataflow").is_some() {
bcx.tcx.sess.fatal("stop_after_dataflow ended compilation");
}

let mut mbcx = MirBorrowckCtxt {
bcx: bcx,
mir: mir,
node_id: id,
move_data: &mdpe.move_data,
flow_inits: flow_inits,
flow_uninits: flow_uninits,
};

for bb in mir.basic_blocks().indices() {
mbcx.process_basic_block(bb);
}

debug!("borrowck_mir done");
}

fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub(crate) fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
node_id: ast::NodeId,
attributes: &[ast::Attribute],
Expand Down Expand Up @@ -142,7 +75,7 @@ fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let print_postflow_to =
name_found(tcx.sess, attributes, "borrowck_graphviz_postflow");

let mut mbcx = MirBorrowckCtxtPreDataflow {
let mut mbcx = DataflowBuilder {
node_id: node_id,
print_preflow_to: print_preflow_to,
print_postflow_to: print_postflow_to,
Expand All @@ -153,46 +86,7 @@ fn do_dataflow<'a, 'tcx, BD, P>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mbcx.flow_state.results()
}


pub struct MirBorrowckCtxtPreDataflow<'a, 'tcx: 'a, BD> where BD: BitDenotation
{
node_id: ast::NodeId,
flow_state: DataflowAnalysis<'a, 'tcx, BD>,
print_preflow_to: Option<String>,
print_postflow_to: Option<String>,
}

#[allow(dead_code)]
pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> {
bcx: &'b mut BorrowckCtxt<'a, 'tcx>,
mir: &'b Mir<'tcx>,
node_id: ast::NodeId,
move_data: &'b MoveData<'tcx>,
flow_inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>,
flow_uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>>
}

impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> {
fn process_basic_block(&mut self, bb: BasicBlock) {
let BasicBlockData { ref statements, ref terminator, is_cleanup: _ } =
self.mir[bb];
for stmt in statements {
self.process_statement(bb, stmt);
}

self.process_terminator(bb, terminator);
}

fn process_statement(&mut self, bb: BasicBlock, stmt: &Statement<'tcx>) {
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}", bb, stmt);
}

fn process_terminator(&mut self, bb: BasicBlock, term: &Option<Terminator<'tcx>>) {
debug!("MirBorrowckCtxt::process_terminator({:?}, {:?})", bb, term);
}
}

fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
path: MovePathIndex,
mut cond: F)
-> Option<MovePathIndex>
Expand Down Expand Up @@ -253,7 +147,7 @@ fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx
}
}

fn on_lookup_result_bits<'a, 'tcx, F>(
pub(crate) fn on_lookup_result_bits<'a, 'tcx, F>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
move_data: &MoveData<'tcx>,
Expand All @@ -271,7 +165,7 @@ fn on_lookup_result_bits<'a, 'tcx, F>(
}
}

fn on_all_children_bits<'a, 'tcx, F>(
pub(crate) fn on_all_children_bits<'a, 'tcx, F>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
move_data: &MoveData<'tcx>,
Expand Down Expand Up @@ -312,7 +206,7 @@ fn on_all_children_bits<'a, 'tcx, F>(
on_all_children_bits(tcx, mir, move_data, move_path_index, &mut each_child);
}

fn on_all_drop_children_bits<'a, 'tcx, F>(
pub(crate) fn on_all_drop_children_bits<'a, 'tcx, F>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
ctxt: &MoveDataParamEnv<'tcx>,
Expand All @@ -333,7 +227,7 @@ fn on_all_drop_children_bits<'a, 'tcx, F>(
})
}

fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
pub(crate) fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
ctxt: &MoveDataParamEnv<'tcx>,
Expand All @@ -350,7 +244,7 @@ fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
}
}

fn drop_flag_effects_for_location<'a, 'tcx, F>(
pub(crate) fn drop_flag_effects_for_location<'a, 'tcx, F>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
ctxt: &MoveDataParamEnv<'tcx>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use rustc::mir::{BasicBlock, Mir};
use rustc_data_structures::bitslice::bits_to_string;
use rustc_data_structures::indexed_set::{IdxSet};
use rustc_data_structures::indexed_vec::Idx;
use rustc_mir::util as mir_util;

use dot;
use dot::IntoCow;
Expand All @@ -28,8 +27,10 @@ use std::marker::PhantomData;
use std::mem;
use std::path::Path;

use super::super::MirBorrowckCtxtPreDataflow;
use util;

use super::{BitDenotation, DataflowState};
use super::DataflowBuilder;

impl<O: BitDenotation> DataflowState<O> {
fn each_bit<F>(&self, words: &IdxSet<O::Idx>, mut f: F)
Expand Down Expand Up @@ -86,7 +87,7 @@ pub trait MirWithFlowState<'tcx> {
fn flow_state(&self) -> &DataflowState<Self::BD>;
}

impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>
impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD>
where 'tcx: 'a, BD: BitDenotation
{
type BD = BD;
Expand All @@ -103,8 +104,8 @@ struct Graph<'a, 'tcx, MWF:'a, P> where
render_idx: P,
}

pub fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
mbcx: &MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>,
pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>(
mbcx: &DataflowBuilder<'a, 'tcx, BD>,
path: &Path,
render_idx: P)
-> io::Result<()>
Expand Down Expand Up @@ -220,7 +221,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
}
Ok(())
}
mir_util::write_graphviz_node_label(
util::write_graphviz_node_label(
*n, self.mbcx.mir(), &mut v, 4,
|w| {
let flow = self.mbcx.flow_state();
Expand Down
Loading

0 comments on commit a4c68c6

Please sign in to comment.