From a66d7b2001def5ab87e99d661e31890660f38374 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 Nov 2018 17:12:52 +1100 Subject: [PATCH] Use `SmallVec` to avoid allocations in `from_decimal_string`. This reduces the number of allocations in a "check clean" build of `tuple-stress` by 14%, reducing instruction counts by 0.6%. --- src/Cargo.lock | 1 + src/librustc_apfloat/Cargo.toml | 1 + src/librustc_apfloat/ieee.rs | 13 +++++++------ src/librustc_apfloat/lib.rs | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index b4317864502ce..17b1744a07f2f 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2095,6 +2095,7 @@ version = "0.0.0" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", + "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/src/librustc_apfloat/Cargo.toml b/src/librustc_apfloat/Cargo.toml index 735b74f156500..a8a5da90c7a6b 100644 --- a/src/librustc_apfloat/Cargo.toml +++ b/src/librustc_apfloat/Cargo.toml @@ -10,3 +10,4 @@ path = "lib.rs" [dependencies] bitflags = "1.0" rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } +smallvec = { version = "0.6.5", features = ["union"] } diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs index 87d59d2e763cb..4f405858e350c 100644 --- a/src/librustc_apfloat/ieee.rs +++ b/src/librustc_apfloat/ieee.rs @@ -11,6 +11,7 @@ use {Category, ExpInt, IEK_INF, IEK_NAN, IEK_ZERO}; use {Float, FloatConvert, ParseError, Round, Status, StatusAnd}; +use smallvec::{SmallVec, smallvec}; use std::cmp::{self, Ordering}; use std::convert::TryFrom; use std::fmt::{self, Write}; @@ -1962,7 +1963,7 @@ impl IeeeFloat { // to hold the full significand, and an extra limb required by // tcMultiplyPart. let max_limbs = limbs_for_bits(1 + 196 * significand_digits / 59); - let mut dec_sig = Vec::with_capacity(max_limbs); + let mut dec_sig: SmallVec<[Limb; 1]> = SmallVec::with_capacity(max_limbs); // Convert to binary efficiently - we do almost all multiplication // in a Limb. When this would overflow do we do a single @@ -2021,11 +2022,11 @@ impl IeeeFloat { const FIRST_EIGHT_POWERS: [Limb; 8] = [1, 5, 25, 125, 625, 3125, 15625, 78125]; - let mut p5_scratch = vec![]; - let mut p5 = vec![FIRST_EIGHT_POWERS[4]]; + let mut p5_scratch = smallvec![]; + let mut p5: SmallVec<[Limb; 1]> = smallvec![FIRST_EIGHT_POWERS[4]]; - let mut r_scratch = vec![]; - let mut r = vec![FIRST_EIGHT_POWERS[power & 7]]; + let mut r_scratch = smallvec![]; + let mut r: SmallVec<[Limb; 1]> = smallvec![FIRST_EIGHT_POWERS[power & 7]]; power >>= 3; while power > 0 { @@ -2064,7 +2065,7 @@ impl IeeeFloat { let calc_precision = (LIMB_BITS << attempt) - 1; attempt += 1; - let calc_normal_from_limbs = |sig: &mut Vec, + let calc_normal_from_limbs = |sig: &mut SmallVec<[Limb; 1]>, limbs: &[Limb]| -> StatusAnd { sig.resize(limbs_for_bits(calc_precision), 0); diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs index 6ea722ba769c1..69c9f385409e4 100644 --- a/src/librustc_apfloat/lib.rs +++ b/src/librustc_apfloat/lib.rs @@ -53,6 +53,7 @@ extern crate rustc_cratesio_shim; #[macro_use] extern crate bitflags; +extern crate smallvec; use std::cmp::Ordering; use std::fmt;