rustc: move the MIR map into TyCtxt.
This commit is contained in:
parent
36340ba994
commit
e34792b181
@ -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") }
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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) => (
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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())),
|
||||
|
@ -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>> }
|
||||
|
@ -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).
|
||||
|
@ -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, ¶m_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> {
|
||||
|
@ -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)]
|
||||
|
@ -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",
|
||||
|
@ -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 \
|
||||
|
@ -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]
|
||||
|
@ -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(),
|
||||
|
@ -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)?;
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cell_extras)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(custom_attribute)]
|
||||
#![feature(dotdot_in_tuple_patterns)]
|
||||
|
@ -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()
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user