rustc: move the MIR map into TyCtxt.

This commit is contained in:
Eduard Burtescu 2016-10-28 13:55:49 +03:00
parent 36340ba994
commit e34792b181
26 changed files with 236 additions and 413 deletions

View File

@ -30,7 +30,6 @@ use hir::svh::Svh;
use middle::lang_items;
use ty::{self, Ty, TyCtxt};
use mir::Mir;
use mir::mir_map::MirMap;
use session::Session;
use session::search_paths::PathKind;
use util::nodemap::{NodeSet, DefIdMap};
@ -209,8 +208,7 @@ pub trait CrateStore<'tcx> {
fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>;
fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>;
fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<Mir<'tcx>>;
fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>;
fn is_item_mir_available(&self, def: DefId) -> bool;
// This is basically a 1-based range of ints, which is a little
@ -228,8 +226,7 @@ pub trait CrateStore<'tcx> {
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &MirMap<'tcx>) -> Vec<u8>;
reachable: &NodeSet) -> Vec<u8>;
fn metadata_encoding_version(&self) -> &[u8];
}
@ -390,8 +387,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
bug!("defid_for_inlined_node")
}
fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Mir<'tcx> { bug!("get_item_mir") }
fn is_item_mir_available(&self, def: DefId) -> bool {
bug!("is_item_mir_available")
}
@ -412,8 +409,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &MirMap<'tcx>) -> Vec<u8> { vec![] }
reachable: &NodeSet) -> Vec<u8> { vec![] }
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
}

View File

@ -1,38 +0,0 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
use hir::def_id::DefId;
use mir::Mir;
use std::marker::PhantomData;
pub struct MirMap<'tcx> {
pub map: DepTrackingMap<MirMapConfig<'tcx>>,
}
impl<'tcx> MirMap<'tcx> {
pub fn new(graph: DepGraph) -> Self {
MirMap {
map: DepTrackingMap::new(graph)
}
}
}
pub struct MirMapConfig<'tcx> {
data: PhantomData<&'tcx ()>
}
impl<'tcx> DepTrackingMapConfig for MirMapConfig<'tcx> {
type Key = DefId;
type Value = Mir<'tcx>;
fn to_dep_node(key: &DefId) -> DepNode<DefId> {
DepNode::Mir(*key)
}
}

View File

@ -37,7 +37,6 @@ pub mod tcx;
pub mod visit;
pub mod transform;
pub mod traversal;
pub mod mir_map;
macro_rules! newtype_index {
($name:ident, $debug_name:expr) => (

View File

@ -11,7 +11,6 @@
use dep_graph::DepNode;
use hir;
use hir::map::DefPathData;
use mir::mir_map::MirMap;
use mir::{Mir, Promoted};
use ty::TyCtxt;
use syntax::ast::NodeId;
@ -85,12 +84,11 @@ pub trait Pass {
fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
}
/// A pass which inspects the whole MirMap.
/// A pass which inspects the whole Mir map.
pub trait MirMapPass<'tcx>: Pass {
fn run_pass<'a>(
&mut self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
map: &mut MirMap<'tcx>,
hooks: &mut [Box<for<'s> MirPassHook<'s>>]);
}
@ -114,13 +112,18 @@ pub trait MirPass<'tcx>: Pass {
impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
fn run_pass<'a>(&mut self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
map: &mut MirMap<'tcx>,
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
{
let def_ids = map.map.keys();
let def_ids = tcx.mir_map.borrow().keys();
for def_id in def_ids {
if !def_id.is_local() {
continue;
}
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
let mir = map.map.get_mut(&def_id).unwrap();
let mir = &mut tcx.mir_map.borrow()[&def_id].borrow_mut();
tcx.dep_graph.write(DepNode::Mir(def_id));
let id = tcx.map.as_local_node_id(def_id).unwrap();
let src = MirSource::from_node(tcx, id);
@ -163,11 +166,11 @@ impl<'a, 'tcx> Passes {
passes
}
pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, map: &mut MirMap<'tcx>) {
pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self;
for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) {
time(tcx.sess.time_passes(), &*pass.name(),
|| pass.run_pass(tcx, map, pass_hooks));
|| pass.run_pass(tcx, pass_hooks));
}
}

View File

@ -22,6 +22,7 @@ use middle::free_region::FreeRegionMap;
use middle::region::RegionMaps;
use middle::resolve_lifetime;
use middle::stability;
use mir::Mir;
use ty::subst::{Kind, Substs};
use traits;
use ty::{self, TraitRef, Ty, TypeAndMut};
@ -65,8 +66,9 @@ pub struct CtxtArenas<'tcx> {
// references
generics: TypedArena<ty::Generics<'tcx>>,
trait_defs: TypedArena<ty::TraitDef<'tcx>>,
adt_defs: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
trait_def: TypedArena<ty::TraitDef<'tcx>>,
adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
mir: TypedArena<RefCell<Mir<'tcx>>>,
}
impl<'tcx> CtxtArenas<'tcx> {
@ -81,8 +83,9 @@ impl<'tcx> CtxtArenas<'tcx> {
layout: TypedArena::new(),
generics: TypedArena::new(),
trait_defs: TypedArena::new(),
adt_defs: TypedArena::new()
trait_def: TypedArena::new(),
adt_def: TypedArena::new(),
mir: TypedArena::new()
}
}
}
@ -358,6 +361,15 @@ pub struct GlobalCtxt<'tcx> {
pub map: ast_map::Map<'tcx>,
/// Maps from the def-id of a function/method or const/static
/// to its MIR. Mutation is done at an item granularity to
/// allow MIR optimization passes to function and still
/// access cross-crate MIR (e.g. inlining or const eval).
///
/// Note that cross-crate MIR appears to be always borrowed
/// (in the `RefCell` sense) to prevent accidental mutation.
pub mir_map: RefCell<DepTrackingMap<maps::Mir<'tcx>>>,
// Records the free variables refrenced by every closure
// expression. Do not track deps for this, just recompute it from
// scratch every time.
@ -604,6 +616,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.global_interners.arenas.generics.alloc(generics)
}
pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell<Mir<'gcx>> {
self.global_interners.arenas.mir.alloc(RefCell::new(mir))
}
pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
-> &'gcx ty::TraitDef<'gcx> {
let did = def.trait_ref.def_id;
@ -617,7 +633,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn alloc_trait_def(self, def: ty::TraitDef<'gcx>)
-> &'gcx ty::TraitDef<'gcx> {
self.global_interners.arenas.trait_defs.alloc(def)
self.global_interners.arenas.trait_def.alloc(def)
}
pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
@ -633,7 +649,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
variants: Vec<ty::VariantDefData<'gcx, 'gcx>>)
-> ty::AdtDefMaster<'gcx> {
let def = ty::AdtDefData::new(self, did, kind, variants);
let interned = self.global_interners.arenas.adt_defs.alloc(def);
let interned = self.global_interners.arenas.adt_def.alloc(def);
self.insert_adt_def(did, interned);
interned
}
@ -738,6 +754,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
fulfilled_predicates: RefCell::new(fulfilled_predicates),
map: map,
mir_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
freevars: RefCell::new(freevars),
maybe_unused_trait_imports: maybe_unused_trait_imports,
tcache: RefCell::new(DepTrackingMap::new(dep_graph.clone())),

