1
Fork 0

Rollup merge of #97079 - SparrowLii:successors, r=lcnr

Change `Successors` to `impl Iterator<Item = BasicBlock>`

This PR fixes the FIXME in `compiler\rustc_middle\src\mir\mod.rs`.
This can omit several `&`, `*` or `cloned` operations on Successros' generated elements
This commit is contained in:
Yuki Okushi 2022-05-17 19:01:32 +09:00 committed by GitHub
commit 70cd85f5e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 54 additions and 55 deletions

View file

@ -24,7 +24,7 @@ pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Grap
let terminator = body[source].terminator();
let labels = terminator.kind.fmt_successor_labels();
for (&target, label) in terminator.successors().zip(labels) {
for (target, label) in terminator.successors().zip(labels) {
let src = node(def_id, source);
let trg = node(def_id, target);
edges.push(Edge::new(src, trg, label.to_string()));

View file

@ -1355,10 +1355,7 @@ pub enum InlineAsmOperand<'tcx> {
/// Type for MIR `Assert` terminator error messages.
pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
// FIXME: Change `Successors` to `impl Iterator<Item = BasicBlock>`.
#[allow(rustc::pass_by_value)]
pub type Successors<'a> =
iter::Chain<option::IntoIter<&'a BasicBlock>, slice::Iter<'a, BasicBlock>>;
pub type Successors<'a> = impl Iterator<Item = BasicBlock> + 'a;
pub type SuccessorsMut<'a> =
iter::Chain<option::IntoIter<&'a mut BasicBlock>, slice::IterMut<'a, BasicBlock>>;
@ -3434,13 +3431,13 @@ impl<'tcx> graph::WithStartNode for Body<'tcx> {
impl<'tcx> graph::WithSuccessors for Body<'tcx> {
#[inline]
fn successors(&self, node: Self::Node) -> <Self as GraphSuccessors<'_>>::Iter {
self.basic_blocks[node].terminator().successors().cloned()
self.basic_blocks[node].terminator().successors()
}
}
impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> {
type Item = BasicBlock;
type Iter = iter::Cloned<Successors<'b>>;
type Iter = Successors<'b>;
}
impl<'tcx, 'graph> graph::GraphPredecessors<'graph> for Body<'tcx> {

View file

@ -166,9 +166,7 @@ impl<'tcx> MirPatch<'tcx> {
// get terminator's targets and apply the statement to all of them.
if loc.statement_index > body[loc.block].statements.len() {
let term = body[loc.block].terminator();
let successors = term.successors().clone();
for i in successors {
for i in term.successors() {
stmts_and_targets
.push((Statement { source_info, kind: stmt.clone() }, i.clone()));
}

View file

@ -43,7 +43,7 @@ impl PredecessorCache {
let mut preds = IndexVec::from_elem(SmallVec::new(), basic_blocks);
for (bb, data) in basic_blocks.iter_enumerated() {
if let Some(term) = &data.terminator {
for &succ in term.successors() {
for succ in term.successors() {
preds[succ].push(bb);
}
}

View file

@ -416,32 +416,36 @@ impl<'tcx> TerminatorKind<'tcx> {
| Return
| Unreachable
| Call { destination: None, cleanup: None, .. }
| InlineAsm { destination: None, cleanup: None, .. } => None.into_iter().chain(&[]),
Goto { target: ref t }
| Call { destination: None, cleanup: Some(ref t), .. }
| Call { destination: Some((_, ref t)), cleanup: None, .. }
| Yield { resume: ref t, drop: None, .. }
| DropAndReplace { target: ref t, unwind: None, .. }
| Drop { target: ref t, unwind: None, .. }
| Assert { target: ref t, cleanup: None, .. }
| FalseUnwind { real_target: ref t, unwind: None }
| InlineAsm { destination: Some(ref t), cleanup: None, .. }
| InlineAsm { destination: None, cleanup: Some(ref t), .. } => {
Some(t).into_iter().chain(&[])
| InlineAsm { destination: None, cleanup: None, .. } => {
None.into_iter().chain((&[]).into_iter().copied())
}
Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. }
| Yield { resume: ref t, drop: Some(ref u), .. }
| DropAndReplace { target: ref t, unwind: Some(ref u), .. }
| Drop { target: ref t, unwind: Some(ref u), .. }
| Assert { target: ref t, cleanup: Some(ref u), .. }
| FalseUnwind { real_target: ref t, unwind: Some(ref u) }
| InlineAsm { destination: Some(ref t), cleanup: Some(ref u), .. } => {
Some(t).into_iter().chain(slice::from_ref(u))
Goto { target: t }
| Call { destination: None, cleanup: Some(t), .. }
| Call { destination: Some((_, t)), cleanup: None, .. }
| Yield { resume: t, drop: None, .. }
| DropAndReplace { target: t, unwind: None, .. }
| Drop { target: t, unwind: None, .. }
| Assert { target: t, cleanup: None, .. }
| FalseUnwind { real_target: t, unwind: None }
| InlineAsm { destination: Some(t), cleanup: None, .. }
| InlineAsm { destination: None, cleanup: Some(t), .. } => {
Some(t).into_iter().chain((&[]).into_iter().copied())
}
SwitchInt { ref targets, .. } => None.into_iter().chain(&targets.targets),
FalseEdge { ref real_target, ref imaginary_target } => {
Some(real_target).into_iter().chain(slice::from_ref(imaginary_target))
Call { destination: Some((_, t)), cleanup: Some(ref u), .. }
| Yield { resume: t, drop: Some(ref u), .. }
| DropAndReplace { target: t, unwind: Some(ref u), .. }
| Drop { target: t, unwind: Some(ref u), .. }
| Assert { target: t, cleanup: Some(ref u), .. }
| FalseUnwind { real_target: t, unwind: Some(ref u) }
| InlineAsm { destination: Some(t), cleanup: Some(ref u), .. } => {
Some(t).into_iter().chain(slice::from_ref(u).into_iter().copied())
}
SwitchInt { ref targets, .. } => {
None.into_iter().chain(targets.targets.iter().copied())
}
FalseEdge { real_target, ref imaginary_target } => Some(real_target)
.into_iter()
.chain(slice::from_ref(imaginary_target).into_iter().copied()),
}
}

View file

@ -180,7 +180,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
// two iterations yield `C` and finally `A` for a final traversal of [E, D, B, C, A]
loop {
let bb = if let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() {
if let Some(&bb) = iter.next() {
if let Some(bb) = iter.next() {
bb
} else {
break;