From 55215bbd1e03303de10f128fe3c4db3cd9ec5171 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 2 Aug 2022 17:40:36 -0700 Subject: [PATCH] Use a `SmallVec` for `ABIArgSlot`s (#4586) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are always length 1 for Wasm benchmarks.

Sightglass Benchmark Results

``` compilation :: nanoseconds :: benchmarks/spidermonkey/benchmark.wasm Δ = 328624015.86 ± 40274677.93 (confidence = 99%) main.so is 0.88x to 0.91x faster than slots-smallvec.so! slots-smallvec.so is 1.10x to 1.13x faster than main.so! [3070752447 3203778792.55 3446269274] main.so [2503544039 2875154776.69 3197966713] slots-smallvec.so compilation :: nanoseconds :: benchmarks/pulldown-cmark/benchmark.wasm Δ = 9685705.06 ± 3221286.87 (confidence = 99%) main.so is 0.91x to 0.96x faster than slots-smallvec.so! slots-smallvec.so is 1.05x to 1.09x faster than main.so! [129356493 145594942.79 165038803] main.so [118555011 135909237.73 188780619] slots-smallvec.so compilation :: nanoseconds :: benchmarks/bz2/benchmark.wasm No difference in performance. [79080493 86757564.46 112649639] main.so [78083384 85934125.69 94992743] slots-smallvec.so ``` --- cranelift/codegen/src/isa/aarch64/abi.rs | 2 +- cranelift/codegen/src/isa/x64/abi.rs | 2 +- cranelift/codegen/src/machinst/abi_impl.rs | 11 ++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cranelift/codegen/src/isa/aarch64/abi.rs b/cranelift/codegen/src/isa/aarch64/abi.rs index e57866c307..524740d45b 100644 --- a/cranelift/codegen/src/isa/aarch64/abi.rs +++ b/cranelift/codegen/src/isa/aarch64/abi.rs @@ -212,7 +212,7 @@ impl ABIMachineSpec for AArch64MachineDeps { let upper_reg = xreg(next_xreg + 1); ret.push(ABIArg::Slots { - slots: vec![ + slots: smallvec![ ABIArgSlot::Reg { reg: lower_reg.to_real_reg().unwrap(), ty: param.value_type, diff --git a/cranelift/codegen/src/isa/x64/abi.rs b/cranelift/codegen/src/isa/x64/abi.rs index 9202e2c82f..abe6a576bb 100644 --- a/cranelift/codegen/src/isa/x64/abi.rs +++ b/cranelift/codegen/src/isa/x64/abi.rs @@ -125,7 +125,7 @@ impl ABIMachineSpec for X64ABIMachineSpec { ); } - let mut slots = vec![]; + let mut slots = ABIArgSlotVec::new(); for (rc, reg_ty) in rcs.iter().zip(reg_tys.iter()) { let intreg = *rc == RegClass::Int; let nextreg = if intreg { diff --git a/cranelift/codegen/src/machinst/abi_impl.rs b/cranelift/codegen/src/machinst/abi_impl.rs index dd2e860386..cd304ca478 100644 --- a/cranelift/codegen/src/machinst/abi_impl.rs +++ b/cranelift/codegen/src/machinst/abi_impl.rs @@ -153,6 +153,11 @@ impl ABIArgSlot { } } +/// A vector of `ABIArgSlot`s. Inline capacity for one element because basically +/// 100% of values use one slot. Only `i128`s need multiple slots, and they are +/// super rare (and never happen with Wasm). +pub type ABIArgSlotVec = SmallVec<[ABIArgSlot; 1]>; + /// An ABIArg is composed of one or more parts. This allows for a CLIF-level /// Value to be passed with its parts in more than one location at the ABI /// level. For example, a 128-bit integer may be passed in two 64-bit registers, @@ -169,7 +174,7 @@ pub enum ABIArg { /// parts used to store a value of this type. Slots { /// Slots, one per register part. - slots: Vec, + slots: ABIArgSlotVec, /// Purpose of this arg. purpose: ir::ArgumentPurpose, }, @@ -206,7 +211,7 @@ impl ABIArg { purpose: ir::ArgumentPurpose, ) -> ABIArg { ABIArg::Slots { - slots: vec![ABIArgSlot::Reg { reg, ty, extension }], + slots: smallvec![ABIArgSlot::Reg { reg, ty, extension }], purpose, } } @@ -219,7 +224,7 @@ impl ABIArg { purpose: ir::ArgumentPurpose, ) -> ABIArg { ABIArg::Slots { - slots: vec![ABIArgSlot::Stack { + slots: smallvec![ABIArgSlot::Stack { offset, ty, extension,