View File

@ -10,7 +10,10 @@
use dep_graph::{DepNode, DepTrackingMapConfig};
use hir::def_id::DefId;
use mir;
use ty::{self, Ty};
use std::cell::RefCell;
use std::marker::PhantomData;
use std::rc::Rc;
use syntax::{attr, ast};
@ -43,3 +46,4 @@ dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId }
dep_map_ty! { Mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>> }

View File

@ -24,6 +24,7 @@ use hir::def::{Def, CtorKind, PathResolution, ExportMap};
use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
use mir::Mir;
use traits;
use ty;
use ty::subst::{Subst, Substs};
@ -34,7 +35,7 @@ use util::nodemap::FnvHashMap;
use serialize::{self, Encodable, Encoder};
use std::borrow::Cow;
use std::cell::{Cell, RefCell};
use std::cell::{Cell, RefCell, Ref};
use std::hash::{Hash, Hasher};
use std::iter;
use std::ops::Deref;
@ -2519,6 +2520,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|| self.sess.cstore.item_super_predicates(self.global_tcx(), did))
}
/// Given the did of an item, returns its MIR, borrowed immutably.
pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> {
lookup_locally_or_in_crate_store("mir_map", did, &self.mir_map, || {
let mir = self.sess.cstore.get_item_mir(self.global_tcx(), did);
let mir = self.alloc_mir(mir);
// Perma-borrow MIR from extern crates to prevent mutation.
mem::forget(mir.borrow());
mir
}).borrow()
}
/// If `type_needs_drop` returns true, then `ty` is definitely
/// non-copy and *might* have a destructor attached; if it returns
/// false, then `ty` definitely has no destructor (i.e. no drop glue).

View File

