From 851a701f90081fbc83fa151e9f272cea2a990779 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Wed, 8 Jan 2020 22:07:05 +0100 Subject: [PATCH 1/6] Reuse a Vec in mir simplification --- src/librustc_mir/transform/simplify.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index ddf8d73e5481f..d589c03761acc 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -94,6 +94,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.strip_nops(); let mut start = START_BLOCK; + let mut new_stmts = vec![]; loop { let mut changed = false; @@ -114,7 +115,6 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.collapse_goto_chain(successor, &mut changed); } - let mut new_stmts = vec![]; let mut inner_changed = true; while inner_changed { inner_changed = false; @@ -124,7 +124,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } let data = &mut self.basic_blocks[bb]; - data.statements.extend(new_stmts); + data.statements.extend(new_stmts.drain(..)); data.terminator = Some(terminator); changed |= inner_changed; From dec8166abc6675627819723b10301e395f3876d5 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 30 Jan 2020 10:27:50 +0100 Subject: [PATCH 2/6] Use Vec::append --- src/librustc_mir/transform/simplify.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index d589c03761acc..813091b7f95a0 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -124,7 +124,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } let data = &mut self.basic_blocks[bb]; - data.statements.extend(new_stmts.drain(..)); + data.statements.append(&mut new_stmts); data.terminator = Some(terminator); changed |= inner_changed; From 33513fad8089956adcbb5b9803f56de1a8e94b57 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 30 Jan 2020 10:35:50 +0100 Subject: [PATCH 3/6] Avoid an intermediate Vec in mir simplify --- src/librustc_mir/transform/simplify.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 813091b7f95a0..3a1ccb5046524 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -94,7 +94,6 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { self.strip_nops(); let mut start = START_BLOCK; - let mut new_stmts = vec![]; loop { let mut changed = false; @@ -119,13 +118,11 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { while inner_changed { inner_changed = false; inner_changed |= self.simplify_branch(&mut terminator); - inner_changed |= self.merge_successor(&mut new_stmts, &mut terminator); + inner_changed |= self.merge_successor(bb, &mut terminator); changed |= inner_changed; } - let data = &mut self.basic_blocks[bb]; - data.statements.append(&mut new_stmts); - data.terminator = Some(terminator); + self.basic_blocks[bb].terminator = Some(terminator); changed |= inner_changed; } @@ -199,7 +196,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { // merge a block with 1 `goto` predecessor to its parent fn merge_successor( &mut self, - new_stmts: &mut Vec>, + merge_into: BasicBlock, terminator: &mut Terminator<'tcx>, ) -> bool { let target = match terminator.kind { @@ -216,7 +213,9 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { return false; } }; - new_stmts.extend(self.basic_blocks[target].statements.drain(..)); + + let (from, to) = self.basic_blocks.pick2_mut(target, merge_into); + to.statements.append(&mut from.statements); self.pred_count[target] = 0; true From 2440998666cb9fe5f35c1de9ef44849b71870fc3 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Thu, 13 Feb 2020 11:44:12 +0100 Subject: [PATCH 4/6] perf(mir): Reserve enough space for the merged blocks before appending --- src/librustc_mir/transform/simplify.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 3a1ccb5046524..d8de9f2180d64 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -95,6 +95,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { let mut start = START_BLOCK; + let mut merged_blocks = Vec::new(); loop { let mut changed = false; @@ -118,10 +119,23 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { while inner_changed { inner_changed = false; inner_changed |= self.simplify_branch(&mut terminator); - inner_changed |= self.merge_successor(bb, &mut terminator); + inner_changed |= self.merge_successor(&mut merged_blocks, &mut terminator); changed |= inner_changed; } + let merged_block_count = + merged_blocks.iter().map(|&i| self.basic_blocks[i].statements.len()).sum(); + + if merged_block_count > 0 { + let mut statements = std::mem::take(&mut self.basic_blocks[bb].statements); + statements.reserve(merged_block_count); + for &from in &merged_blocks { + statements.append(&mut self.basic_blocks[from].statements); + } + self.basic_blocks[bb].statements = statements; + } + merged_blocks.clear(); + self.basic_blocks[bb].terminator = Some(terminator); changed |= inner_changed; @@ -196,7 +210,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { // merge a block with 1 `goto` predecessor to its parent fn merge_successor( &mut self, - merge_into: BasicBlock, + merged_blocks: &mut Vec, terminator: &mut Terminator<'tcx>, ) -> bool { let target = match terminator.kind { @@ -214,8 +228,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } }; - let (from, to) = self.basic_blocks.pick2_mut(target, merge_into); - to.statements.append(&mut from.statements); + merged_blocks.push(target); self.pred_count[target] = 0; true From 84c024d92f34206d0f02ab814c6e5bd3abb876c3 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Sun, 16 Feb 2020 23:23:44 +0100 Subject: [PATCH 5/6] Clarify mir block merging --- src/librustc_mir/transform/simplify.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index d8de9f2180d64..1534b9bdceade 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -95,6 +95,10 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { let mut start = START_BLOCK; + // Vec of the blocks that should be merged. We store the indices here, instead of the + // statements itself to avoid moving the (relatively) large statements twice. + // We do not push the statements directly into the target block (`bb`) as that is slower + // due to additional reallocations let mut merged_blocks = Vec::new(); loop { let mut changed = false; @@ -116,6 +120,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } let mut inner_changed = true; + merged_blocks.clear(); while inner_changed { inner_changed = false; inner_changed |= self.simplify_branch(&mut terminator); @@ -134,7 +139,6 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } self.basic_blocks[bb].statements = statements; } - merged_blocks.clear(); self.basic_blocks[bb].terminator = Some(terminator); From 851e9d64baa8d54a2960a3e5946143cb24b772b5 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Mon, 2 Mar 2020 20:08:21 +0100 Subject: [PATCH 6/6] s/merged_block_count/statements_to_merge/g --- src/librustc_mir/transform/simplify.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 1534b9bdceade..7aa1052d4b2c8 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -128,12 +128,12 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { changed |= inner_changed; } - let merged_block_count = + let statements_to_merge = merged_blocks.iter().map(|&i| self.basic_blocks[i].statements.len()).sum(); - if merged_block_count > 0 { + if statements_to_merge > 0 { let mut statements = std::mem::take(&mut self.basic_blocks[bb].statements); - statements.reserve(merged_block_count); + statements.reserve(statements_to_merge); for &from in &merged_blocks { statements.append(&mut self.basic_blocks[from].statements); }