Fix remaining compilation issues

This commit is contained in:
Paul Daniel Faria
2019-10-27 21:15:02 -04:00
parent fc6b58d0a8
commit 4de31b26d1
20 changed files with 102 additions and 50 deletions

View File

@@ -151,6 +151,16 @@ impl BodyCache<'tcx> {
}
}
#[macro_export]
macro_rules! read_only {
($body_cache:expr) => {
{
$body_cache.ensure_predecessors();
$body_cache.unwrap_read_only()
}
};
}
impl BodyCache<'tcx> {
pub fn ensure_predecessors(&mut self) {
self.cache.ensure_predecessors(&self.body);
@@ -160,12 +170,8 @@ impl BodyCache<'tcx> {
self.cache.predecessors(&self.body)
}
pub fn read_only(&self) -> ReadOnlyBodyCache<'_, '_> {
assert!(self.cache.predecessors.is_some(), "");
ReadOnlyBodyCache {
cache: &self.cache,
body: &self.body,
}
pub fn unwrap_read_only(&self) -> ReadOnlyBodyCache<'_, 'tcx> {
ReadOnlyBodyCache::new(&self.cache, &self.body)
}
pub fn body(&self) -> &Body<'tcx> {
@@ -176,6 +182,8 @@ impl BodyCache<'tcx> {
&mut self.body
}
pub fn cache(&self) -> &Cache { &self.cache }
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
self.cache.basic_blocks_mut(&mut self.body)
}
@@ -223,6 +231,24 @@ pub struct ReadOnlyBodyCache<'a, 'tcx> {
}
impl ReadOnlyBodyCache<'a, 'tcx> {
fn new(cache: &'a Cache, body: &'a Body<'tcx>) -> Self {
assert!(
cache.predecessors.is_some(),
"Cannot construct ReadOnlyBodyCache without computed predecessors");
Self {
cache,
body,
}
}
pub fn from_external_cache(cache: &'a mut Cache, body: &'a Body<'tcx>) -> Self {
cache.ensure_predecessors(body);
Self {
cache,
body,
}
}
#[inline]
pub fn predecessors(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
self.cache.predecessors.as_ref().unwrap()

View File

@@ -38,7 +38,9 @@ use syntax::symbol::Symbol;
use syntax_pos::{Span, DUMMY_SP};
pub use crate::mir::interpret::AssertMessage;
pub use crate::mir::cache::{BodyCache, ReadOnlyBodyCache};
// TODO(nashenas88) Cache only exported for use in librustc_mir/transform/check_unsafety.rs
pub use crate::mir::cache::{BodyCache, Cache, ReadOnlyBodyCache};
pub use crate::read_only;
pub mod cache;
pub mod interpret;

View File

@@ -147,7 +147,13 @@ rustc_queries! {
crate::mir::Promoted,
crate::mir::BodyCache<'tcx>
>> = tcx.queries.on_disk_cache.try_load_query_result(tcx, id);
promoted.map(|p| &*tcx.arena.alloc(p))
promoted.map(|p| {
let cache = tcx.arena.alloc(p);
for body_cache in cache.iter_mut() {
body_cache.ensure_predecessors();
}
&*cache
})
}
}
}

View File