@ -55,15 +55,13 @@ pub struct MoveDataParamEnv<'tcx> {
param_env: ty::ParameterEnvironment<'tcx>,
}
pub fn borrowck_mir<'a, 'tcx: 'a>(
bcx: &mut BorrowckCtxt<'a, 'tcx>,
fk: FnKind,
_decl: &hir::FnDecl,
mir: &'a Mir<'tcx>,
body: &hir::Block,
_sp: Span,
id: ast::NodeId,
attributes: &[ast::Attribute]) {
pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
fk: FnKind,
_decl: &hir::FnDecl,
body: &hir::Block,
_sp: Span,
id: ast::NodeId,
attributes: &[ast::Attribute]) {
match fk {
FnKind::ItemFn(name, ..) |
FnKind::Method(name, ..) => {
@ -75,8 +73,10 @@ pub fn borrowck_mir<'a, 'tcx: 'a>(
}
let tcx = bcx.tcx;
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
let mir = &tcx.item_mir(tcx.map.local_def_id(id));
let move_data = MoveData::gather_moves(mir, tcx, &param_env);
let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
let flow_inits =
@ -170,8 +170,8 @@ pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> {
mir: &'b Mir<'tcx>,
node_id: ast::NodeId,
move_data: MoveData<'tcx>,
flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx>>,
flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx>>
flow_inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>,
flow_uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>>
}
impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> {

View File

@ -51,8 +51,6 @@ use rustc::hir::{FnDecl, Block};
use rustc::hir::intravisit;
use rustc::hir::intravisit::{Visitor, FnKind};
use rustc::mir::mir_map::MirMap;
pub mod check_loans;
pub mod gather_loans;
@ -102,10 +100,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
}
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &MirMap<'tcx>) {
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut bccx = BorrowckCtxt {
tcx: tcx,
mir_map: Some(mir_map),
free_region_map: FreeRegionMap::new(),
stats: BorrowStats {
loaned_paths_same: 0,
@ -168,12 +165,9 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
attributes: &[ast::Attribute]) {
debug!("borrowck_fn(id={})", id);
let def_id = this.tcx.map.local_def_id(id);
if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) {
let mir = this.mir_map.unwrap().map.get(&def_id).unwrap();
this.with_temp_region_map(id, |this| {
mir::borrowck_mir(this, fk, decl, mir, body, sp, id, attributes)
mir::borrowck_mir(this, fk, decl, body, sp, id, attributes)
});
}
@ -249,7 +243,6 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
/// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir_map: Option<&'a MirMap<'tcx>>,
fn_parts: FnParts<'a>,
cfg: &cfg::CFG)
-> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>)
@ -257,7 +250,6 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
let mut bccx = BorrowckCtxt {
tcx: tcx,
mir_map: mir_map,
free_region_map: FreeRegionMap::new(),
stats: BorrowStats {
loaned_paths_same: 0,
@ -297,10 +289,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
free_region_map: FreeRegionMap,
// Statistics:
stats: BorrowStats,
// NodeId to MIR mapping (for methods that carry the #[rustc_mir] attribute).
mir_map: Option<&'a MirMap<'tcx>>,
stats: BorrowStats
}
#[derive(Clone)]

View File

@ -13,7 +13,6 @@ use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
use rustc::hir::def::DefMap;
use rustc::hir::lowering::lower_crate;
use rustc_mir as mir;
use rustc::mir::mir_map::MirMap;
use rustc::session::{Session, CompileResult, compile_result_from_err_count};
use rustc::session::config::{self, Input, OutputFilenames, OutputType,
OutputTypes};
@ -175,7 +174,7 @@ pub fn compile_input(sess: &Session,
resolutions,
&arenas,
&crate_name,
|tcx, mir_map, analysis, incremental_hashes_map, result| {
|tcx, analysis, incremental_hashes_map, result| {
{
// Eventually, we will want to track plugins.
let _ignore = tcx.dep_graph.in_ignore();
@ -187,7 +186,6 @@ pub fn compile_input(sess: &Session,
opt_crate,
tcx.map.krate(),
&analysis,
mir_map.as_ref(),
tcx,
&crate_name);
(control.after_analysis.callback)(&mut state);
@ -203,10 +201,7 @@ pub fn compile_input(sess: &Session,
println!("Pre-trans");
tcx.print_debug_stats();
}
let trans = phase_4_translate_to_llvm(tcx,
mir_map.unwrap(),
analysis,
&incremental_hashes_map);
let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map);
if log_enabled!(::log::INFO) {
println!("Post-trans");
@ -348,7 +343,6 @@ pub struct CompileState<'a, 'b, 'ast: 'a, 'tcx: 'b> where 'ast: 'tcx {
pub hir_crate: Option<&'a hir::Crate>,
pub ast_map: Option<&'a hir_map::Map<'ast>>,
pub resolutions: Option<&'a Resolutions>,
pub mir_map: Option<&'b MirMap<'tcx>>,
pub analysis: Option<&'a ty::CrateAnalysis<'a>>,
pub tcx: Option<TyCtxt<'b, 'tcx, 'tcx>>,
pub trans: Option<&'a trans::CrateTranslation>,
@ -375,7 +369,6 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
ast_map: None,
resolutions: None,
analysis: None,
mir_map: None,
tcx: None,
trans: None,
}
@ -449,13 +442,11 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
krate: Option<&'a ast::Crate>,
hir_crate: &'a hir::Crate,
analysis: &'a ty::CrateAnalysis<'a>,
mir_map: Option<&'b MirMap<'tcx>>,
tcx: TyCtxt<'b, 'tcx, 'tcx>,
crate_name: &'a str)
-> CompileState<'a, 'b, 'ast, 'tcx> {
CompileState {
analysis: Some(analysis),
mir_map: mir_map,
tcx: Some(tcx),
expanded_crate: krate,
hir_crate: Some(hir_crate),
@ -812,17 +803,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
f: F)
-> Result<R, usize>
where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
Option<MirMap<'tcx>>,
ty::CrateAnalysis,
IncrementalHashesMap,
CompileResult) -> R
{
macro_rules! try_with_f {
($e: expr, ($t: expr, $m: expr, $a: expr, $h: expr)) => {
($e: expr, ($t: expr, $a: expr, $h: expr)) => {
match $e {
Ok(x) => x,
Err(x) => {
f($t, $m, $a, $h, Err(x));
f($t, $a, $h, Err(x));
return Err(x);
}
}
@ -888,7 +878,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|| rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));
// passes are timed inside typeck
try_with_f!(typeck::check_crate(tcx), (tcx, None, analysis, incremental_hashes_map));
try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map));
time(time_passes,
"const checking",
@ -928,28 +918,28 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
"rvalue checking",
|| rvalues::check_crate(tcx));
let mut mir_map =
time(time_passes,
"MIR dump",
|| mir::mir_map::build_mir_for_crate(tcx));
time(time_passes,
"MIR dump",
|| mir::mir_map::build_mir_for_crate(tcx));
time(time_passes, "MIR passes", || {
let mut passes = sess.mir_passes.borrow_mut();
// Push all the built-in passes.
passes.push_hook(box mir::transform::dump_mir::DumpMir);
passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("initial"));
passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
passes.push_pass(
box mir::transform::qualify_consts::QualifyAndPromoteConstants::default());
passes.push_pass(box mir::transform::type_check::TypeckMir);
passes.push_pass(
box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("qualify-consts"));
// And run everything.
passes.run_passes(tcx, &mut mir_map);
passes.run_passes(tcx);
});
time(time_passes,
"borrow checking",
|| borrowck::check_crate(tcx, &mir_map));
|| borrowck::check_crate(tcx));
// Avoid overwhelming user with errors if type checking failed.
// I'm not sure how helpful this is, to be honest, but it avoids
@ -958,11 +948,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
if sess.err_count() > 0 {
return Ok(f(tcx,
Some(mir_map),
analysis,
incremental_hashes_map,
Err(sess.err_count())));
return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
}
analysis.reachable =
@ -990,20 +976,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// The above three passes generate errors w/o aborting
if sess.err_count() > 0 {
return Ok(f(tcx,
Some(mir_map),
analysis,
incremental_hashes_map,
Err(sess.err_count())));
return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
}
Ok(f(tcx, Some(mir_map), analysis, incremental_hashes_map, Ok(())))
Ok(f(tcx, analysis, incremental_hashes_map, Ok(())))
})
}
/// Run the translation phase to LLVM, after which the AST and analysis can
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mut mir_map: MirMap<'tcx>,
analysis: ty::CrateAnalysis,
incremental_hashes_map: &IncrementalHashesMap)
-> trans::CrateTranslation {
@ -1037,13 +1018,13 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans"));
passes.run_passes(tcx, &mut mir_map);
passes.run_passes(tcx);
});
let translation =
time(time_passes,
"translation",
move || trans::trans_crate(tcx, &mir_map, analysis, &incremental_hashes_map));
move || trans::trans_crate(tcx, analysis, &incremental_hashes_map));
time(time_passes,
"assert dep graph",

View File

@ -52,8 +52,6 @@ use rustc::hir::map::{blocks, NodePrinter};
use rustc::hir;
use rustc::hir::print as pprust_hir;
use rustc::mir::mir_map::MirMap;
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpSourceMode {
PpmNormal,
@ -234,7 +232,7 @@ impl PpSourceMode {
resolutions.clone(),
arenas,
id,
|tcx, _, _, _, _| {
|tcx, _, _, _| {
let annotation = TypedAnnotation {
tcx: tcx,
};
@ -695,7 +693,6 @@ impl fold::Folder for ReplaceBodyWithLoop {
fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir_map: Option<&MirMap<'tcx>>,
code: blocks::Code,
mode: PpFlowGraphMode,
mut out: W)
@ -725,7 +722,6 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
blocks::FnLikeCode(fn_like) => {
let (bccx, analysis_data) =
borrowck::build_borrowck_dataflow_data_for_fn(tcx,
mir_map,
fn_like.to_fn_parts(),
&cfg);
@ -952,32 +948,28 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
resolutions.clone(),
arenas,
crate_name,
|tcx, mir_map, _, _, _| {
|tcx, _, _, _| {
match ppm {
PpmMir | PpmMirCFG => {
if let Some(mir_map) = mir_map {
if let Some(nodeid) = nodeid {
let def_id = tcx.map.local_def_id(nodeid);
match ppm {
PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mir_map, &mut out),
PpmMirCFG => {
write_mir_graphviz(tcx, iter::once(def_id), &mir_map, &mut out)
}
_ => unreachable!(),
}?;
} else {
match ppm {
PpmMir => write_mir_pretty(tcx,
mir_map.map.keys().into_iter(),
&mir_map,
&mut out),
PpmMirCFG => write_mir_graphviz(tcx,
mir_map.map.keys().into_iter(),
&mir_map,
&mut out),
_ => unreachable!(),
}?;
}
if let Some(nodeid) = nodeid {
let def_id = tcx.map.local_def_id(nodeid);
match ppm {
PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mut out),
PpmMirCFG => {
write_mir_graphviz(tcx, iter::once(def_id), &mut out)
}
_ => unreachable!(),
}?;
} else {
match ppm {
PpmMir => write_mir_pretty(tcx,
tcx.mir_map.borrow().keys().into_iter(),
&mut out),
PpmMirCFG => write_mir_graphviz(tcx,
tcx.mir_map.borrow().keys().into_iter(),
&mut out),
_ => unreachable!(),
}?;
}
Ok(())
}
@ -995,12 +987,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
let out: &mut Write = &mut out;
print_flowgraph(variants,
tcx,
mir_map.as_ref(),
code,
mode,
out)
print_flowgraph(variants, tcx, code, mode, out)
}
None => {
let message = format!("--pretty=flowgraph needs block, fn, or method; got \

View File

@ -24,7 +24,6 @@ use rustc::dep_graph::DepNode;
use rustc::hir::map as hir_map;
use rustc::hir::map::DefKey;
use rustc::mir::Mir;
use rustc::mir::mir_map::MirMap;
use rustc::util::nodemap::{NodeSet, DefIdMap};
use rustc_back::PanicStrategy;
@ -467,10 +466,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x)
}
fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-> Option<Mir<'tcx>> {
fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx> {
self.dep_graph.read(DepNode::MetaData(def));
self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index)
self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index).unwrap_or_else(|| {
bug!("get_item_mir: missing MIR for {}", tcx.item_path_str(def))
})
}
fn is_item_mir_available(&self, def: DefId) -> bool {
@ -523,10 +523,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &MirMap<'tcx>) -> Vec<u8>
reachable: &NodeSet) -> Vec<u8>
{
encoder::encode_metadata(tcx, self, reexports, link_meta, reachable, mir_map)
encoder::encode_metadata(tcx, self, reexports, link_meta, reachable)
}
fn metadata_encoding_version(&self) -> &[u8]

View File

@ -22,7 +22,6 @@ use rustc::mir;
use rustc::traits::specialization_graph;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::mir::mir_map::MirMap;
use rustc::session::config::{self, CrateTypeProcMacro};
use rustc::util::nodemap::{FnvHashMap, NodeSet};
@ -51,7 +50,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
link_meta: &'a LinkMeta,
cstore: &'a cstore::CStore,
reachable: &'a NodeSet,
mir_map: &'a MirMap<'tcx>,
lazy_state: LazyState,
type_shorthands: FnvHashMap<Ty<'tcx>, usize>,
@ -606,7 +604,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}
fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
self.mir_map.map.get(&def_id).map(|mir| self.lazy(mir))
self.tcx.mir_map.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow()))
}
// Encodes the inherent implementations of a structure, enumeration, or trait.
@ -1346,8 +1344,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
cstore: &cstore::CStore,
reexports: &def::ExportMap,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &MirMap<'tcx>)
reachable: &NodeSet)
-> Vec<u8> {
let mut cursor = Cursor::new(vec![]);
cursor.write_all(METADATA_HEADER).unwrap();
@ -1362,7 +1359,6 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: link_meta,
cstore: cstore,
reachable: reachable,
mir_map: mir_map,
lazy_state: LazyState::NoNode,
type_shorthands: Default::default(),
predicate_shorthands: Default::default(),

View File

@ -11,7 +11,6 @@
use dot;
use rustc::hir::def_id::DefId;
use rustc::mir::*;
use rustc::mir::mir_map::MirMap;
use rustc::ty::TyCtxt;
use std::fmt::Debug;
use std::io::{self, Write};
@ -22,14 +21,13 @@ use rustc_data_structures::indexed_vec::Idx;
/// Write a graphviz DOT graph of a list of MIRs.
pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
iter: I,
mir_map: &MirMap<'tcx>,
w: &mut W)
-> io::Result<()>
where W: Write, I: Iterator<Item=DefId>
{
for def_id in iter {
let nodeid = tcx.map.as_local_node_id(def_id).unwrap();
let mir = &mir_map.map[&def_id];
let mir = &tcx.item_mir(def_id);
writeln!(w, "digraph Mir_{} {{", nodeid)?;

View File

@ -25,7 +25,6 @@ use rustc::mir::visit::MutVisitor;
use pretty;
use hair::cx::Cx;
use rustc::mir::mir_map::MirMap;
use rustc::infer::InferCtxtBuilder;
use rustc::traits::Reveal;
use rustc::ty::{self, Ty, TyCtxt};
@ -37,16 +36,10 @@ use syntax_pos::Span;
use std::mem;
pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MirMap<'tcx> {
let mut map = MirMap::new(tcx.dep_graph.clone());
{
let mut dump = BuildMir {
tcx: tcx,
map: &mut map,
};
tcx.visit_all_items_in_krate(DepNode::Mir, &mut dump);
}
map
pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
tcx.visit_all_items_in_krate(DepNode::Mir, &mut BuildMir {
tcx: tcx
});
}
/// A pass to lift all the types and substitutions in a Mir
@ -83,8 +76,7 @@ impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> {
// BuildMir -- walks a crate, looking for fn items and methods to build MIR from
struct BuildMir<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
map: &'a mut MirMap<'tcx>,
tcx: TyCtxt<'a, 'tcx, 'tcx>
}
/// Helper type of a temporary returned by BuildMir::cx(...).
@ -93,8 +85,7 @@ struct BuildMir<'a, 'tcx: 'a> {
struct CxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
src: MirSource,
def_id: DefId,
infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>,
map: &'a mut MirMap<'gcx>,
infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>
}
impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
@ -104,8 +95,7 @@ impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
CxBuilder {
src: src,
infcx: self.tcx.infer_ctxt(None, Some(param_env), Reveal::NotSpecializable),
def_id: def_id,
map: self.map
def_id: def_id
}
}
}
@ -114,13 +104,14 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
fn build<F>(&'tcx mut self, f: F)
where F: for<'b> FnOnce(Cx<'b, 'gcx, 'tcx>) -> (Mir<'tcx>, build::ScopeAuxiliaryVec)
{
let src = self.src;
let mir = self.infcx.enter(|infcx| {
let (src, def_id) = (self.src, self.def_id);
self.infcx.enter(|infcx| {
let (mut mir, scope_auxiliary) = f(Cx::new(&infcx, src));
// Convert the Mir to global types.
let tcx = infcx.tcx.global_tcx();
let mut globalizer = GlobalizeMir {
tcx: infcx.tcx.global_tcx(),
tcx: tcx,
span: mir.span
};
globalizer.visit_mir(&mut mir);
@ -128,13 +119,11 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
mem::transmute::<Mir, Mir<'gcx>>(mir)
};
pretty::dump_mir(infcx.tcx.global_tcx(), "mir_map", &0,
src, &mir, Some(&scope_auxiliary));
pretty::dump_mir(tcx, "mir_map", &0, src, &mir, Some(&scope_auxiliary));
mir
let mir = tcx.alloc_mir(mir);
assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none());
});
assert!(self.map.map.insert(self.def_id, mir).is_none())
}
}

