Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shift mir-dataflow from rustc_borrowck to rustc_mir crate. #42924

Merged
merged 1 commit into from
Jun 30, 2017
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
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