From 75fdc9d3a403fd63b1123d2bf018758afd4d95b6 Mon Sep 17 00:00:00 2001 From: T0b1 Date: Sun, 16 Apr 2023 14:10:24 +0200 Subject: [PATCH] try bigger smallvec for vregs --- src/ion/fast_alloc.rs | 62 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/src/ion/fast_alloc.rs b/src/ion/fast_alloc.rs index 358f18b..38c2439 100644 --- a/src/ion/fast_alloc.rs +++ b/src/ion/fast_alloc.rs @@ -144,8 +144,8 @@ struct FastAllocState<'a, F: Function> { pub vregs: Vec, pub pregs: Vec, pub blocks: Vec, - pub liveins: Vec, - pub liveouts: Vec, + pub liveins: Vec, + pub liveouts: Vec, pub cur_stack_slot_idx: u32, pub reftype_vregs_in_pregs_count: u32, @@ -1147,6 +1147,60 @@ impl BlockBitmap { } } +#[derive(Clone, Debug)] +struct VRegBitmap { + storage: SmallVec<[u64; 8]>, +} + +impl VRegBitmap { + fn init(vreg_count: usize) -> Self { + let u64_count = (vreg_count + 63) / 64; + let mut storage = SmallVec::<[u64; 8]>::with_capacity(u64_count); + storage.resize(u64_count, 0); + Self { storage } + } + + fn set(&mut self, idx: usize) { + let idx = idx / 64; + let bit = 1u64 << (idx % 64); + self.storage[idx] |= bit; + } + + fn un_set(&mut self, idx: usize) { + let idx = idx / 64; + let bit = 1u64 << (idx % 64); + self.storage[idx] &= !bit; + } + + fn is_set(&mut self, idx: usize) -> bool { + let idx = idx / 64; + let bit = 1u64 << (idx % 64); + (self.storage[idx] & bit) != 0 + } + + fn is_empty(&self) -> bool { + for &b in self.storage.iter() { + if b != 0 { + return false; + } + } + return true; + } + + pub fn union_with(&mut self, other: &Self) -> bool { + let mut changed = 0; + for (word_idx, &bits) in other.storage.iter().enumerate() { + if bits == 0 { + continue; + } + let self_word = &mut self.storage[word_idx]; + changed |= bits & !*self_word; + *self_word |= bits; + } + changed != 0 + } +} + // currently, copy from liveranges.rs // don't inline for better perf stats #[inline(never)] @@ -1156,10 +1210,10 @@ fn calc_live_bitmaps<'a, F: Function>( ) -> Result<(), RegAllocError> { state .liveins - .resize(state.blocks.len(), BlockBitmap::init(state.vregs.len())); + .resize(state.blocks.len(), VRegBitmap::init(state.vregs.len())); state .liveouts - .resize(state.blocks.len(), BlockBitmap::init(state.vregs.len())); + .resize(state.blocks.len(), VRegBitmap::init(state.vregs.len())); // Run a worklist algorithm to precisely compute liveins and // liveouts.