View File

@ -12,7 +12,6 @@ use build::{ScopeAuxiliaryVec, ScopeId};
use rustc::hir;
use rustc::hir::def_id::DefId;
use rustc::mir::*;
use rustc::mir::mir_map::MirMap;
use rustc::mir::transform::MirSource;
use rustc::ty::TyCtxt;
use rustc_data_structures::fnv::FnvHashMap;
@ -90,14 +89,13 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
/// Write out a human-readable textual representation for the given MIR.
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
iter: I,
mir_map: &MirMap<'tcx>,
w: &mut Write)
-> io::Result<()>
where I: Iterator<Item=DefId>, 'tcx: 'a
{
let mut first = true;
for def_id in iter {
let mir = &mir_map.map[&def_id];
let mir = &tcx.item_mir(def_id);
if first {
first = false;

View File

@ -16,7 +16,6 @@
use rustc_data_structures::bitvec::BitVector;
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc::dep_graph::DepNode;
use rustc::hir;
use rustc::hir::map as hir_map;
use rustc::hir::def_id::DefId;
@ -26,9 +25,8 @@ use rustc::traits::{self, Reveal};
use rustc::ty::{self, TyCtxt, Ty};
use rustc::ty::cast::CastTy;
use rustc::mir::*;
use rustc::mir::mir_map::MirMap;
use rustc::mir::traversal::ReversePostorder;
use rustc::mir::transform::{Pass, MirMapPass, MirPassHook, MirSource};
use rustc::mir::transform::{Pass, MirPass, MirSource};
use rustc::mir::visit::{LvalueContext, Visitor};
use rustc::util::nodemap::DefIdMap;
use syntax::abi::Abi;
@ -142,7 +140,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
tcx: TyCtxt<'a, 'gcx, 'tcx>,
param_env: ty::ParameterEnvironment<'tcx>,
qualif_map: &'a mut DefIdMap<Qualif>,
mir_map: Option<&'a MirMap<'tcx>>,
temp_qualif: IndexVec<Local, Option<Qualif>>,
return_qualif: Option<Qualif>,
qualif: Qualif,
@ -155,7 +152,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
param_env: ty::ParameterEnvironment<'tcx>,
qualif_map: &'a mut DefIdMap<Qualif>,
mir_map: Option<&'a MirMap<'tcx>>,
def_id: DefId,
mir: &'a Mir<'tcx>,
mode: Mode)
@ -172,7 +168,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
tcx: tcx,
param_env: param_env,
qualif_map: qualif_map,
mir_map: mir_map,
temp_qualif: IndexVec::from_elem(None, &mir.local_decls),
return_qualif: None,
qualif: Qualif::empty(),
@ -595,7 +590,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
} else {
let qualif = qualify_const_item_cached(self.tcx,
self.qualif_map,
self.mir_map,
def_id);
self.add(qualif);
}
@ -949,7 +943,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
qualif_map: &mut DefIdMap<Qualif>,
mir_map: Option<&MirMap<'tcx>>,
def_id: DefId)
-> Qualif {
match qualif_map.entry(def_id) {
@ -960,124 +953,100 @@ fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
let extern_mir;
let param_env_and_mir = if def_id.is_local() {
mir_map.and_then(|map| map.map.get(&def_id)).map(|mir| {
let node_id = tcx.map.as_local_node_id(def_id).unwrap();
(ty::ParameterEnvironment::for_item(tcx, node_id), mir)
})
} else if let Some(mir) = tcx.sess.cstore.maybe_get_item_mir(tcx, def_id) {
// These should only be monomorphic constants.
extern_mir = mir;
Some((tcx.empty_parameter_environment(), &extern_mir))
let param_env = if def_id.is_local() {
let node_id = tcx.map.as_local_node_id(def_id).unwrap();
ty::ParameterEnvironment::for_item(tcx, node_id)
} else {
None
// These should only be monomorphic constants.
tcx.empty_parameter_environment()
};
let (param_env, mir) = param_env_and_mir.unwrap_or_else(|| {
bug!("missing constant MIR for {}", tcx.item_path_str(def_id))
});
let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, mir_map,
def_id, mir, Mode::Const);
let mir = &tcx.item_mir(def_id);
let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, def_id, mir, Mode::Const);
let qualif = qualifier.qualify_const();
qualifier.qualif_map.insert(def_id, qualif);
qualif
}
pub struct QualifyAndPromoteConstants;
#[derive(Default)]
pub struct QualifyAndPromoteConstants {
qualif_map: DefIdMap<Qualif>
}
impl Pass for QualifyAndPromoteConstants {}
impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
fn run_pass<'a>(&mut self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
map: &mut MirMap<'tcx>,
hooks: &mut [Box<for<'s> MirPassHook<'s>>]) {
let mut qualif_map = DefIdMap();
impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
src: MirSource, mir: &mut Mir<'tcx>) {
let id = src.item_id();
let def_id = tcx.map.local_def_id(id);
let mode = match src {
MirSource::Fn(_) => {
if is_const_fn(tcx, def_id) {
Mode::ConstFn
} else {
Mode::Fn
}
}
MirSource::Const(_) => {
match self.qualif_map.entry(def_id) {
Entry::Occupied(_) => return,
Entry::Vacant(entry) => {
// Guard against `const` recursion.
entry.insert(Qualif::RECURSIVE);
}
}
Mode::Const
}
MirSource::Static(_, hir::MutImmutable) => Mode::Static,
MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
MirSource::Promoted(..) => return
};
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
// First, visit `const` items, potentially recursing, to get
// accurate MUTABLE_INTERIOR and NEEDS_DROP qualifications.
let keys = map.map.keys();
for &def_id in &keys {
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
let id = tcx.map.as_local_node_id(def_id).unwrap();
let src = MirSource::from_node(tcx, id);
if let MirSource::Const(_) = src {
qualify_const_item_cached(tcx, &mut qualif_map, Some(map), def_id);
if mode == Mode::Fn || mode == Mode::ConstFn {
// This is ugly because Qualifier holds onto mir,
// which can't be mutated until its scope ends.
let (temps, candidates) = {
let mut qualifier = Qualifier::new(tcx, param_env,
&mut self.qualif_map,
def_id, mir, mode);
if mode == Mode::ConstFn {
// Enforce a constant-like CFG for `const fn`.
qualifier.qualify_const();
} else {
while let Some((bb, data)) = qualifier.rpo.next() {
qualifier.visit_basic_block_data(bb, data);
}
}
(qualifier.temp_promotion_state, qualifier.promotion_candidates)
};
// Do the actual promotion, now that we know what's viable.
promote_consts::promote_candidates(mir, tcx, temps, candidates);
} else {
let mut qualifier = Qualifier::new(tcx, param_env,
&mut self.qualif_map,
def_id, mir, mode);
let qualif = qualifier.qualify_const();
if mode == Mode::Const {
qualifier.qualif_map.insert(def_id, qualif);
}
}
// Then, handle everything else, without recursing,
// as the MIR map is not shared, since promotion
// in functions (including `const fn`) mutates it.
for &def_id in &keys {
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
let id = tcx.map.as_local_node_id(def_id).unwrap();
let src = MirSource::from_node(tcx, id);
let mode = match src {
MirSource::Fn(_) => {
if is_const_fn(tcx, def_id) {
Mode::ConstFn
} else {
Mode::Fn
}
// Statics must be Sync.
if mode == Mode::Static {
let ty = mir.return_ty;
tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
let mut fulfillment_cx = traits::FulfillmentContext::new();
fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
infcx.report_fulfillment_errors(&err);
}
MirSource::Const(_) => continue,
MirSource::Static(_, hir::MutImmutable) => Mode::Static,
MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
MirSource::Promoted(..) => bug!()
};
let param_env = ty::ParameterEnvironment::for_item(tcx, id);
let mir = map.map.get_mut(&def_id).unwrap();
for hook in &mut *hooks {
hook.on_mir_pass(tcx, src, mir, self, false);
}
if mode == Mode::Fn || mode == Mode::ConstFn {
// This is ugly because Qualifier holds onto mir,
// which can't be mutated until its scope ends.
let (temps, candidates) = {
let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
None, def_id, mir, mode);
if mode == Mode::ConstFn {
// Enforce a constant-like CFG for `const fn`.
qualifier.qualify_const();
} else {
while let Some((bb, data)) = qualifier.rpo.next() {
qualifier.visit_basic_block_data(bb, data);
}
}
(qualifier.temp_promotion_state,
qualifier.promotion_candidates)
};
// Do the actual promotion, now that we know what's viable.
promote_consts::promote_candidates(mir, tcx, temps, candidates);
} else {
let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
None, def_id, mir, mode);
qualifier.qualify_const();
}
for hook in &mut *hooks {
hook.on_mir_pass(tcx, src, mir, self, true);
}
// Statics must be Sync.
if mode == Mode::Static {
let ty = mir.return_ty;
tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
let mut fulfillment_cx = traits::FulfillmentContext::new();
fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
infcx.report_fulfillment_errors(&err);
}
});
}
});
}
}
}

View File

@ -44,7 +44,6 @@ use rustc::ty::adjustment::CustomCoerceUnsized;
use rustc::dep_graph::{DepNode, WorkProduct};
use rustc::hir::map as hir_map;
use rustc::util::common::time;
use rustc::mir::mir_map::MirMap;
use session::config::{self, NoDebugInfo};
use rustc_incremental::IncrementalHashesMap;
use session::Session;
@ -866,7 +865,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
false
};
let mir = def_id.and_then(|id| ccx.get_mir(id));
let mir = def_id.map(|id| ccx.tcx().item_mir(id));
let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) =
(no_debug, definition, &mir) {
@ -1278,8 +1277,7 @@ fn write_metadata(cx: &SharedCrateContext,
let metadata = cstore.encode_metadata(cx.tcx(),
cx.export_map(),
cx.link_meta(),
reachable_ids,
cx.mir_map());
reachable_ids);
if kind == MetadataKind::Uncompressed {
return metadata;
}
@ -1527,7 +1525,6 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
}
pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir_map: &MirMap<'tcx>,
analysis: ty::CrateAnalysis,
incremental_hashes_map: &IncrementalHashesMap)
-> CrateTranslation {
@ -1551,7 +1548,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let link_meta = link::build_link_meta(incremental_hashes_map, name);
let shared_ccx = SharedCrateContext::new(tcx,
&mir_map,
export_map,
Sha256::new(),
link_meta.clone(),

View File

@ -205,7 +205,6 @@ use rustc::mir::visit::Visitor as MirVisitor;
use rustc_const_eval as const_eval;
use syntax::abi::Abi;
use errors;
use syntax_pos::DUMMY_SP;
use base::custom_coerce_unsize_info;
use context::SharedCrateContext;
@ -346,8 +345,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
// Scan the MIR in order to find function calls, closures, and
// drop-glue
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
|| format!("Could not find MIR for static: {:?}", def_id));
let mir = scx.tcx().item_mir(def_id);
let empty_substs = scx.empty_substs_for_def_id(def_id);
let visitor = MirNeighborCollector {
@ -367,8 +365,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
// Scan the MIR in order to find function calls, closures, and
// drop-glue
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(instance.def),
|| format!("Could not find MIR for function: {}", instance));
let mir = scx.tcx().item_mir(instance.def);
let visitor = MirNeighborCollector {
scx: scx,
@ -451,11 +448,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
match *rvalue {
mir::Rvalue::Aggregate(mir::AggregateKind::Closure(def_id,
ref substs), _) => {
let mir = errors::expect(self.scx.sess().diagnostic(),
self.scx.get_mir(def_id),
|| {
format!("Could not find MIR for closure: {:?}", def_id)
});
let mir = self.scx.tcx().item_mir(def_id);
let concrete_substs = monomorphize::apply_param_substs(self.scx,
self.param_substs,
@ -1248,8 +1241,7 @@ fn collect_const_item_neighbours<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
{
// Scan the MIR in order to find function calls, closures, and
// drop-glue
let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
|| format!("Could not find MIR for const: {:?}", def_id));
let mir = scx.tcx().item_mir(def_id);
let visitor = MirNeighborCollector {
scx: scx,

View File

@ -19,6 +19,7 @@ use llvm::{True, False, Bool, OperandBundleDef};
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::infer::TransNormalize;
use rustc::mir::Mir;
use rustc::util::common::MemoizationMap;
use middle::lang_items::LangItem;
use rustc::ty::subst::Substs;
@ -32,7 +33,6 @@ use consts;
use debuginfo::{self, DebugLoc};
use declare;
use machine;
use mir::CachedMir;
use monomorphize;
use type_::Type;
use value::Value;
@ -46,7 +46,7 @@ use arena::TypedArena;
use libc::{c_uint, c_char};
use std::ops::Deref;
use std::ffi::CString;
use std::cell::{Cell, RefCell};
use std::cell::{Cell, RefCell, Ref};
use syntax::ast;
use syntax::parse::token::InternedString;
@ -250,10 +250,8 @@ pub fn validate_substs(substs: &Substs) {
// Function context. Every LLVM function we create will have one of
// these.
pub struct FunctionContext<'a, 'tcx: 'a> {
// The MIR for this function. At present, this is optional because
// we only have MIR available for things that are local to the
// crate.
pub mir: Option<CachedMir<'a, 'tcx>>,
// The MIR for this function.
pub mir: Option<Ref<'tcx, Mir<'tcx>>>,
// The ValueRef returned from a call to llvm::LLVMAddFunction; the
// address of the first instruction in the sequence of
@ -313,8 +311,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
}
impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
pub fn mir(&self) -> CachedMir<'a, 'tcx> {
self.mir.clone().expect("fcx.mir was empty")
pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
self.mir.as_ref().map(Ref::clone).expect("fcx.mir was empty")
}
pub fn cleanup(&self) {
@ -490,7 +488,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
self.set_lpad_ref(lpad.map(|p| &*self.fcx().lpad_arena.alloc(p)))
}
pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
self.fcx.mir()
}
@ -609,7 +607,7 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
self.bcx.llbb
}
pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
self.bcx.mir()
}

View File

@ -15,15 +15,12 @@ use middle::cstore::LinkMeta;
use rustc::hir::def::ExportMap;
use rustc::hir::def_id::DefId;
use rustc::traits;
use rustc::mir::mir_map::MirMap;
use rustc::mir;
use base;
use builder::Builder;
use common::BuilderRef_res;
use debuginfo;
use declare;
use glue::DropGlueKind;
use mir::CachedMir;
use monomorphize::Instance;
use partitioning::CodegenUnit;
@ -76,8 +73,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
stats: Stats,
check_overflow: bool,
mir_map: &'a MirMap<'tcx>,
mir_cache: RefCell<DepTrackingMap<MirCache<'tcx>>>,
use_dll_storage_attrs: bool,
@ -184,19 +179,6 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> {
}
}
// Cache for mir loaded from metadata
struct MirCache<'tcx> {
data: PhantomData<&'tcx ()>
}
impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> {
type Key = DefId;
type Value = Rc<mir::Mir<'tcx>>;
fn to_dep_node(key: &DefId) -> DepNode<DefId> {
DepNode::Mir(*key)
}
}
// # Global Cache
pub struct ProjectionCache<'gcx> {
@ -453,7 +435,6 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
mir_map: &'b MirMap<'tcx>,
export_map: ExportMap,
symbol_hasher: Sha256,
link_meta: LinkMeta,
@ -517,8 +498,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
link_meta: link_meta,
symbol_hasher: RefCell::new(symbol_hasher),
tcx: tcx,
mir_map: mir_map,
mir_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
stats: Stats {
n_glues_created: Cell::new(0),
n_null_glues: Cell::new(0),
@ -582,23 +561,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
self.use_dll_storage_attrs
}
pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
if def_id.is_local() {
self.mir_map.map.get(&def_id).map(CachedMir::Ref)
} else {
if let Some(mir) = self.mir_cache.borrow().get(&def_id).cloned() {
return Some(CachedMir::Owned(mir));
}
let mir = self.sess().cstore.maybe_get_item_mir(self.tcx, def_id);
let cached = mir.map(Rc::new);
if let Some(ref mir) = cached {
self.mir_cache.borrow_mut().insert(def_id, mir.clone());
}
cached.map(CachedMir::Owned)
}
}
pub fn translation_items(&self) -> &RefCell<FnvHashSet<TransItem<'tcx>>> {
&self.translation_items
}
@ -617,10 +579,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
&self.symbol_hasher
}
pub fn mir_map(&self) -> &MirMap<'tcx> {
&self.mir_map
}
pub fn metadata_symbol_name(&self) -> String {
format!("rust_metadata_{}_{}",
self.link_meta().crate_name,
@ -1008,10 +966,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
self.shared.use_dll_storage_attrs()
}
pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
self.shared.get_mir(def_id)
}
pub fn symbol_map(&self) -> &SymbolMap<'tcx> {
&*self.local().symbol_map
}

