From fdcf7b694f139fbd3aea8c382c8b6c73d0a17906 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 1 Nov 2022 10:00:09 -0700 Subject: [PATCH] Avoid indexing and use iteration (#98) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...while still appeasing the borrow checker by taking spillsets out of `self` and then putting them back in again when we're done. I was just doing this to enable playing with some data structures in follow up commits, but decided to benchmark this commit as-is and found 2-4% speed ups to Cranelift compilation! ``` compilation :: instructions-retired :: benchmarks/bz2/benchmark.wasm Δ = 39946528.13 ± 38398.29 (confidence = 99%) no-index.so is 1.04x to 1.04x faster than main.so! [985704952 985984130.24 986180413] main.so [945649144 946037602.11 946262076] no-index.so compilation :: instructions-retired :: benchmarks/pulldown-cmark/benchmark.wasm Δ = 48413802.56 ± 34288.05 (confidence = 99%) no-index.so is 1.03x to 1.03x faster than main.so! [1593663899 1593926801.92 1594246604] main.so [1545196678 1545512999.36 1545802144] no-index.so compilation :: instructions-retired :: benchmarks/spidermonkey/benchmark.wasm Δ = 841028066.56 ± 253404.59 (confidence = 99%) no-index.so is 1.02x to 1.02x faster than main.so! [34798712681 34801346430.28 34802786661] main.so [33958847844 33960318363.72 33962177143] no-index.so ``` --- src/ion/spill.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ion/spill.rs b/src/ion/spill.rs index 5bc6e9e..a95eed5 100644 --- a/src/ion/spill.rs +++ b/src/ion/spill.rs @@ -89,9 +89,11 @@ impl<'a, F: Function> Env<'a, F> { spillslot: SpillSlotIndex, ) { self.spillsets[spillset.index()].slot = spillslot; - for i in 0..self.spillsets[spillset.index()].vregs.len() { - // don't borrow self - let vreg = self.spillsets[spillset.index()].vregs[i]; + + // Take `spillsets` to avoid a conflicting borrow of `self`. + let spillsets = std::mem::take(&mut self.spillsets); + + for vreg in &spillsets[spillset.index()].vregs { trace!( "spillslot {:?} alloc'ed to spillset {:?}: vreg {:?}", spillslot, @@ -112,6 +114,10 @@ impl<'a, F: Function> Env<'a, F> { .insert(LiveRangeKey::from_range(&entry.range), entry.index); } } + + // Replace `spillsets`. + let default = std::mem::replace(&mut self.spillsets, spillsets); + debug_assert!(default.is_empty()); } pub fn allocate_spillslots(&mut self) {