1
Fork 0

Account for new maybe_sideeffect helper that requires predecessors

This commit is contained in:
Paul Daniel Faria 2019-10-23 13:46:23 -04:00
parent c8c266a0fb
commit 2eed90a621
10 changed files with 176 additions and 133 deletions

View file

@ -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]
}
}

View file

@ -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`.

View file

@ -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());

View file

@ -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.

View file

@ -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);
}

View file

@ -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);

View file

@ -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)
}
}

View file

@ -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()
}

View file

@ -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;
}

View file

@ -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;
}