From 649c73f96d8969f05000a071007bcd050fa8d466 Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Thu, 10 Oct 2019 23:16:44 -0400 Subject: [PATCH] Simplify Cache wrapper to single type, impl Deref on it, fix all compilation errors in librustc_codegen_ssa --- src/librustc/mir/cache.rs | 82 +++++++++---------- src/librustc/mir/mod.rs | 7 +- src/librustc/mir/visit.rs | 23 +++--- src/librustc_codegen_ssa/base.rs | 5 +- src/librustc_codegen_ssa/mir/analyze.rs | 40 +++++---- src/librustc_codegen_ssa/mir/block.rs | 12 +-- src/librustc_codegen_ssa/mir/mod.rs | 16 ++-- src/librustc_codegen_ssa/mir/place.rs | 2 +- src/librustc_codegen_ssa/mir/rvalue.rs | 6 +- src/librustc_mir/borrow_check/mod.rs | 48 +++++------ .../borrow_check/nll/type_check/mod.rs | 8 +- src/librustc_mir/shim.rs | 12 --- .../transform/ensure_predecessors_cache.rs | 26 ------ src/librustc_mir/transform/generator.rs | 4 - src/librustc_mir/transform/mod.rs | 3 - 15 files changed, 132 insertions(+), 162 deletions(-) delete mode 100644 src/librustc_mir/transform/ensure_predecessors_cache.rs diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index 4300a5acba4f..e218931b7491 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -6,7 +6,7 @@ use crate::mir::{BasicBlock, BasicBlockData, Body, LocalDecls, Location, Success use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use std::iter; -use std::ops::{Index, IndexMut}; +use std::ops::{Deref, DerefMut, Index, IndexMut}; use std::vec::IntoIter; #[derive(Clone, Debug)] @@ -111,33 +111,21 @@ impl Cache { } } -pub struct OwningCache<'tcx> { +pub struct BodyCache { cache: Cache, - body: Body<'tcx>, + body: T, } -impl<'tcx> OwningCache<'tcx> { - pub fn borrow(&mut self) -> BorrowedCache<'_, 'tcx> { - BorrowedCache { - cache: &mut self.cache, - body: &self.body, - } - } - - pub fn borrow_mut(&mut self) -> MutCache<'_, 'tcx> { - MutCache { - cache: &mut self.cache, - body: &mut self.body, +impl BodyCache { + pub fn new(body: T) -> Self { + Self { + cache: Cache::new(), + body } } } -pub struct BorrowedCache<'a, 'tcx> { - cache: &'a mut Cache, - body: &'a Body<'tcx> -} - -impl<'a, 'tcx> BorrowedCache<'a, 'tcx> { +impl<'a, 'tcx> BodyCache<&'a Body<'tcx>> { #[inline] pub fn predecessors_for(&mut self, bb: BasicBlock) -> &[BasicBlock] { self.cache.predecessors_for(bb, self.body) @@ -159,7 +147,14 @@ impl<'a, 'tcx> BorrowedCache<'a, 'tcx> { } } -impl<'a, 'tcx> Index for BorrowedCache<'a, 'tcx> { +impl<'a, 'tcx> Deref for BodyCache<&'a Body<'tcx>> { + type Target = Body<'tcx>; + fn deref(&self) -> &Body<'tcx> { + self.body + } +} + +impl<'a, 'tcx> Index for BodyCache<&'a Body<'tcx>> { type Output = BasicBlockData<'tcx>; #[inline] @@ -168,16 +163,16 @@ impl<'a, 'tcx> Index for BorrowedCache<'a, 'tcx> { } } -impl<'a, 'tcx> graph::DirectedGraph for BorrowedCache<'a, 'tcx> { +impl<'a, 'tcx> graph::DirectedGraph for BodyCache<&'a Body<'tcx>> { type Node = BasicBlock; } -impl<'a, 'graph, 'tcx> graph::GraphPredecessors<'graph> for BorrowedCache<'a, 'tcx> { +impl<'a, 'graph, 'tcx> graph::GraphPredecessors<'graph> for BodyCache<&'a Body<'tcx>> { type Item = BasicBlock; type Iter = IntoIter; } -impl<'a, 'tcx> graph::WithPredecessors for BorrowedCache<'a, 'tcx> { +impl<'a, 'tcx> graph::WithPredecessors for BodyCache<&'a Body<'tcx>> { fn predecessors( &mut self, node: Self::Node, @@ -186,19 +181,19 @@ impl<'a, 'tcx> graph::WithPredecessors for BorrowedCache<'a, 'tcx> { } } -impl<'a, 'tcx> graph::WithNumNodes for BorrowedCache<'a, 'tcx> { +impl<'a, 'tcx> graph::WithNumNodes for BodyCache<&'a Body<'tcx>> { fn num_nodes(&self) -> usize { self.body.num_nodes() } } -impl<'a, 'tcx> graph::WithStartNode for BorrowedCache<'a, 'tcx> { +impl<'a, 'tcx> graph::WithStartNode for BodyCache<&'a Body<'tcx>> { fn start_node(&self) -> Self::Node { self.body.start_node() } } -impl<'a, 'tcx> graph::WithSuccessors for BorrowedCache<'a, 'tcx> { +impl<'a, 'tcx> graph::WithSuccessors for BodyCache<&'a Body<'tcx>> { fn successors( &self, node: Self::Node, @@ -207,17 +202,12 @@ impl<'a, 'tcx> graph::WithSuccessors for BorrowedCache<'a, 'tcx> { } } -impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for BorrowedCache<'a, 'tcx> { +impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for BodyCache<&'a Body<'tcx>> { type Item = BasicBlock; type Iter = iter::Cloned>; } -pub struct MutCache<'a, 'tcx> { - cache: &'a mut Cache, - body: &'a mut Body<'tcx>, -} - -impl<'a, 'tcx> MutCache<'a, 'tcx> { +impl<'a, 'tcx> BodyCache<&'a mut Body<'tcx>> { #[inline] pub fn body(&mut self) -> &mut Body<'tcx> { self.body @@ -234,7 +224,21 @@ impl<'a, 'tcx> MutCache<'a, 'tcx> { } } -impl<'a, 'tcx> Index for MutCache<'a, 'tcx> { +impl<'a, 'tcx> Deref for BodyCache<&'a mut Body<'tcx>> { + type Target = Body<'tcx>; + + fn deref(&self) -> &Body<'tcx> { + self.body + } +} + +impl<'a, 'tcx> DerefMut for BodyCache<&'a mut Body<'tcx>> { + fn deref_mut(&mut self) -> &mut Body<'tcx> { + self.body + } +} + +impl<'a, 'tcx> Index for BodyCache<&'a mut Body<'tcx>> { type Output = BasicBlockData<'tcx>; #[inline] @@ -243,13 +247,9 @@ impl<'a, 'tcx> Index for MutCache<'a, 'tcx> { } } -impl<'a, 'tcx> IndexMut for MutCache<'a, 'tcx> { +impl<'a, 'tcx> IndexMut for BodyCache<&'a mut Body<'tcx>> { fn index_mut(&mut self, index: BasicBlock) -> &mut Self::Output { self.cache.invalidate_predecessors(); &mut self.body.basic_blocks[index] } } - -//CloneTypeFoldableAndLiftImpls! { -// Cache, -//} diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index fa435b9a51b8..9f7184057638 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -38,6 +38,7 @@ use syntax::symbol::Symbol; use syntax_pos::{Span, DUMMY_SP}; pub use crate::mir::interpret::AssertMessage; +pub use crate::mir::cache::BodyCache; pub mod cache; pub mod interpret; @@ -2596,7 +2597,11 @@ impl Location { } /// Returns `true` if `other` is earlier in the control flow graph than `self`. - pub fn is_predecessor_of<'tcx>(&self, other: Location, mut body_cache: cache::BorrowedCache<'_, 'tcx>) -> bool { + pub fn is_predecessor_of<'tcx>( + &self, + other: Location, + mut body_cache: BodyCache<&'_ Body<'tcx>> + ) -> bool { // If we are in the same block as the other location and are an earlier statement // then we are a predecessor of `other`. if self.block == other.block && self.statement_index < other.statement_index { diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index fbcfe1048395..5803663bbecd 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -1,7 +1,6 @@ use crate::ty::subst::SubstsRef; use crate::ty::{CanonicalUserTypeAnnotation, Ty}; use crate::mir::*; -use crate::mir::cache::*; use syntax_pos::Span; // # The MIR Visitor @@ -72,7 +71,10 @@ macro_rules! make_mir_visitor { // Override these, and call `self.super_xxx` to revert back to the // default behavior. - fn visit_body(&mut self, body_cache: & $($mutability)? cache_type!('tcx $($mutability)?)) { + fn visit_body( + &mut self, + body_cache: & $($mutability)? BodyCache<&'_ $($mutability)? Body<'tcx>> + ) { self.super_body(body_cache); } @@ -241,8 +243,10 @@ macro_rules! make_mir_visitor { // The `super_xxx` methods comprise the default behavior and are // not meant to be overridden. - fn super_body(&mut self, - body_cache: & $($mutability)? cache_type!('tcx $($mutability)?)) { + fn super_body( + &mut self, + body_cache: & $($mutability)? BodyCache<&'_ $($mutability)? Body<'tcx>> + ) { let span = body_cache.body().span; if let Some(yield_ty) = &$($mutability)? body_cache.body().yield_ty { self.visit_ty(yield_ty, TyContext::YieldTy(SourceInfo { @@ -793,7 +797,11 @@ macro_rules! make_mir_visitor { // Convenience methods - fn visit_location(&mut self, body_cache: & $($mutability)? cache_type!('tcx $($mutability)?), location: Location) { + fn visit_location( + &mut self, + body_cache: & $($mutability)? BodyCache<&'_ $($mutability)? Body<'tcx>>, + location: Location + ) { let basic_block = & $($mutability)? body_cache[location.block]; if basic_block.statements.len() == location.statement_index { if let Some(ref $($mutability)? terminator) = basic_block.terminator { @@ -809,11 +817,6 @@ macro_rules! make_mir_visitor { } } -macro_rules! cache_type { - ($tcx:lifetime mut) => {MutCache<'_, $tcx>}; - ($tcx:lifetime) => {BorrowedCache<'_, $tcx>}; -} - macro_rules! visit_place_fns { (mut) => ( fn tcx<'a>(&'a self) -> TyCtxt<'tcx>; diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index 22693beb855d..d67a9d3799ea 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -31,6 +31,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::cstore::EncodedMetadata; use rustc::middle::lang_items::StartFnLangItem; use rustc::middle::weak_lang_items; +use rustc::mir::BodyCache; use rustc::mir::mono::{CodegenUnitNameBuilder, CodegenUnit, MonoItem}; use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; @@ -374,7 +375,9 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let lldecl = cx.get_fn(instance); let mir = cx.tcx().instance_mir(instance.def); - mir::codegen_mir::(cx, lldecl, &mir, instance, sig); + // TODO(nashenas88) move this into instance_mir before merging PR + let mut mir = BodyCache::new(mir); + mir::codegen_mir::(cx, lldecl, &mut mir, instance, sig); } /// Creates the `main` function which will initialize the rust runtime and call diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index e44551fcbcdf..7a2940a8e673 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -4,7 +4,7 @@ use rustc_index::bit_set::BitSet; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::vec::{Idx, IndexVec}; -use rustc::mir::{self, Location, TerminatorKind}; +use rustc::mir::{self, Body, BodyCache, Location, TerminatorKind}; use rustc::mir::visit::{ Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext, NonUseContext, }; @@ -17,10 +17,10 @@ use super::FunctionCx; use crate::traits::*; pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - fx: &FunctionCx<'a, 'tcx, Bx>, + fx: &mut FunctionCx<'a, 'tcx, Bx>, ) -> BitSet { - let mir = fx.mir; - let mut analyzer = LocalAnalyzer::new(fx); + let mir = fx.mir.take().unwrap(); + let mut analyzer = LocalAnalyzer::new(fx, mir); analyzer.visit_body(mir); @@ -54,11 +54,14 @@ pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( } } - analyzer.non_ssa_locals + let (mir, non_ssa_locals) = analyzer.finalize(); + fx.mir = Some(mir); + non_ssa_locals } struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { fx: &'mir FunctionCx<'a, 'tcx, Bx>, + mir: &'a mut BodyCache<&'a Body<'tcx>>, dominators: Dominators, non_ssa_locals: BitSet, // The location of the first visited direct assignment to each @@ -67,27 +70,32 @@ struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { } impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { - fn new(fx: &'mir FunctionCx<'a, 'tcx, Bx>) -> Self { + fn new(fx: &'mir FunctionCx<'a, 'tcx, Bx>, mir: &'a mut BodyCache<&'a Body<'tcx>>) -> Self { let invalid_location = - mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location(); + mir::BasicBlock::new(mir.basic_blocks().len()).start_location(); let mut analyzer = LocalAnalyzer { fx, - dominators: fx.mir.dominators(), - non_ssa_locals: BitSet::new_empty(fx.mir.local_decls.len()), - first_assignment: IndexVec::from_elem(invalid_location, &fx.mir.local_decls) + dominators: mir.dominators(), + mir, + non_ssa_locals: BitSet::new_empty(mir.local_decls.len()), + first_assignment: IndexVec::from_elem(invalid_location, &mir.local_decls) }; // Arguments get assigned to by means of the function being called - for arg in fx.mir.args_iter() { + for arg in mir.args_iter() { analyzer.first_assignment[arg] = mir::START_BLOCK.start_location(); } analyzer } + fn finalize(self) -> (&'a mut BodyCache<&'a Body<'tcx>>, BitSet) { + (self.mir, self.non_ssa_locals) + } + fn first_assignment(&self, local: mir::Local) -> Option { let location = self.first_assignment[local]; - if location.block.index() < self.fx.mir.basic_blocks().len() { + if location.block.index() < self.mir.basic_blocks().len() { Some(location) } else { None @@ -130,7 +138,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { }; if is_consume { let base_ty = - mir::Place::ty_from(place_ref.base, proj_base, self.fx.mir, cx.tcx()); + mir::Place::ty_from(place_ref.base, proj_base, self.mir.body(), cx.tcx()); let base_ty = self.fx.monomorphize(&base_ty); // ZSTs don't require any actual memory access. @@ -139,7 +147,7 @@ impl> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { .ty; let elem_ty = self.fx.monomorphize(&elem_ty); let span = if let mir::PlaceBase::Local(index) = place_ref.base { - self.fx.mir.local_decls[*index].source_info.span + self.mir.local_decls[*index].source_info.span } else { DUMMY_SP }; @@ -243,7 +251,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> if let Some(index) = place.as_local() { self.assign(index, location); - let decl_span = self.fx.mir.local_decls[index].source_info.span; + let decl_span = self.mir.local_decls[index].source_info.span; if !self.fx.rvalue_creates_operand(rvalue, decl_span) { self.not_ssa(index); } @@ -348,7 +356,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> } PlaceContext::MutatingUse(MutatingUseContext::Drop) => { - let ty = self.fx.mir.local_decls[local].ty; + let ty = self.mir.local_decls[local].ty; let ty = self.fx.monomorphize(&ty); // Only need the place if we're actually dropping it. diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index d76392f7570b..d09ff0160db1 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -132,7 +132,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { } else { let llret = bx.call(fn_ptr, &llargs, self.funclet(fx)); bx.apply_attrs_callsite(&fn_abi, llret); - if fx.mir[*self.bb].is_cleanup { + if fx.mir.unwrap()[*self.bb].is_cleanup { // Cleanup is always the cold path. Don't inline // drop glue. Also, when there is a deeply-nested // struct, there are "symmetry" issues that cause @@ -324,7 +324,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { target: mir::BasicBlock, unwind: Option, ) { - let ty = location.ty(self.mir, bx.tcx()).ty; + let ty = location.ty(self.mir.unwrap().body(), bx.tcx()).ty; let ty = self.monomorphize(&ty); let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty); @@ -510,7 +510,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let extra_args = &args[sig.inputs().len()..]; let extra_args = extra_args.iter().map(|op_arg| { - let op_ty = op_arg.ty(self.mir, bx.tcx()); + let op_ty = op_arg.ty(self.mir.unwrap().body(), bx.tcx()); self.monomorphize(&op_ty) }).collect::>(); @@ -791,7 +791,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bb: mir::BasicBlock, ) { let mut bx = self.build_block(bb); - let data = &self.mir[bb]; + let data = &self.mir.unwrap()[bb]; debug!("codegen_block({:?}={:?})", bb, data); @@ -1053,7 +1053,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { target_bb: Bx::BasicBlock ) -> Bx::BasicBlock { if base::wants_msvc_seh(self.cx.sess()) { - span_bug!(self.mir.span, "landing pad was not inserted?") + span_bug!(self.mir.unwrap().span, "landing pad was not inserted?") } let mut bx = self.new_block("cleanup"); @@ -1154,7 +1154,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // // If someone changes that, please update this code path // to create a temporary. - span_bug!(self.mir.span, "can't directly store to unaligned value"); + span_bug!(self.mir.unwrap().span, "can't directly store to unaligned value"); } llargs.push(dest.llval); ReturnDest::Nothing diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index 6041232489d0..8b1278672380 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -1,6 +1,6 @@ use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{TyLayout, HasTyCtxt, FnAbiExt}; -use rustc::mir::{self, Body}; +use rustc::mir::{self, Body, BodyCache}; use rustc_target::abi::call::{FnAbi, PassMode}; use crate::base; use crate::traits::*; @@ -21,7 +21,7 @@ use self::operand::{OperandRef, OperandValue}; pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { instance: Instance<'tcx>, - mir: &'a mir::Body<'tcx>, + mir: Option<&'a mut BodyCache<&'a mir::Body<'tcx>>>, debug_context: Option>, @@ -122,7 +122,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, llfn: Bx::Function, - mir: &'a Body<'tcx>, + mir: &'a mut BodyCache<&'a Body<'tcx>>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, ) { @@ -159,7 +159,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let mut fx = FunctionCx { instance, - mir, + mir: Some(mir), llfn, fn_abi, cx, @@ -174,7 +174,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( per_local_var_debug_info: debuginfo::per_local_var_debug_info(cx.tcx(), mir), }; - let memory_locals = analyze::non_ssa_locals(&fx); + let memory_locals = analyze::non_ssa_locals(&mut fx); // Allocate variable and temp allocas fx.locals = { @@ -327,10 +327,10 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let mut idx = 0; let mut llarg_idx = fx.fn_abi.ret.is_indirect() as usize; - mir.args_iter().enumerate().map(|(arg_index, local)| { - let arg_decl = &mir.local_decls[local]; + mir.unwrap().args_iter().enumerate().map(|(arg_index, local)| { + let arg_decl = &mir.unwrap().local_decls[local]; - if Some(local) == mir.spread_arg { + if Some(local) == mir.unwrap().spread_arg { // This argument (e.g., the last argument in the "rust-call" ABI) // is a tuple that was spread at the ABI level and now we have // to reconstruct it into a tuple local variable, from multiple diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 4df5bce95377..8f3c1de9c644 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -591,7 +591,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn monomorphized_place_ty(&self, place_ref: &mir::PlaceRef<'_, 'tcx>) -> Ty<'tcx> { let tcx = self.cx.tcx(); - let place_ty = mir::Place::ty_from(place_ref.base, place_ref.projection, self.mir, tcx); + let place_ty = mir::Place::ty_from(place_ref.base, place_ref.projection, self.mir.unwrap().body(), tcx); self.monomorphize(&place_ty.ty) } } diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index f7fb4a571401..c1519b6106df 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -460,7 +460,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } mir::Rvalue::Discriminant(ref place) => { - let discr_ty = rvalue.ty(&*self.mir, bx.tcx()); + let discr_ty = rvalue.ty(self.mir.unwrap().body(), bx.tcx()); let discr = self.codegen_place(&mut bx, &place.as_ref()) .codegen_get_discr(&mut bx, discr_ty); (bx, OperandRef { @@ -513,7 +513,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::Aggregate(..) => { // According to `rvalue_creates_operand`, only ZST // aggregate rvalues are allowed to be operands. - let ty = rvalue.ty(self.mir, self.cx.tcx()); + let ty = rvalue.ty(self.mir.unwrap().body(), self.cx.tcx()); let operand = OperandRef::new_zst( &mut bx, self.cx.layout_of(self.monomorphize(&ty)), @@ -710,7 +710,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { true, mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => { - let ty = rvalue.ty(self.mir, self.cx.tcx()); + let ty = rvalue.ty(self.mir.unwrap().body(), self.cx.tcx()); let ty = self.monomorphize(&ty); self.cx.spanned_layout_of(ty, span).is_zst() } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 63a8de5eebac..f861a423ae26 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -9,8 +9,8 @@ use rustc::lint::builtin::UNUSED_MUT; use rustc::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT}; use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{ - ClearCrossCrate, Local, Location, Body, Mutability, Operand, Place, PlaceBase, PlaceElem, - PlaceRef, Static, StaticKind + ClearCrossCrate, Local, Location, Body, BodyCache, Mutability, Operand, Place, PlaceBase, + PlaceElem, PlaceRef, Static, StaticKind }; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; @@ -167,16 +167,12 @@ fn do_mir_borrowck<'a, 'tcx>( let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted); - // Region replacement above very likely invalidated the predecessors cache. It's used later on - // when retrieving the dominators from the body, so we need to ensure it exists before locking - // the body for changes. - body.ensure_predecessors(); - let body = &body; // no further changes - let location_table = &LocationTable::new(body); + let body_cache = &BodyCache::new(&body); // no further changes + let location_table = &LocationTable::new(body_cache); let mut errors_buffer = Vec::new(); let (move_data, move_errors): (MoveData<'tcx>, Option, MoveError<'tcx>)>>) = - match MoveData::gather_moves(body, tcx) { + match MoveData::gather_moves(body_cache, tcx) { Ok(move_data) => (move_data, None), Err((move_data, move_errors)) => (move_data, Some(move_errors)), }; @@ -186,27 +182,27 @@ fn do_mir_borrowck<'a, 'tcx>( param_env, }; - let dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); + let dead_unwinds = BitSet::new_empty(body_cache.basic_blocks().len()); let mut flow_inits = FlowAtLocation::new(do_dataflow( tcx, - body, + body_cache, def_id, &attributes, &dead_unwinds, - MaybeInitializedPlaces::new(tcx, body, &mdpe), + MaybeInitializedPlaces::new(tcx, body_cache, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]), )); let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure(); let borrow_set = Rc::new(BorrowSet::build( - tcx, body, locals_are_invalidated_at_exit, &mdpe.move_data)); + tcx, body_cache, locals_are_invalidated_at_exit, &mdpe.move_data)); // If we are in non-lexical mode, compute the non-lexical lifetimes. let (regioncx, polonius_output, opt_closure_req) = nll::compute_regions( infcx, def_id, free_regions, - body, + body_cache, &promoted, &local_names, &upvars, @@ -227,29 +223,29 @@ fn do_mir_borrowck<'a, 'tcx>( let flow_borrows = FlowAtLocation::new(do_dataflow( tcx, - body, + body_cache, def_id, &attributes, &dead_unwinds, - Borrows::new(tcx, body, param_env, regioncx.clone(), &borrow_set), + Borrows::new(tcx, body_cache, param_env, regioncx.clone(), &borrow_set), |rs, i| DebugFormatted::new(&rs.location(i)), )); let flow_uninits = FlowAtLocation::new(do_dataflow( tcx, - body, + body_cache, def_id, &attributes, &dead_unwinds, - MaybeUninitializedPlaces::new(tcx, body, &mdpe), + MaybeUninitializedPlaces::new(tcx, body_cache, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]), )); let flow_ever_inits = FlowAtLocation::new(do_dataflow( tcx, - body, + body_cache, def_id, &attributes, &dead_unwinds, - EverInitializedPlaces::new(tcx, body, &mdpe), + EverInitializedPlaces::new(tcx, body_cache, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().inits[i]), )); @@ -261,11 +257,11 @@ fn do_mir_borrowck<'a, 'tcx>( _ => true, }; - let dominators = body.dominators(); + let dominators = body_cache.dominators(); let mut mbcx = MirBorrowckCtxt { infcx, - body, + body_cache, mir_def_id: def_id, param_env, move_data: &mdpe.move_data, @@ -403,7 +399,7 @@ fn do_mir_borrowck<'a, 'tcx>( crate struct MirBorrowckCtxt<'cx, 'tcx> { crate infcx: &'cx InferCtxt<'cx, 'tcx>, - body: &'cx Body<'tcx>, + body_cache: BodyCache<&'cx Body<'tcx>>, mir_def_id: DefId, param_env: ty::ParamEnv<'tcx>, move_data: &'cx MoveData<'tcx>, @@ -494,7 +490,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx type FlowState = Flows<'cx, 'tcx>; fn body(&self) -> &'cx Body<'tcx> { - self.body + self.body_cache } fn visit_block_entry(&mut self, bb: BasicBlock, flow_state: &Self::FlowState) { @@ -644,7 +640,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx let tcx = self.infcx.tcx; // Compute the type with accurate region information. - let drop_place_ty = drop_place.ty(self.body, self.infcx.tcx); + let drop_place_ty = drop_place.ty(self.body_cache, self.infcx.tcx); // Erase the regions. let drop_place_ty = self.infcx.tcx.erase_regions(&drop_place_ty).ty; @@ -988,7 +984,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut error_reported = false; let tcx = self.infcx.tcx; - let body = self.body; + let body = self.body_cache; let param_env = self.param_env; let location_table = self.location_table.start_index(location); let borrow_set = self.borrow_set.clone(); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 99bcfa9bc259..4f95aa4a7b00 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -385,15 +385,15 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } - fn visit_body(&mut self, body: &Body<'tcx>) { - self.sanitize_type(&"return type", body.return_ty()); - for local_decl in &body.local_decls { + fn visit_body(&mut self, body_cache: &BodyCache<&'_ Body<'tcx>>) { + self.sanitize_type(&"return type", body_cache.return_ty()); + for local_decl in &body_cache.local_decls { self.sanitize_type(local_decl, local_decl.ty); } if self.errors_reported { return; } - self.super_body(body); + self.super_body(body_cache); } } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 938d3f8ce976..734e1a5972e4 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -123,17 +123,6 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx &add_call_guards::CriticalCallEdges, ]); - // The `ensure_predecessors_cache::EnsurePredecessorsCache` MirPass wasn't used in the - // `run_passes` above because the above pass is not always guaranteed to run. There can be - // instances where, e.g. a `MirPhase::Validated` pass has already been run on a `Body` by the - // time it arrived at this line, and so the above `run_passes` call will NOT run any of the - // passes (They do not run if a same or later pass has already been executed on a `Body`). - // Adding the ensure pass during the `run_passes` for `MirPhase::Validated` would not - // help because the predecessors cache would be invalidated between that pass and this call. - // Having the single ensure outside of the `run_passes` list here guarantees that anyone - // using this `Body` could call `Body::unwrap_predecessors()` without worrying about a panic. - result.ensure_predecessors(); - debug!("make_shim({:?}) = {:?}", instance, result); tcx.arena.alloc(result) @@ -926,7 +915,6 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { sig.inputs().len(), span, ); - body.ensure_predecessors(); crate::util::dump_mir( tcx, diff --git a/src/librustc_mir/transform/ensure_predecessors_cache.rs b/src/librustc_mir/transform/ensure_predecessors_cache.rs deleted file mode 100644 index db1ef863351c..000000000000 --- a/src/librustc_mir/transform/ensure_predecessors_cache.rs +++ /dev/null @@ -1,26 +0,0 @@ -use rustc::mir::Body; -use rustc::ty::TyCtxt; -use crate::transform::{MirPass, MirSource}; - -pub struct EnsurePredecessorsCache { - label: String, -} - -impl EnsurePredecessorsCache { - pub fn new>(label: S) -> Self { - Self { - label: label.into(), - } - } -} - -impl<'tcx> MirPass<'tcx> for EnsurePredecessorsCache { - fn run_pass(&self, _: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { - debug!("{}: Ensure predecessors cache: {:?}", self.label, body.span.data()); - // predecessors is lazily calculated. We want to ensure that the cache is properly filled - // before the next stages of compilation, since these following stages will only be allowed - // to read the cache and not generate it. If the cache is already up to date, this line is - // a nop. - body.ensure_predecessors(); - } -} diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 8c11d66fb48c..37205e65a0a4 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -1203,10 +1203,6 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // RETURN_PLACE then is a fresh unused local with type ret_ty. let new_ret_local = replace_result_variable(ret_ty, body, tcx); - // Replacing result variables very likely clears the predecessors cache (needed inside of - // compute layout), so we need to ensure the cache exists. - body.ensure_predecessors(); - // Extract locals which are live across suspension point into `layout` // `remap` gives a mapping from local indices onto generator struct indices // `storage_liveness` tells us which locals have live storage at suspension points diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index e80fb9361707..1eac40fc591a 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -20,7 +20,6 @@ pub mod check_unsafety; pub mod simplify_branches; pub mod simplify_try; pub mod simplify; -pub mod ensure_predecessors_cache; pub mod erase_regions; pub mod no_landing_pads; pub mod rustc_peek; @@ -251,7 +250,6 @@ fn mir_validated( &simplify::SimplifyCfg::new("qualify-consts"), ]); - body.ensure_predecessors(); let promoted = promote_pass.promoted_fragments.into_inner(); (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted)) } @@ -316,7 +314,6 @@ fn run_optimization_passes<'tcx>( &simplify::SimplifyLocals, &add_call_guards::CriticalCallEdges, - &ensure_predecessors_cache::EnsurePredecessorsCache::new("before-opt-dump"), &dump_mir::Marker("PreCodegen"), ]); }