@@ -2988,7 +2988,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> ReadOnlyBodyCache<'tcx, 'tcx> {
match instance {
ty::InstanceDef::Item(did) => {
self.optimized_mir(did).read_only()
self.optimized_mir(did).unwrap_read_only()
}
ty::InstanceDef::VtableShim(..) |
ty::InstanceDef::ReifyShim(..) |
@@ -2998,7 +2998,7 @@ impl<'tcx> TyCtxt<'tcx> {
ty::InstanceDef::ClosureOnceShim { .. } |
ty::InstanceDef::DropGlue(..) |
ty::InstanceDef::CloneShim(..) => {
self.mir_shims(instance).read_only()
self.mir_shims(instance).unwrap_read_only()
}
}
}

View File

@@ -1080,12 +1080,14 @@ impl<'a, 'tcx> CrateMetadata {
}
fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> BodyCache<'tcx> {
self.root.per_def.mir.get(self, id)
let mut cache = self.root.per_def.mir.get(self, id)
.filter(|_| !self.is_proc_macro(id))
.unwrap_or_else(|| {
bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id))
})
.decode((self, tcx))
.decode((self, tcx));
cache.ensure_predecessors();
cache
}
fn get_promoted_mir(
@@ -1093,12 +1095,16 @@ impl<'a, 'tcx> CrateMetadata {
tcx: TyCtxt<'tcx>,
id: DefIndex,
) -> IndexVec<Promoted, BodyCache<'tcx>> {
self.root.per_def.promoted_mir.get(self, id)
let mut cache = self.root.per_def.promoted_mir.get(self, id)
.filter(|_| !self.is_proc_macro(id))
.unwrap_or_else(|| {
bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id))
})
.decode((self, tcx))
.decode((self, tcx));
for body_cache in cache.iter_mut() {
body_cache.ensure_predecessors();
}
cache
}
fn mir_const_qualif(&self, id: DefIndex) -> mir::ConstQualifs {

View File

@@ -10,7 +10,7 @@ use rustc::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT};
use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
use rustc::mir::{
ClearCrossCrate, Local, Location, Body, BodyCache, Mutability, Operand, Place, PlaceBase,
PlaceElem, PlaceRef, ReadOnlyBodyCache, Static, StaticKind
PlaceElem, PlaceRef, ReadOnlyBodyCache, Static, StaticKind, read_only
};
use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
use rustc::mir::{Terminator, TerminatorKind};
@@ -167,8 +167,8 @@ fn do_mir_borrowck<'a, 'tcx>(
let mut body_cache = BodyCache::new(body);
let free_regions =
nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body_cache, &mut promoted);
let body_cache = body_cache.read_only(); // no further changes
let promoted: IndexVec<_, _> = promoted.iter().map(|body_cache| body_cache.read_only()).collect();
let body_cache = read_only!(body_cache); // no further changes
let promoted: IndexVec<_, _> = promoted.iter_mut().map(|body_cache| read_only!(body_cache)).collect();
let location_table = &LocationTable::new(&body_cache);
@@ -492,7 +492,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
type FlowState = Flows<'cx, 'tcx>;
fn body(&self) -> &'cx Body<'tcx> {
&self.body_cache
self.body_cache.body()
}
fn visit_block_entry(&mut self, bb: BasicBlock, flow_state: &Self::FlowState) {

View File

@@ -302,7 +302,8 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
}
}
for &pred_block in self.cx.body_cache.predecessors_for(block).iter() {
let body_cache = self.cx.body_cache;
for &pred_block in body_cache.predecessors_for(block).iter() {
debug!("compute_drop_live_points_for_block: pred_block = {:?}", pred_block,);
// Check whether the variable is (at least partially)

View File

@@ -540,7 +540,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
// checker on the promoted MIR, then transfer the constraints back to
// the main MIR, changing the locations to the provided location.
let parent_body = mem::replace(&mut self.body, &promoted_body_cache);
let parent_body = mem::replace(&mut self.body, promoted_body_cache.body());
// Use new sets of constraints and closure bounds so that we can
// modify their locations.

View File

@@ -56,7 +56,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Prefixes {
next: Some(place_ref),
kind,
body: &self.body_cache,
body: self.body_cache.body(),
tcx: self.infcx.tcx,
}
}

View File

@@ -303,11 +303,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
if let Some(promoted) = promoted {
return Ok(self.tcx.promoted_mir(did)[promoted].read_only());
return Ok(self.tcx.promoted_mir(did)[promoted].unwrap_read_only());
}
match instance {
ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
Ok(self.tcx.optimized_mir(did).read_only())
Ok(self.tcx.optimized_mir(did).unwrap_read_only())
} else {
throw_unsup!(NoMirFor(self.tcx.def_path_str(def_id)))
},

View File

@@ -125,6 +125,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
debug!("make_shim({:?}) = {:?}", instance, result.body());
result.ensure_predecessors();
tcx.arena.alloc(result)
}
@@ -928,5 +929,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &BodyCache<'_> {
|_, _| Ok(()),
);
tcx.arena.alloc(BodyCache::new(body))
let mut body_cache = BodyCache::new(body);
body_cache.ensure_predecessors();
tcx.arena.alloc(body_cache)
}

View File

@@ -516,7 +516,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult
// N.B., this borrow is valid because all the consumers of
// `mir_built` force this.
let body = &tcx.mir_built(def_id).borrow();
let body_cache = &tcx.mir_built(def_id).borrow();
let param_env = tcx.param_env(def_id);
@@ -527,8 +527,10 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult
hir::BodyOwnerKind::Const |
hir::BodyOwnerKind::Static(_) => (true, false),
};
let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env);
checker.visit_body(body.read_only());
let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body_cache, tcx, param_env);
let mut cache = body_cache.cache().clone();
let read_only_cache = ReadOnlyBodyCache::from_external_cache(&mut cache, body_cache.body());
checker.visit_body(read_only_cache);
check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks);
UnsafetyCheckResult {

View File

@@ -10,7 +10,7 @@ use rustc::mir::{
AggregateKind, Constant, Location, Place, PlaceBase, Body, BodyCache, Operand, Local, UnOp,
Rvalue. StatementKind, Statement, LocalKind, TerminatorKind, Terminator, ClearCrossCrate,
SourceInfo, BinOp, SourceScope, SourceScopeData, LocalDecl, BasicBlock, ReadOnlyBodyCache,
RETURN_PLACE
read_only, RETURN_PLACE
};
use rustc::mir::visit::{
Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
@@ -93,7 +93,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
// That would require an uniform one-def no-mutation analysis
// and RPO (or recursing when needing the value of a local).
let mut optimization_finder = ConstPropagator::new(
body_cache.read_only(),
read_only!(body_cache),
dummy_body,
tcx,
source
@@ -285,7 +285,7 @@ impl<'mir, 'tcx> HasTyCtxt<'tcx> for ConstPropagator<'mir, 'tcx> {
impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
fn new(
body_cache: ReadOnlyBodyCache<'mir, 'tcx>,
body_cache: ReadOnlyBodyCache<'_, 'tcx>,
dummy_body: &'mir Body<'tcx>,
tcx: TyCtxt<'tcx>,
source: MirSource<'tcx>,

View File

@@ -21,7 +21,7 @@
use rustc::mir::{
Constant, Local, LocalKind, Location, Place, Body, BodyCache, Operand, Rvalue,
StatementKind
StatementKind, read_only
};
use rustc::mir::visit::MutVisitor;
use rustc::ty::TyCtxt;
@@ -40,10 +40,10 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
let mut def_use_analysis = DefUseAnalysis::new(body_cache);
loop {
def_use_analysis.analyze(body_cache.read_only());
def_use_analysis.analyze(read_only!(body_cache));
if eliminate_self_assignments(body_cache, &def_use_analysis) {
def_use_analysis.analyze(body_cache.read_only());
def_use_analysis.analyze(read_only!(body_cache));
}
let mut changed = false;

View File

@@ -759,7 +759,7 @@ fn compute_layout<'tcx>(
// Use a liveness analysis to compute locals which are live across a suspension point
let LivenessInfo {
live_locals, live_locals_at_suspension_points, storage_conflicts, storage_liveness
} = locals_live_across_suspend_points(tcx, body_cache.read_only(), source, movable);
} = locals_live_across_suspend_points(tcx, read_only!(body_cache), source, movable);
// Erase regions from the types passed in from typeck so we can compare them with
// MIR types

View File

@@ -514,7 +514,7 @@ impl Inliner<'tcx> {
&self,
args: Vec<Operand<'tcx>>,
callsite: &CallSite<'tcx>,
caller_body: &mut Body<'tcx>,
caller_body_cache: &mut BodyCache<'tcx>,
) -> Vec<Local> {
let tcx = self.tcx;
@@ -543,12 +543,12 @@ impl Inliner<'tcx> {
// and the vector is `[closure_ref, tmp0, tmp1, tmp2]`.
if tcx.is_closure(callsite.callee) {
let mut args = args.into_iter();
let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body);
let self_ = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body_cache);
let tuple = self.create_temp_if_necessary(args.next().unwrap(), callsite, caller_body_cache);
assert!(args.next().is_none());
let tuple = Place::from(tuple);
let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_body, tcx).ty.kind {
let tuple_tys = if let ty::Tuple(s) = tuple.ty(caller_body_cache.body(), tcx).ty.kind {
s
} else {
bug!("Closure arguments are not passed as a tuple");
@@ -568,13 +568,13 @@ impl Inliner<'tcx> {
));
// Spill to a local to make e.g., `tmp0`.
self.create_temp_if_necessary(tuple_field, callsite, caller_body)
self.create_temp_if_necessary(tuple_field, callsite, caller_body_cache)
});
closure_ref_arg.chain(tuple_tmp_args).collect()
} else {
args.into_iter()
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body))
.map(|a| self.create_temp_if_necessary(a, callsite, caller_body_cache))
.collect()
}
}
@@ -585,14 +585,14 @@ impl Inliner<'tcx> {
&self,
arg: Operand<'tcx>,
callsite: &CallSite<'tcx>,
caller_body: &mut Body<'tcx>,
caller_body_cache: &mut BodyCache<'tcx>,
) -> Local {
// FIXME: Analysis of the usage of the arguments to avoid
// unnecessary temporaries.
if let Operand::Move(place) = &arg {
if let Some(local) = place.as_local() {
if caller_body.local_kind(local) == LocalKind::Temp {
if caller_body_cache.local_kind(local) == LocalKind::Temp {
// Reuse the operand if it's a temporary already
return local;
}
@@ -603,16 +603,16 @@ impl Inliner<'tcx> {
// Otherwise, create a temporary for the arg
let arg = Rvalue::Use(arg);
let ty = arg.ty(caller_body, self.tcx);
let ty = arg.ty(caller_body_cache.body(), self.tcx);
let arg_tmp = LocalDecl::new_temp(ty, callsite.location.span);
let arg_tmp = caller_body.local_decls.push(arg_tmp);
let arg_tmp = caller_body_cache.local_decls.push(arg_tmp);
let stmt = Statement {
source_info: callsite.location,
kind: StatementKind::Assign(box(Place::from(arg_tmp), arg)),
};
caller_body[callsite.bb].statements.push(stmt);
caller_body_cache[callsite.bb].statements.push(stmt);
arg_tmp
}
}

View File

@@ -2,7 +2,7 @@
use rustc::mir::{
Constant, Location, Place, PlaceBase, PlaceRef, Body, BodyCache, Operand, ProjectionElem,
Rvalue, Local
Rvalue, Local, read_only
};
use rustc::mir::visit::{MutVisitor, Visitor};
use rustc::ty::{self, TyCtxt};
@@ -24,8 +24,9 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
// read-only so that we can do global analyses on the MIR in the process (e.g.
// `Place::ty()`).
let optimizations = {
let read_only_cache = read_only!(body_cache);
let mut optimization_finder = OptimizationFinder::new(body_cache, tcx);
optimization_finder.visit_body(body_cache.read_only());
optimization_finder.visit_body(read_only_cache);
optimization_finder.optimizations
};

View File

@@ -334,6 +334,7 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &BodyCache<'_> {
let (body, _) = tcx.mir_validated(def_id);
let mut body_cache = body.steal();
run_optimization_passes(tcx, &mut body_cache, def_id, None);
body_cache.ensure_predecessors();
tcx.arena.alloc(body_cache)
}
@@ -348,6 +349,7 @@ fn promoted_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx IndexVec<Promot
for (p, mut body_cache) in promoted.iter_enumerated_mut() {
run_optimization_passes(tcx, &mut body_cache, def_id, Some(p));
body_cache.ensure_predecessors();
}
tcx.intern_promoted(promoted)

View File

@@ -296,11 +296,12 @@ impl<'tcx> MirPass<'tcx> for SimplifyLocals {
fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) {
trace!("running SimplifyLocals on {:?}", source);
let locals = {
let read_only_cache = read_only!(body_cache);
let mut marker = DeclMarker {
locals: BitSet::new_empty(body_cache.local_decls.len()),
body: body_cache,
};
marker.visit_body(body_cache.read_only());
marker.visit_body(read_only_cache);
// Return pointer and arguments are always live
marker.locals.insert(RETURN_PLACE);
for arg in body_cache.args_iter() {

View File

@@ -41,8 +41,9 @@ impl<'tcx> MirPass<'tcx> for UniformArrayMoveOut {
let mut patch = MirPatch::new(body_cache);
let param_env = tcx.param_env(src.def_id());
{
let read_only_cache = read_only!(body_cache);
let mut visitor = UniformArrayMoveOutVisitor{ body: body_cache, patch: &mut patch, tcx, param_env};
visitor.visit_body(body_cache.read_only());
visitor.visit_body(read_only_cache);
}
patch.apply(body_cache);
}
@@ -188,11 +189,12 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut<'tcx> {
let mut patch = MirPatch::new(body_cache);
let param_env = tcx.param_env(src.def_id());
{
let read_only_cache = read_only!(body_cache);
let mut visitor = RestoreDataCollector {
locals_use: IndexVec::from_elem(LocalUse::new(), &body_cache.local_decls),
candidates: vec![],
};
visitor.visit_body(body_cache.read_only());
visitor.visit_body(read_only_cache);
for candidate in &visitor.candidates {
let statement = &body_cache[candidate.block].statements[candidate.statement_index];