View File

@ -45,7 +45,7 @@ impl MirDebugScope {
/// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
/// If debuginfo is disabled, the returned vector is empty.
pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, MirDebugScope> {
let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn");
let mir = fcx.mir();
let null_scope = MirDebugScope {
scope_metadata: ptr::null_mut(),
file_start_pos: BytePos(0),

View File

@ -25,6 +25,7 @@
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(cell_extras)]
#![feature(const_fn)]
#![feature(custom_attribute)]
#![feature(dotdot_in_tuple_patterns)]

View File

@ -261,9 +261,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
}
}
let mir = ccx.get_mir(instance.def).unwrap_or_else(|| {
bug!("missing constant MIR for {}", instance)
});
let mir = ccx.tcx().item_mir(instance.def);
MirConstContext::new(ccx, &mir, instance.substs, args).trans()
}

View File

@ -23,8 +23,7 @@ use type_of;
use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
use syntax::parse::token::keywords;
use std::ops::Deref;
use std::rc::Rc;
use std::cell::Ref;
use std::iter;
use basic_block::BasicBlock;
@ -39,25 +38,9 @@ use rustc::mir::traversal;
use self::operand::{OperandRef, OperandValue};
#[derive(Clone)]
pub enum CachedMir<'mir, 'tcx: 'mir> {
Ref(&'mir mir::Mir<'tcx>),
Owned(Rc<mir::Mir<'tcx>>)
}
impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> {
type Target = mir::Mir<'tcx>;
fn deref(&self) -> &mir::Mir<'tcx> {
match *self {
CachedMir::Ref(r) => r,
CachedMir::Owned(ref rc) => rc
}
}
}
/// Master context for translating MIR.
pub struct MirContext<'bcx, 'tcx:'bcx> {
mir: CachedMir<'bcx, 'tcx>,
mir: Ref<'tcx, mir::Mir<'tcx>>,
/// Function context
fcx: &'bcx common::FunctionContext<'bcx, 'tcx>,
@ -223,7 +206,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
let scopes = debuginfo::create_mir_scopes(fcx);
let mut mircx = MirContext {
mir: mir.clone(),
mir: Ref::clone(&mir),
fcx: fcx,
llpersonalityslot: None,
blocks: block_bcxs,

View File

@ -189,7 +189,7 @@ pub fn run_core(search_paths: SearchPaths,
resolutions,
&arenas,
&name,
|tcx, _, analysis, _, result| {
|tcx, analysis, _, result| {
if let Err(_) = result {
sess.fatal("Compilation failed, aborting rustdoc");
}