Skip to content

Commit

Permalink
Shift mir-dataflow from rustc_borrowck to rustc_mir crate.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
pnkfelix committed Jun 28, 2017
1 parent 6b52a11 commit 13cd022
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 13cd022

Please sign in to comment.