Use a closure instead of three chained iterators
This commit is contained in:
parent
820fce61e7
commit
9193dfe435
6 changed files with 58 additions and 72 deletions
|
|
@ -437,8 +437,8 @@ impl<'tcx> Terminator<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
|
||||
self.kind.successors_mut()
|
||||
pub fn successors_mut<'a>(&'a mut self, f: impl FnMut(&'a mut BasicBlock)) {
|
||||
self.kind.successors_mut(f)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -486,7 +486,6 @@ pub use helper::*;
|
|||
mod helper {
|
||||
use super::*;
|
||||
pub type Successors<'a> = impl DoubleEndedIterator<Item = BasicBlock> + 'a;
|
||||
pub type SuccessorsMut<'a> = impl DoubleEndedIterator<Item = &'a mut BasicBlock> + 'a;
|
||||
|
||||
impl SwitchTargets {
|
||||
/// Like [`SwitchTargets::target_for_value`], but returning the same type as
|
||||
|
|
@ -560,69 +559,63 @@ mod helper {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[define_opaque(SuccessorsMut)]
|
||||
pub fn successors_mut(&mut self) -> SuccessorsMut<'_> {
|
||||
pub fn successors_mut<'a>(&'a mut self, mut f: impl FnMut(&'a mut BasicBlock)) {
|
||||
use self::TerminatorKind::*;
|
||||
match *self {
|
||||
// 3-successors for async drop: target, unwind, dropline (parent coroutine drop)
|
||||
Drop {
|
||||
target: ref mut t,
|
||||
unwind: UnwindAction::Cleanup(ref mut u),
|
||||
drop: Some(ref mut d),
|
||||
..
|
||||
} => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(Some(d))),
|
||||
// 2-successors
|
||||
Call {
|
||||
target: Some(ref mut t), unwind: UnwindAction::Cleanup(ref mut u), ..
|
||||
match self {
|
||||
Drop { target, unwind, drop, .. } => {
|
||||
f(target);
|
||||
if let UnwindAction::Cleanup(u) = unwind {
|
||||
f(u)
|
||||
}
|
||||
if let Some(d) = drop {
|
||||
f(d)
|
||||
}
|
||||
}
|
||||
| Yield { resume: ref mut t, drop: Some(ref mut u), .. }
|
||||
| Drop {
|
||||
target: ref mut t,
|
||||
unwind: UnwindAction::Cleanup(ref mut u),
|
||||
drop: None,
|
||||
..
|
||||
Call { target, unwind, .. } => {
|
||||
if let Some(target) = target {
|
||||
f(target);
|
||||
}
|
||||
if let UnwindAction::Cleanup(u) = unwind {
|
||||
f(u)
|
||||
}
|
||||
}
|
||||
| Drop { target: ref mut t, unwind: _, drop: Some(ref mut u), .. }
|
||||
| Assert { target: ref mut t, unwind: UnwindAction::Cleanup(ref mut u), .. }
|
||||
| FalseUnwind {
|
||||
real_target: ref mut t,
|
||||
unwind: UnwindAction::Cleanup(ref mut u),
|
||||
} => slice::from_mut(t).into_iter().chain(Some(u).into_iter().chain(None)),
|
||||
// single successor
|
||||
Goto { target: ref mut t }
|
||||
| Call { target: None, unwind: UnwindAction::Cleanup(ref mut t), .. }
|
||||
| Call { target: Some(ref mut t), unwind: _, .. }
|
||||
| Yield { resume: ref mut t, drop: None, .. }
|
||||
| Drop { target: ref mut t, unwind: _, .. }
|
||||
| Assert { target: ref mut t, unwind: _, .. }
|
||||
| FalseUnwind { real_target: ref mut t, unwind: _ } => {
|
||||
slice::from_mut(t).into_iter().chain(None.into_iter().chain(None))
|
||||
Yield { resume, drop, .. } => {
|
||||
f(resume);
|
||||
if let Some(d) = drop {
|
||||
f(d)
|
||||
}
|
||||
}
|
||||
Assert { target, unwind, .. } | FalseUnwind { real_target: target, unwind } => {
|
||||
f(target);
|
||||
if let UnwindAction::Cleanup(u) = unwind {
|
||||
f(u)
|
||||
}
|
||||
}
|
||||
Goto { target } => {
|
||||
f(target);
|
||||
}
|
||||
// No successors
|
||||
UnwindResume
|
||||
| UnwindTerminate(_)
|
||||
| CoroutineDrop
|
||||
| Return
|
||||
| Unreachable
|
||||
| TailCall { .. }
|
||||
| Call { target: None, unwind: _, .. } => {
|
||||
(&mut []).into_iter().chain(None.into_iter().chain(None))
|
||||
| TailCall { .. } => {}
|
||||
InlineAsm { targets, unwind, .. } => {
|
||||
for target in targets {
|
||||
f(target);
|
||||
}
|
||||
if let UnwindAction::Cleanup(u) = unwind {
|
||||
f(u)
|
||||
}
|
||||
}
|
||||
// Multiple successors
|
||||
InlineAsm { ref mut targets, unwind: UnwindAction::Cleanup(ref mut u), .. } => {
|
||||
targets.iter_mut().chain(Some(u).into_iter().chain(None))
|
||||
SwitchInt { targets, .. } => {
|
||||
for target in &mut targets.targets {
|
||||
f(target);
|
||||
}
|
||||
}
|
||||
InlineAsm { ref mut targets, unwind: _, .. } => {
|
||||
targets.iter_mut().chain(None.into_iter().chain(None))
|
||||
}
|
||||
SwitchInt { ref mut targets, .. } => {
|
||||
targets.targets.iter_mut().chain(None.into_iter().chain(None))
|
||||
}
|
||||
// FalseEdge
|
||||
FalseEdge { ref mut real_target, ref mut imaginary_target } => {
|
||||
slice::from_mut(real_target)
|
||||
.into_iter()
|
||||
.chain(Some(imaginary_target).into_iter().chain(None))
|
||||
FalseEdge { real_target, imaginary_target } => {
|
||||
f(real_target);
|
||||
f(imaginary_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1064,10 +1064,8 @@ fn insert_switch<'tcx>(
|
|||
},
|
||||
);
|
||||
|
||||
let blocks = body.basic_blocks_mut().iter_mut();
|
||||
|
||||
for target in blocks.flat_map(|b| b.terminator_mut().successors_mut()) {
|
||||
*target += 1;
|
||||
for b in body.basic_blocks_mut().iter_mut() {
|
||||
b.terminator_mut().successors_mut(|target| *target += 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -765,12 +765,12 @@ impl OpportunitySet {
|
|||
|
||||
// Replace `succ` by `new_succ` where it appears.
|
||||
let mut num_edges = 0;
|
||||
for s in basic_blocks[current].terminator_mut().successors_mut() {
|
||||
basic_blocks[current].terminator_mut().successors_mut(|s| {
|
||||
if *s == succ {
|
||||
*s = new_succ;
|
||||
num_edges += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Update predecessors with the new block.
|
||||
let _new_succ = self.predecessors.push(num_edges);
|
||||
|
|
|
|||
|
|
@ -115,9 +115,7 @@ impl<'tcx> MutVisitor<'tcx> for BasicBlockUpdater<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, _location: Location) {
|
||||
for succ in terminator.successors_mut() {
|
||||
*succ = self.map[*succ];
|
||||
}
|
||||
terminator.successors_mut(|succ| *succ = self.map[*succ]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -58,13 +58,13 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
|
|||
}
|
||||
}
|
||||
|
||||
for target in body[bb].terminator_mut().successors_mut() {
|
||||
body[bb].terminator_mut().successors_mut(|target| {
|
||||
if *target != resume_block && nop_landing_pads.contains(*target) {
|
||||
debug!(" folding noop jump to {:?} to resume block", target);
|
||||
*target = resume_block;
|
||||
jumps_folded += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
|
||||
if is_nop_landing_pad {
|
||||
|
|
|
|||
|
|
@ -147,9 +147,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
|
|||
let mut terminator =
|
||||
self.basic_blocks[bb].terminator.take().expect("invalid terminator state");
|
||||
|
||||
for successor in terminator.successors_mut() {
|
||||
self.collapse_goto_chain(successor, &mut changed);
|
||||
}
|
||||
terminator
|
||||
.successors_mut(|successor| self.collapse_goto_chain(successor, &mut changed));
|
||||
|
||||
let mut inner_changed = true;
|
||||
merged_blocks.clear();
|
||||
|
|
@ -375,9 +374,7 @@ pub(super) fn remove_dead_blocks(body: &mut Body<'_>) {
|
|||
}
|
||||
|
||||
for block in basic_blocks {
|
||||
for target in block.terminator_mut().successors_mut() {
|
||||
*target = replacements[target.index()];
|
||||
}
|
||||
block.terminator_mut().successors_mut(|target| *target = replacements[target.index()]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue