Skip to content

Commit c3e6daa

Browse files
committed
Fixup nits in merge_consecutive_blocks and merge multiple blocks at once to improve performance.
1 parent 156c061 commit c3e6daa

File tree

1 file changed

+23
-20
lines changed

1 file changed

+23
-20
lines changed

src/librustc_mir/transform/simplify_cfg.rs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ impl SimplifyCfg {
5151
let mut worklist = vec![START_BLOCK];
5252
while let Some(bb) = worklist.pop() {
5353
// Temporarily swap out the terminator we're modifying to keep borrowck happy
54-
let mut terminator = Terminator::Diverge;
55-
mem::swap(&mut terminator, &mut mir.basic_block_data_mut(bb).terminator);
54+
let mut terminator = mem::replace(&mut mir.basic_block_data_mut(bb).terminator,
55+
Terminator::Diverge);
5656

5757
// Shortcut chains of empty blocks that just jump from one to the next
5858
for target in terminator.successors_mut() {
@@ -71,27 +71,30 @@ impl SimplifyCfg {
7171
}
7272

7373
// See if we can merge the target block into this one
74-
match terminator {
75-
Terminator::Goto { target } if target.index() > DIVERGE_BLOCK.index() &&
76-
predecessor_map.num_predecessors(target) == 1 => {
77-
changed = true;
78-
let mut other_data = BasicBlockData {
79-
statements: Vec::new(),
80-
terminator: Terminator::Goto { target: target}
81-
};
82-
mem::swap(&mut other_data, mir.basic_block_data_mut(target));
83-
84-
// target used to have 1 predecessor (bb), and still has only one (itself)
85-
// All the successors of target have had target replaced by bb in their
86-
// list of predecessors, keeping the number the same.
87-
88-
let data = mir.basic_block_data_mut(bb);
89-
data.statements.append(&mut other_data.statements);
90-
mem::swap(&mut data.terminator, &mut other_data.terminator);
74+
while let Terminator::Goto { target } = terminator {
75+
if target.index() <= DIVERGE_BLOCK.index() || predecessor_map.num_predecessors(target) > 1 {
76+
break;
9177
}
92-
_ => mir.basic_block_data_mut(bb).terminator = terminator
78+
79+
changed = true;
80+
81+
let mut other_data = mem::replace(mir.basic_block_data_mut(target), BasicBlockData {
82+
statements: Vec::new(),
83+
terminator: Terminator::Goto { target: target }
84+
});
85+
86+
// target used to have 1 predecessor (bb), and still has only one (itself)
87+
// All the successors of target have had target replaced by bb in their
88+
// list of predecessors, keeping the number the same.
89+
90+
let data = mir.basic_block_data_mut(bb);
91+
data.statements.append(&mut other_data.statements);
92+
terminator = other_data.terminator;
9393
}
9494

95+
// Restore the terminator we swapped out for Diverge
96+
mir.basic_block_data_mut(bb).terminator = terminator;
97+
9598
for succ in mir.basic_block_data(bb).terminator.successors() {
9699
if !seen[succ.index()] {
97100
seen[succ.index()] = true;

0 commit comments

Comments
 (0)