Use a SmallVec for ABIArgSlots (#4586)
These are always length 1 for Wasm benchmarks. <h3>Sightglass Benchmark Results</h3> ``` 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 ```
This commit is contained in:
@@ -212,7 +212,7 @@ impl ABIMachineSpec for AArch64MachineDeps {
|
|||||||
let upper_reg = xreg(next_xreg + 1);
|
let upper_reg = xreg(next_xreg + 1);
|
||||||
|
|
||||||
ret.push(ABIArg::Slots {
|
ret.push(ABIArg::Slots {
|
||||||
slots: vec![
|
slots: smallvec![
|
||||||
ABIArgSlot::Reg {
|
ABIArgSlot::Reg {
|
||||||
reg: lower_reg.to_real_reg().unwrap(),
|
reg: lower_reg.to_real_reg().unwrap(),
|
||||||
ty: param.value_type,
|
ty: param.value_type,
|
||||||
|
|||||||
@@ -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()) {
|
for (rc, reg_ty) in rcs.iter().zip(reg_tys.iter()) {
|
||||||
let intreg = *rc == RegClass::Int;
|
let intreg = *rc == RegClass::Int;
|
||||||
let nextreg = if intreg {
|
let nextreg = if intreg {
|
||||||
|
|||||||
@@ -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
|
/// 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
|
/// 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,
|
/// 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.
|
/// parts used to store a value of this type.
|
||||||
Slots {
|
Slots {
|
||||||
/// Slots, one per register part.
|
/// Slots, one per register part.
|
||||||
slots: Vec<ABIArgSlot>,
|
slots: ABIArgSlotVec,
|
||||||
/// Purpose of this arg.
|
/// Purpose of this arg.
|
||||||
purpose: ir::ArgumentPurpose,
|
purpose: ir::ArgumentPurpose,
|
||||||
},
|
},
|
||||||
@@ -206,7 +211,7 @@ impl ABIArg {
|
|||||||
purpose: ir::ArgumentPurpose,
|
purpose: ir::ArgumentPurpose,
|
||||||
) -> ABIArg {
|
) -> ABIArg {
|
||||||
ABIArg::Slots {
|
ABIArg::Slots {
|
||||||
slots: vec![ABIArgSlot::Reg { reg, ty, extension }],
|
slots: smallvec![ABIArgSlot::Reg { reg, ty, extension }],
|
||||||
purpose,
|
purpose,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,7 +224,7 @@ impl ABIArg {
|
|||||||
purpose: ir::ArgumentPurpose,
|
purpose: ir::ArgumentPurpose,
|
||||||
) -> ABIArg {
|
) -> ABIArg {
|
||||||
ABIArg::Slots {
|
ABIArg::Slots {
|
||||||
slots: vec![ABIArgSlot::Stack {
|
slots: smallvec![ABIArgSlot::Stack {
|
||||||
offset,
|
offset,
|
||||||
ty,
|
ty,
|
||||||
extension,
|
extension,
|
||||||
|
|||||||
Reference in New Issue
Block a user