EbbHeaderBlockData::predecessors: use SmallVec instead of Vec
Allocations associated with pushes to EbbHeaderBlockData::predecessors account for 4.9% of all heap allocation (calls) in CL. This change avoids almost all of them by changing it to be a SmallVec<[PredBlock; 4]>. Dynamic instruction count falls by 0.15%.
This commit is contained in:
committed by
Benjamin Bouvier
parent
955cdd5f83
commit
c6a4c60a0f
@@ -15,6 +15,7 @@ cranelift-codegen = { path = "../cranelift-codegen", version = "0.42.0", default
|
||||
target-lexicon = "0.8.1"
|
||||
log = { version = "0.4.6", default-features = false }
|
||||
hashmap_core = { version = "0.1.9", optional = true }
|
||||
smallvec = { version = "0.6.10" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -16,6 +16,7 @@ use cranelift_codegen::ir::types::{F32, F64};
|
||||
use cranelift_codegen::ir::{Ebb, Function, Inst, InstBuilder, InstructionData, Type, Value};
|
||||
use cranelift_codegen::packed_option::PackedOption;
|
||||
use cranelift_codegen::packed_option::ReservedValue;
|
||||
use smallvec::SmallVec;
|
||||
use std::vec::Vec;
|
||||
|
||||
/// Structure containing the data relevant the construction of SSA for a given function.
|
||||
@@ -123,9 +124,11 @@ impl PredBlock {
|
||||
}
|
||||
}
|
||||
|
||||
type PredBlockSmallVec = SmallVec<[PredBlock; 4]>;
|
||||
|
||||
struct EbbHeaderBlockData {
|
||||
// The predecessors of the Ebb header block, with the block and branch instruction.
|
||||
predecessors: Vec<PredBlock>,
|
||||
predecessors: PredBlockSmallVec,
|
||||
// A ebb header block is sealed if all of its predecessors have been declared.
|
||||
sealed: bool,
|
||||
// The ebb which this block is part of.
|
||||
@@ -366,7 +369,7 @@ impl SSABuilder {
|
||||
/// Predecessors have to be added with `declare_ebb_predecessor`.
|
||||
pub fn declare_ebb_header_block(&mut self, ebb: Ebb) -> Block {
|
||||
let block = self.blocks.push(BlockData::EbbHeader(EbbHeaderBlockData {
|
||||
predecessors: Vec::new(),
|
||||
predecessors: PredBlockSmallVec::new(),
|
||||
sealed: false,
|
||||
ebb,
|
||||
undef_variables: Vec::new(),
|
||||
@@ -587,7 +590,8 @@ impl SSABuilder {
|
||||
// There is disagreement in the predecessors on which value to use so we have
|
||||
// to keep the ebb argument. To avoid borrowing `self` for the whole loop,
|
||||
// temporarily detach the predecessors list and replace it with an empty list.
|
||||
let mut preds = mem::replace(self.predecessors_mut(dest_ebb), Vec::new());
|
||||
let mut preds =
|
||||
mem::replace(self.predecessors_mut(dest_ebb), PredBlockSmallVec::new());
|
||||
for &mut PredBlock {
|
||||
block: ref mut pred_block,
|
||||
branch: ref mut last_inst,
|
||||
@@ -699,7 +703,7 @@ impl SSABuilder {
|
||||
}
|
||||
|
||||
/// Same as predecessors, but for &mut.
|
||||
fn predecessors_mut(&mut self, ebb: Ebb) -> &mut Vec<PredBlock> {
|
||||
fn predecessors_mut(&mut self, ebb: Ebb) -> &mut PredBlockSmallVec {
|
||||
let block = self.header_block(ebb);
|
||||
match self.blocks[block] {
|
||||
BlockData::EbbBody { .. } => panic!("should not happen"),
|
||||
|
||||
Reference in New Issue
Block a user