Skip to content

Commit 23de827

Browse files
committed
Auto merge of #68551 - Marwes:allocations_mir, r=ecstatic-morse
perf: Reuse a Vec in mir simplification Just moves the vec out of the outer loop so it is reused every iteration
2 parents e5e8ba4 + 851e9d6 commit 23de827

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

src/librustc_mir/transform/simplify.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
9595

9696
let mut start = START_BLOCK;
9797

98+
// Vec of the blocks that should be merged. We store the indices here, instead of the
99+
// statements itself to avoid moving the (relatively) large statements twice.
100+
// We do not push the statements directly into the target block (`bb`) as that is slower
101+
// due to additional reallocations
102+
let mut merged_blocks = Vec::new();
98103
loop {
99104
let mut changed = false;
100105

@@ -114,18 +119,28 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
114119
self.collapse_goto_chain(successor, &mut changed);
115120
}
116121

117-
let mut new_stmts = vec![];
118122
let mut inner_changed = true;
123+
merged_blocks.clear();
119124
while inner_changed {
120125
inner_changed = false;
121126
inner_changed |= self.simplify_branch(&mut terminator);
122-
inner_changed |= self.merge_successor(&mut new_stmts, &mut terminator);
127+
inner_changed |= self.merge_successor(&mut merged_blocks, &mut terminator);
123128
changed |= inner_changed;
124129
}
125130

126-
let data = &mut self.basic_blocks[bb];
127-
data.statements.extend(new_stmts);
128-
data.terminator = Some(terminator);
131+
let statements_to_merge =
132+
merged_blocks.iter().map(|&i| self.basic_blocks[i].statements.len()).sum();
133+
134+
if statements_to_merge > 0 {
135+
let mut statements = std::mem::take(&mut self.basic_blocks[bb].statements);
136+
statements.reserve(statements_to_merge);
137+
for &from in &merged_blocks {
138+
statements.append(&mut self.basic_blocks[from].statements);
139+
}
140+
self.basic_blocks[bb].statements = statements;
141+
}
142+
143+
self.basic_blocks[bb].terminator = Some(terminator);
129144

130145
changed |= inner_changed;
131146
}
@@ -199,7 +214,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
199214
// merge a block with 1 `goto` predecessor to its parent
200215
fn merge_successor(
201216
&mut self,
202-
new_stmts: &mut Vec<Statement<'tcx>>,
217+
merged_blocks: &mut Vec<BasicBlock>,
203218
terminator: &mut Terminator<'tcx>,
204219
) -> bool {
205220
let target = match terminator.kind {
@@ -216,7 +231,8 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
216231
return false;
217232
}
218233
};
219-
new_stmts.extend(self.basic_blocks[target].statements.drain(..));
234+
235+
merged_blocks.push(target);
220236
self.pred_count[target] = 0;
221237

222238
true

0 commit comments

Comments
 (0)