Account for new maybe_sideeffect helper that requires predecessors
This commit is contained in:
parent
c8c266a0fb
commit
2eed90a621
10 changed files with 176 additions and 133 deletions
|
@ -47,8 +47,7 @@ impl Cache {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
/// This will recompute the predecessors cache if it is not available
|
||||
pub fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
pub fn ensure_predecessors(&mut self, body: &Body<'_>) {
|
||||
if self.predecessors.is_none() {
|
||||
let mut result = IndexVec::from_elem(vec![], body.basic_blocks());
|
||||
for (bb, data) in body.basic_blocks().iter_enumerated() {
|
||||
|
@ -61,7 +60,12 @@ impl Cache {
|
|||
|
||||
self.predecessors = Some(result)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// This will recompute the predecessors cache if it is not available
|
||||
pub fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
|
||||
self.ensure_predecessors(body);
|
||||
self.predecessors.as_ref().unwrap()
|
||||
}
|
||||
|
||||
|
@ -70,6 +74,11 @@ impl Cache {
|
|||
&self.predecessors(body)[bb]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn unwrap_predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
|
||||
&self.predecessors.as_ref().unwrap()[bb]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn predecessor_locations<'a>(&'a mut self, loc: Location, body: &'a Body<'a>) -> impl Iterator<Item = Location> + 'a {
|
||||
let if_zero_locations = if loc.statement_index == 0 {
|
||||
|
@ -137,13 +146,17 @@ impl<'a, 'tcx> BodyCache<&'a Body<'tcx>> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
|
||||
&self.body.basic_blocks
|
||||
pub fn read_only(mut self) -> ReadOnlyBodyCache<'a, 'tcx> {
|
||||
self.cache.ensure_predecessors(self.body);
|
||||
ReadOnlyBodyCache {
|
||||
cache: self.cache,
|
||||
body: self.body,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dominators(&mut self) -> Dominators<BasicBlock> {
|
||||
dominators(self)
|
||||
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
|
||||
&self.body.basic_blocks
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,50 +177,6 @@ impl<'a, 'tcx> Index<BasicBlock> for BodyCache<&'a Body<'tcx>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> graph::DirectedGraph for BodyCache<&'a Body<'tcx>> {
|
||||
type Node = BasicBlock;
|
||||
}
|
||||
|
||||
impl<'a, 'graph, 'tcx> graph::GraphPredecessors<'graph> for BodyCache<&'a Body<'tcx>> {
|
||||
type Item = BasicBlock;
|
||||
type Iter = IntoIter<BasicBlock>;
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> graph::WithPredecessors for BodyCache<&'a Body<'tcx>> {
|
||||
fn predecessors(
|
||||
&mut self,
|
||||
node: Self::Node,
|
||||
) -> <Self as GraphPredecessors<'_>>::Iter {
|
||||
self.predecessors_for(node).to_vec().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
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 BodyCache<&'a Body<'tcx>> {
|
||||
fn start_node(&self) -> Self::Node {
|
||||
self.body.start_node()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> graph::WithSuccessors for BodyCache<&'a Body<'tcx>> {
|
||||
fn successors(
|
||||
&self,
|
||||
node: Self::Node,
|
||||
) -> <Self as GraphSuccessors<'_>>::Iter {
|
||||
self.body.successors(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for BodyCache<&'a Body<'tcx>> {
|
||||
type Item = BasicBlock;
|
||||
type Iter = iter::Cloned<Successors<'b>>;
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> BodyCache<&'a mut Body<'tcx>> {
|
||||
#[inline]
|
||||
pub fn body(&self) -> &Body<'tcx> {
|
||||
|
@ -259,3 +228,99 @@ impl<'a, 'tcx> IndexMut<BasicBlock> for BodyCache<&'a mut Body<'tcx>> {
|
|||
&mut self.body.basic_blocks[index]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReadOnlyBodyCache<'a, 'tcx> {
|
||||
cache: Cache,
|
||||
body: &'a Body<'tcx>,
|
||||
}
|
||||
|
||||
impl ReadOnlyBodyCache<'a, 'tcx> {
|
||||
#[inline]
|
||||
pub fn predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
|
||||
self.cache.unwrap_predecessors_for(bb)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn body(&self) -> &'a Body<'tcx> {
|
||||
self.body
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
|
||||
&self.body.basic_blocks
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dominators(&self) -> Dominators<BasicBlock> {
|
||||
dominators(self)
|
||||
}
|
||||
|
||||
pub fn to_owned(self) -> BodyCache<&'a Body<'tcx>> {
|
||||
BodyCache {
|
||||
cache: self.cache,
|
||||
body: self.body,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl graph::DirectedGraph for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
type Node = BasicBlock;
|
||||
}
|
||||
|
||||
impl graph::GraphPredecessors<'graph> for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
type Item = BasicBlock;
|
||||
type Iter = IntoIter<BasicBlock>;
|
||||
}
|
||||
|
||||
impl graph::WithPredecessors for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
fn predecessors(
|
||||
&self,
|
||||
node: Self::Node,
|
||||
) -> <Self as GraphPredecessors<'_>>::Iter {
|
||||
self.cache.unwrap_predecessors_for(node).to_vec().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl graph::WithNumNodes for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
fn num_nodes(&self) -> usize {
|
||||
self.body.num_nodes()
|
||||
}
|
||||
}
|
||||
|
||||
impl graph::WithStartNode for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
fn start_node(&self) -> Self::Node {
|
||||
self.body.start_node()
|
||||
}
|
||||
}
|
||||
|
||||
impl graph::WithSuccessors for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
fn successors(
|
||||
&self,
|
||||
node: Self::Node,
|
||||
) -> <Self as GraphSuccessors<'_>>::Iter {
|
||||
self.body.successors(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
type Item = BasicBlock;
|
||||
type Iter = iter::Cloned<Successors<'b>>;
|
||||
}
|
||||
|
||||
|
||||
impl Deref for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
type Target = Body<'tcx>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.body
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<BasicBlock> for ReadOnlyBodyCache<'a, 'tcx> {
|
||||
type Output = BasicBlockData<'tcx>;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
|
||||
&self.body[index]
|
||||
}
|
||||
}
|
|
@ -38,7 +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 use crate::mir::cache::{BodyCache, ReadOnlyBodyCache};
|
||||
|
||||
pub mod cache;
|
||||
pub mod interpret;
|
||||
|
@ -2600,7 +2600,7 @@ impl Location {
|
|||
pub fn is_predecessor_of<'tcx>(
|
||||
&self,
|
||||
other: Location,
|
||||
mut body_cache: BodyCache<&'_ Body<'tcx>>
|
||||
body_cache: &ReadOnlyBodyCache<'_, '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`.
|
||||
|
|
|
@ -65,6 +65,15 @@ use syntax_pos::Span;
|
|||
// variant argument) that does not require visiting, as in
|
||||
// `is_cleanup` above.
|
||||
|
||||
macro_rules! body_cache_type {
|
||||
(mut $a:lifetime, $tcx:lifetime) => {
|
||||
&mut BodyCache<& $a mut Body<$tcx>>
|
||||
};
|
||||
($a:lifetime, $tcx:lifetime) => {
|
||||
&ReadOnlyBodyCache<$a, $tcx>
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! make_mir_visitor {
|
||||
($visitor_trait_name:ident, $($mutability:ident)?) => {
|
||||
pub trait $visitor_trait_name<'tcx> {
|
||||
|
@ -73,7 +82,7 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
fn visit_body(
|
||||
&mut self,
|
||||
body_cache: & $($mutability)? BodyCache<&'_ $($mutability)? Body<'tcx>>
|
||||
body_cache: body_cache_type!($($mutability)? '_, 'tcx)
|
||||
) {
|
||||
self.super_body(body_cache);
|
||||
}
|
||||
|
@ -245,7 +254,7 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
fn super_body(
|
||||
&mut self,
|
||||
body_cache: & $($mutability)? BodyCache<&'_ $($mutability)? Body<'tcx>>
|
||||
body_cache: body_cache_type!($($mutability)? '_, 'tcx)
|
||||
) {
|
||||
macro_rules! body {
|
||||
(mut) => (body_cache.body_mut());
|
||||
|
|
|
@ -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, Body, BodyCache, Location, TerminatorKind};
|
||||
use rustc::mir::{self, Location, TerminatorKind};
|
||||
use rustc::mir::visit::{
|
||||
Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext, NonUseContext,
|
||||
};
|
||||
|
@ -16,15 +16,14 @@ use syntax_pos::DUMMY_SP;
|
|||
use super::FunctionCx;
|
||||
use crate::traits::*;
|
||||
|
||||
pub fn non_ssa_locals<'a, 'b, 'c, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
fx: &FunctionCx<'a, 'b, 'tcx, Bx>,
|
||||
mir: &'c mut BodyCache<&'b Body<'tcx>>,
|
||||
pub fn non_ssa_locals<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
fx: &FunctionCx<'a, 'b, 'tcx, Bx>
|
||||
) -> BitSet<mir::Local> {
|
||||
let mut analyzer = LocalAnalyzer::new(fx, mir);
|
||||
let mut analyzer = LocalAnalyzer::new(fx);
|
||||
|
||||
analyzer.visit_body(mir);
|
||||
analyzer.visit_body(fx.mir);
|
||||
|
||||
for (local, decl) in mir.local_decls.iter_enumerated()
|
||||
for (local, decl) in fx.mir.local_decls.iter_enumerated()
|
||||
{
|
||||
// FIXME(eddyb): We should figure out how to use llvm.dbg.value instead
|
||||
// of putting everything in allocas just so we can use llvm.dbg.declare.
|
||||
|
@ -66,20 +65,20 @@ struct LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
|||
first_assignment: IndexVec<mir::Local, Location>,
|
||||
}
|
||||
|
||||
impl<'mir, 'a, 'b, 'c, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx> {
|
||||
fn new(fx: &'mir FunctionCx<'a, 'b, 'tcx, Bx>, mir: &'c mut BodyCache<&'b Body<'tcx>>) -> Self {
|
||||
impl<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx> {
|
||||
fn new(fx: &'mir FunctionCx<'a, 'b, 'tcx, Bx>) -> Self {
|
||||
let invalid_location =
|
||||
mir::BasicBlock::new(mir.basic_blocks().len()).start_location();
|
||||
let dominators = mir.dominators();
|
||||
mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location();
|
||||
let dominators = fx.mir.dominators();
|
||||
let mut analyzer = LocalAnalyzer {
|
||||
fx,
|
||||
dominators,
|
||||
non_ssa_locals: BitSet::new_empty(mir.local_decls.len()),
|
||||
first_assignment: IndexVec::from_elem(invalid_location, &mir.local_decls)
|
||||
non_ssa_locals: BitSet::new_empty(fx.mir.local_decls.len()),
|
||||
first_assignment: IndexVec::from_elem(invalid_location, &fx.mir.local_decls)
|
||||
};
|
||||
|
||||
// Arguments get assigned to by means of the function being called
|
||||
for arg in mir.args_iter() {
|
||||
for arg in fx.mir.args_iter() {
|
||||
analyzer.first_assignment[arg] = mir::START_BLOCK.start_location();
|
||||
}
|
||||
|
||||
|
@ -131,7 +130,7 @@ impl<'mir, 'a, 'b, 'c, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, '
|
|||
};
|
||||
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.fx.mir.body(), cx.tcx());
|
||||
let base_ty = self.fx.monomorphize(&base_ty);
|
||||
|
||||
// ZSTs don't require any actual memory access.
|
||||
|
|
|
@ -153,7 +153,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> {
|
|||
// a loop.
|
||||
fn maybe_sideeffect<'b, 'tcx2: 'b, Bx: BuilderMethods<'b, 'tcx2>>(
|
||||
&self,
|
||||
mir: &'b mir::Body<'tcx>,
|
||||
mir: &mir::ReadOnlyBodyCache<'_, 'tcx>,
|
||||
bx: &mut Bx,
|
||||
targets: &[mir::BasicBlock],
|
||||
) {
|
||||
|
@ -216,7 +216,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
let lltrue = helper.llblock(self, targets[0]);
|
||||
let llfalse = helper.llblock(self, targets[1]);
|
||||
if switch_ty == bx.tcx().types.bool {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice());
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, targets.as_slice());
|
||||
// Don't generate trivial icmps when switching on bool
|
||||
if let [0] = values[..] {
|
||||
bx.cond_br(discr.immediate(), llfalse, lltrue);
|
||||
|
@ -230,11 +230,11 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
);
|
||||
let llval = bx.const_uint_big(switch_llty, values[0]);
|
||||
let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval);
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice());
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, targets.as_slice());
|
||||
bx.cond_br(cmp, lltrue, llfalse);
|
||||
}
|
||||
} else {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice());
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, targets.as_slice());
|
||||
let (otherwise, targets) = targets.split_last().unwrap();
|
||||
bx.switch(
|
||||
discr.immediate(),
|
||||
|
@ -324,13 +324,13 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
target: mir::BasicBlock,
|
||||
unwind: Option<mir::BasicBlock>,
|
||||
) {
|
||||
let ty = location.ty(self.mir, bx.tcx()).ty;
|
||||
let ty = location.ty(self.mir.body(), bx.tcx()).ty;
|
||||
let ty = self.monomorphize(&ty);
|
||||
let drop_fn = Instance::resolve_drop_in_place(bx.tcx(), ty);
|
||||
|
||||
if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def {
|
||||
// we don't actually need to drop anything.
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.funclet_br(self, &mut bx, target);
|
||||
return
|
||||
}
|
||||
|
@ -361,7 +361,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
FnAbi::of_instance(&bx, drop_fn))
|
||||
}
|
||||
};
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.do_call(self, &mut bx, fn_ty, drop_fn, args,
|
||||
Some((ReturnDest::Nothing, target)),
|
||||
unwind);
|
||||
|
@ -397,7 +397,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
|
||||
// Don't codegen the panic block if success if known.
|
||||
if const_cond == Some(expected) {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.funclet_br(self, &mut bx, target);
|
||||
return;
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
// Create the failure block and the conditional branch to it.
|
||||
let lltarget = helper.llblock(self, target);
|
||||
let panic_block = self.new_block("panic");
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
if expected {
|
||||
bx.cond_br(cond, lltarget, panic_block.llbb());
|
||||
} else {
|
||||
|
@ -493,7 +493,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
if let Some(destination_ref) = destination.as_ref() {
|
||||
let &(ref dest, target) = destination_ref;
|
||||
self.codegen_transmute(&mut bx, &args[0], dest);
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.funclet_br(self, &mut bx, target);
|
||||
} else {
|
||||
// If we are trying to transmute to an uninhabited type,
|
||||
|
@ -510,7 +510,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, '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.body(), bx.tcx());
|
||||
self.monomorphize(&op_ty)
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
|
@ -521,7 +521,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
Some(ty::InstanceDef::DropGlue(_, None)) => {
|
||||
// Empty drop glue; a no-op.
|
||||
let &(_, target) = destination.as_ref().unwrap();
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.funclet_br(self, &mut bx, target);
|
||||
return;
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
let llfn = bx.get_fn_addr(instance);
|
||||
|
||||
if let Some((_, target)) = destination.as_ref() {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[*target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[*target]);
|
||||
}
|
||||
// Codegen the actual panic invoke/call.
|
||||
helper.do_call(
|
||||
|
@ -568,7 +568,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
} else {
|
||||
// a NOP
|
||||
let target = destination.as_ref().unwrap().1;
|
||||
helper.maybe_sideeffect(mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.funclet_br(self, &mut bx, destination.as_ref().unwrap().1)
|
||||
}
|
||||
return;
|
||||
|
@ -682,7 +682,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
}
|
||||
|
||||
if let Some((_, target)) = *destination {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.funclet_br(self, &mut bx, target);
|
||||
} else {
|
||||
bx.unreachable();
|
||||
|
@ -776,7 +776,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
};
|
||||
|
||||
if let Some((_, target)) = destination.as_ref() {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[*target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[*target]);
|
||||
}
|
||||
helper.do_call(self, &mut bx, fn_ty, fn_ptr, &llargs,
|
||||
destination.as_ref().map(|&(_, target)| (ret_dest, target)),
|
||||
|
@ -827,7 +827,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
}
|
||||
|
||||
mir::TerminatorKind::Goto { target } => {
|
||||
helper.maybe_sideeffect(self.mir, &mut bx, &[target]);
|
||||
helper.maybe_sideeffect(&self.mir, &mut bx, &[target]);
|
||||
helper.funclet_br(self, &mut bx, target);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use self::operand::{OperandRef, OperandValue};
|
|||
pub struct FunctionCx<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
|
||||
instance: Instance<'tcx>,
|
||||
|
||||
mir: &'b mir::Body<'tcx>,
|
||||
mir: &'b mir::ReadOnlyBodyCache<'a, 'tcx>,
|
||||
|
||||
debug_context: Option<FunctionDebugContext<Bx::DIScope>>,
|
||||
|
||||
|
@ -156,10 +156,11 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
}).collect();
|
||||
|
||||
let (landing_pads, funclets) = create_funclets(&mir, &mut bx, &cleanup_kinds, &block_bxs);
|
||||
|
||||
let mir_body = mir.body();
|
||||
let readonly_mir = mir.read_only();
|
||||
let mut fx = FunctionCx {
|
||||
instance,
|
||||
mir: mir.body(),
|
||||
mir: &readonly_mir,
|
||||
llfn,
|
||||
fn_abi,
|
||||
cx,
|
||||
|
@ -174,14 +175,14 @@ 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, &mut mir);
|
||||
let memory_locals = analyze::non_ssa_locals(&fx);
|
||||
|
||||
// Allocate variable and temp allocas
|
||||
fx.locals = {
|
||||
let args = arg_local_refs(&mut bx, &fx, &memory_locals);
|
||||
|
||||
let mut allocate_local = |local| {
|
||||
let decl = &mir.local_decls[local];
|
||||
let decl = &mir_body.local_decls[local];
|
||||
let layout = bx.layout_of(fx.monomorphize(&decl.ty));
|
||||
assert!(!layout.ty.has_erasable_regions());
|
||||
|
||||
|
@ -207,7 +208,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
let retptr = allocate_local(mir::RETURN_PLACE);
|
||||
iter::once(retptr)
|
||||
.chain(args.into_iter())
|
||||
.chain(mir.vars_and_temps_iter().map(allocate_local))
|
||||
.chain(mir_body.vars_and_temps_iter().map(allocate_local))
|
||||
.collect()
|
||||
};
|
||||
|
||||
|
@ -226,8 +227,8 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
debug_context.source_locations_enabled = true;
|
||||
}
|
||||
|
||||
let rpo = traversal::reverse_postorder(&mir);
|
||||
let mut visited = BitSet::new_empty(mir.basic_blocks().len());
|
||||
let rpo = traversal::reverse_postorder(&mir_body);
|
||||
let mut visited = BitSet::new_empty(mir_body.basic_blocks().len());
|
||||
|
||||
// Codegen the body of each block using reverse postorder
|
||||
for (bb, _) in rpo {
|
||||
|
@ -237,7 +238,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
|
||||
// Remove blocks that haven't been visited, or have no
|
||||
// predecessors.
|
||||
for bb in mir.basic_blocks().indices() {
|
||||
for bb in mir_body.basic_blocks().indices() {
|
||||
// Unreachable block
|
||||
if !visited.contains(bb.index()) {
|
||||
debug!("codegen_mir: block {:?} was not visited", bb);
|
||||
|
|
|
@ -591,7 +591,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, '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.body(), tcx);
|
||||
self.monomorphize(&place_ty.ty)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -460,7 +460,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
}
|
||||
|
||||
mir::Rvalue::Discriminant(ref place) => {
|
||||
let discr_ty = rvalue.ty(self.mir, bx.tcx());
|
||||
let discr_ty = rvalue.ty(self.mir.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, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, '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.body(), self.cx.tcx());
|
||||
let operand = OperandRef::new_zst(
|
||||
&mut bx,
|
||||
self.cx.layout_of(self.monomorphize(&ty)),
|
||||
|
@ -714,7 +714,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> {
|
|||
true,
|
||||
mir::Rvalue::Repeat(..) |
|
||||
mir::Rvalue::Aggregate(..) => {
|
||||
let ty = rvalue.ty(self.mir, self.cx.tcx());
|
||||
let ty = rvalue.ty(self.mir.body(), self.cx.tcx());
|
||||
let ty = self.monomorphize(&ty);
|
||||
self.cx.spanned_layout_of(ty, span).is_zst()
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ where
|
|||
Self: for<'graph> GraphPredecessors<'graph, Item = <Self as DirectedGraph>::Node>,
|
||||
{
|
||||
fn predecessors(
|
||||
&mut self,
|
||||
&self,
|
||||
node: Self::Node,
|
||||
) -> <Self as GraphPredecessors<'_>>::Iter;
|
||||
}
|
||||
|
|
|
@ -4,20 +4,11 @@ impl<'graph, G: DirectedGraph> DirectedGraph for &'graph G {
|
|||
type Node = G::Node;
|
||||
}
|
||||
|
||||
impl<'graph, G: DirectedGraph> DirectedGraph for &'graph mut G {
|
||||
type Node = G::Node;
|
||||
}
|
||||
|
||||
impl<'graph, G: WithNumNodes> WithNumNodes for &'graph G {
|
||||
fn num_nodes(&self) -> usize {
|
||||
(**self).num_nodes()
|
||||
}
|
||||
}
|
||||
impl<'graph, G: WithNumNodes> WithNumNodes for &'graph mut G {
|
||||
fn num_nodes(&self) -> usize {
|
||||
(**self).num_nodes()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'graph, G: WithStartNode> WithStartNode for &'graph G {
|
||||
fn start_node(&self) -> Self::Node {
|
||||
|
@ -25,25 +16,13 @@ impl<'graph, G: WithStartNode> WithStartNode for &'graph G {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'graph, G: WithStartNode> WithStartNode for &'graph mut G {
|
||||
fn start_node(&self) -> Self::Node {
|
||||
(**self).start_node()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'graph, G: WithSuccessors> WithSuccessors for &'graph G {
|
||||
fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
|
||||
(**self).successors(node)
|
||||
}
|
||||
}
|
||||
impl<'graph, G: WithSuccessors> WithSuccessors for &'graph mut G {
|
||||
fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
|
||||
(**self).successors(node)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'graph, G: WithPredecessors> WithPredecessors for &'graph mut G {
|
||||
fn predecessors(&mut self,
|
||||
impl<'graph, G: WithPredecessors> WithPredecessors for &'graph G {
|
||||
fn predecessors(&self,
|
||||
node: Self::Node)
|
||||
-> <Self as GraphPredecessors<'_>>::Iter {
|
||||
(**self).predecessors(node)
|
||||
|
@ -55,17 +34,7 @@ impl<'iter, 'graph, G: WithPredecessors> GraphPredecessors<'iter> for &'graph G
|
|||
type Iter = <G as GraphPredecessors<'iter>>::Iter;
|
||||
}
|
||||
|
||||
impl<'iter, 'graph, G: WithPredecessors> GraphPredecessors<'iter> for &'graph mut G {
|
||||
type Item = G::Node;
|
||||
type Iter = <G as GraphPredecessors<'iter>>::Iter;
|
||||
}
|
||||
|
||||
impl<'iter, 'graph, G: WithSuccessors> GraphSuccessors<'iter> for &'graph G {
|
||||
type Item = G::Node;
|
||||
type Iter = <G as GraphSuccessors<'iter>>::Iter;
|
||||
}
|
||||
|
||||
impl<'iter, 'graph, G: WithSuccessors> GraphSuccessors<'iter> for &'graph mut G {
|
||||
type Item = G::Node;
|
||||
type Iter = <G as GraphSuccessors<'iter>>::Iter;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue