From d2443a75f352bde49dc529420cc3d8e4bb370c19 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Sat, 7 Sep 2019 18:07:51 +0200 Subject: [PATCH] legalizer/split.rs: simplify_branch_arguments: use SmallVec instead of Vec This function is responsible for 8.5% of all heap allocation (calls) in CL. This change avoids almost all of them by using a SmallVec::<[Value; 32]> instead. Dynamic instruction count falls by 0.25%. The fixed size of 32 was arrived at after profiling with fixed sizes of 1, 2, 4, 8, 16, 32, 64 and 128. 32 is as high as I can push it without the instruction count starting to creep up again, and gets almost all the block-reduction win of 64 and 128. --- cranelift/codegen/src/legalizer/split.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cranelift/codegen/src/legalizer/split.rs b/cranelift/codegen/src/legalizer/split.rs index f16dae161b..9f689922f1 100644 --- a/cranelift/codegen/src/legalizer/split.rs +++ b/cranelift/codegen/src/legalizer/split.rs @@ -68,6 +68,7 @@ use crate::cursor::{Cursor, CursorPosition, FuncCursor}; use crate::flowgraph::{BasicBlock, ControlFlowGraph}; use crate::ir::{self, Ebb, Inst, InstBuilder, InstructionData, Opcode, Type, Value, ValueDef}; use core::iter; +use smallvec::SmallVec; use std::vec::Vec; /// Split `value` into two values using the `isplit` semantics. Do this by reusing existing values @@ -373,7 +374,7 @@ fn resolve_splits(dfg: &ir::DataFlowGraph, value: Value) -> Value { /// After legalizing the instructions computing the value that was split, it is likely that we can /// avoid depending on the split instruction. Its input probably comes from a concatenation. pub fn simplify_branch_arguments(dfg: &mut ir::DataFlowGraph, branch: Inst) { - let mut new_args = Vec::new(); + let mut new_args = SmallVec::<[Value; 32]>::new(); for &arg in dfg.inst_args(branch) { let new_arg = resolve_splits(dfg, arg);