Skip to content

Commit

Permalink
Auto merge of #56269 - nnethercote:_match-Matrix-SmallVec, r=simulacrum
Browse files Browse the repository at this point in the history
Use a `SmallVec` within `_match::Matrix`.

This avoids allocations.
  • Loading branch information
bors committed Dec 10, 2018
2 parents 9cb38a8 + cdc6633 commit e2c329c
Show file tree
Hide file tree
Showing 14 changed files with 65 additions and 59 deletions.
40 changes: 20 additions & 20 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.75 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
Expand Down Expand Up @@ -489,7 +489,7 @@ dependencies = [
"crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand Down Expand Up @@ -1518,7 +1518,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]

Expand All @@ -1529,7 +1529,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]

Expand Down Expand Up @@ -1992,7 +1992,7 @@ dependencies = [
"rustc_target 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_pos 0.0.0",
"tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
Expand Down Expand Up @@ -2037,7 +2037,7 @@ dependencies = [
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

Expand Down Expand Up @@ -2073,7 +2073,7 @@ name = "rustc-ap-serialize"
version = "297.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand All @@ -2089,7 +2089,7 @@ dependencies = [
"rustc-ap-serialize 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-ap-syntax_pos 297.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand Down Expand Up @@ -2172,7 +2172,7 @@ dependencies = [
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_target 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
Expand All @@ -2183,7 +2183,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)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand Down Expand Up @@ -2288,7 +2288,7 @@ dependencies = [
"rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_cratesio_shim 0.0.0",
"serialize 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

Expand Down Expand Up @@ -2322,7 +2322,7 @@ dependencies = [
"rustc_typeck 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_ext 0.0.0",
"syntax_pos 0.0.0",
Expand Down Expand Up @@ -2428,7 +2428,7 @@ dependencies = [
"rustc_errors 0.0.0",
"rustc_target 0.0.0",
"serialize 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
Expand Down Expand Up @@ -2541,7 +2541,7 @@ dependencies = [
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_target 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
Expand All @@ -2568,7 +2568,7 @@ dependencies = [
"rustc_errors 0.0.0",
"rustc_platform_intrinsics 0.0.0",
"rustc_target 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
Expand Down Expand Up @@ -2737,7 +2737,7 @@ dependencies = [
name = "serialize"
version = "0.0.0"
dependencies = [
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
Expand All @@ -2757,7 +2757,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "smallvec"
version = "0.6.5"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
Expand Down Expand Up @@ -2904,7 +2904,7 @@ dependencies = [
"rustc_target 0.0.0",
"scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serialize 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax_pos 0.0.0",
]

Expand All @@ -2917,7 +2917,7 @@ dependencies = [
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
"rustc_target 0.0.0",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
Expand Down Expand Up @@ -3489,7 +3489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9"
"checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
"checksum smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b73ea3738b47563803ef814925e69be00799a8c07420be8b996f8e98fb2336db"
"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7"
"checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
"checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ parking_lot = "0.6"
byteorder = { version = "1.1", features = ["i128"]}
chalk-engine = { version = "0.8.0", default-features=false }
rustc_fs_util = { path = "../librustc_fs_util" }
smallvec = { version = "0.6.5", features = ["union"] }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }

# Note that these dependencies are a lie, they're just here to get linkage to
# work.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_allocator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ rustc_target = { path = "../librustc_target" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
log = "0.4"
smallvec = { version = "0.6.5", features = ["union"] }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
2 changes: 1 addition & 1 deletion src/librustc_apfloat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ path = "lib.rs"
[dependencies]
bitflags = "1.0"
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
smallvec = { version = "0.6.5", features = ["union"] }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
2 changes: 1 addition & 1 deletion src/librustc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ stable_deref_trait = "1.0.0"
rustc-rayon = "0.1.1"
rustc-rayon-core = "0.1.1"
rustc-hash = "1.0.1"
smallvec = { version = "0.6.5", features = ["union"] }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }

[dependencies.parking_lot]
version = "0.6"
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ rustc_codegen_utils = { path = "../librustc_codegen_utils" }
rustc_typeck = { path = "../librustc_typeck" }
serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" }
smallvec = { version = "0.6.5", features = ["union"] }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
byteorder = { version = "1.1", features = ["i128"] }
rustc_apfloat = { path = "../librustc_apfloat" }
smallvec = { version = "0.6.5", features = ["union"] }
smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
51 changes: 28 additions & 23 deletions src/librustc_mir/hair/pattern/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ use syntax_pos::{Span, DUMMY_SP};

use arena::TypedArena;

use smallvec::{SmallVec, smallvec};
use std::cmp::{self, Ordering, min, max};
use std::fmt;
use std::iter::{FromIterator, IntoIterator};
Expand Down Expand Up @@ -237,14 +238,16 @@ impl<'tcx> Pattern<'tcx> {
}
}

pub struct Matrix<'a, 'tcx: 'a>(Vec<Vec<&'a Pattern<'tcx>>>);
/// A 2D matrix. Nx1 matrices are very common, which is why `SmallVec[_; 2]`
/// works well for each row.
pub struct Matrix<'p, 'tcx: 'p>(Vec<SmallVec<[&'p Pattern<'tcx>; 2]>>);

impl<'a, 'tcx> Matrix<'a, 'tcx> {
impl<'p, 'tcx> Matrix<'p, 'tcx> {
pub fn empty() -> Self {
Matrix(vec![])
}

pub fn push(&mut self, row: Vec<&'a Pattern<'tcx>>) {
pub fn push(&mut self, row: SmallVec<[&'p Pattern<'tcx>; 2]>) {
self.0.push(row)
}
}
Expand All @@ -261,7 +264,7 @@ impl<'a, 'tcx> Matrix<'a, 'tcx> {
/// ++++++++++++++++++++++++++
/// + _ + [_, _, ..tail] +
/// ++++++++++++++++++++++++++
impl<'a, 'tcx> fmt::Debug for Matrix<'a, 'tcx> {
impl<'p, 'tcx> fmt::Debug for Matrix<'p, 'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\n")?;

Expand Down Expand Up @@ -293,8 +296,9 @@ impl<'a, 'tcx> fmt::Debug for Matrix<'a, 'tcx> {
}
}

impl<'a, 'tcx> FromIterator<Vec<&'a Pattern<'tcx>>> for Matrix<'a, 'tcx> {
fn from_iter<T: IntoIterator<Item=Vec<&'a Pattern<'tcx>>>>(iter: T) -> Self
impl<'p, 'tcx> FromIterator<SmallVec<[&'p Pattern<'tcx>; 2]>> for Matrix<'p, 'tcx> {
fn from_iter<T>(iter: T) -> Self
where T: IntoIterator<Item=SmallVec<[&'p Pattern<'tcx>; 2]>>
{
Matrix(iter.into_iter().collect())
}
Expand Down Expand Up @@ -998,7 +1002,7 @@ fn compute_missing_ctors<'a, 'tcx: 'a>(
/// matrix isn't exhaustive).
pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
matrix: &Matrix<'p, 'tcx>,
v: &[&'p Pattern<'tcx>],
v: &[&Pattern<'tcx>],
witness: WitnessPreference)
-> Usefulness<'tcx> {
let &Matrix(ref rows) = matrix;
Expand Down Expand Up @@ -1108,7 +1112,7 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
} else {
let matrix = rows.iter().filter_map(|r| {
if r[0].is_wildcard() {
Some(r[1..].to_vec())
Some(SmallVec::from_slice(&r[1..]))
} else {
None
}
Expand Down Expand Up @@ -1199,10 +1203,10 @@ pub fn is_useful<'p, 'a: 'p, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>,

/// A shorthand for the `U(S(c, P), S(c, q))` operation from the paper. I.e., `is_useful` applied
/// to the specialised version of both the pattern matrix `P` and the new pattern `q`.
fn is_useful_specialized<'p, 'a:'p, 'tcx: 'a>(
fn is_useful_specialized<'p, 'a: 'p, 'tcx: 'a>(
cx: &mut MatchCheckCtxt<'a, 'tcx>,
&Matrix(ref m): &Matrix<'p, 'tcx>,
v: &[&'p Pattern<'tcx>],
v: &[&Pattern<'tcx>],
ctor: Constructor<'tcx>,
lty: Ty<'tcx>,
witness: WitnessPreference,
Expand Down Expand Up @@ -1521,15 +1525,15 @@ fn constructor_intersects_pattern<'p, 'a: 'p, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
ctor: &Constructor<'tcx>,
pat: &'p Pattern<'tcx>,
) -> Option<Vec<&'p Pattern<'tcx>>> {
) -> Option<SmallVec<[&'p Pattern<'tcx>; 2]>> {
if should_treat_range_exhaustively(tcx, ctor) {
match (IntRange::from_ctor(tcx, ctor), IntRange::from_pat(tcx, pat)) {
(Some(ctor), Some(pat)) => {
ctor.intersection(&pat).map(|_| {
let (pat_lo, pat_hi) = pat.range.into_inner();
let (ctor_lo, ctor_hi) = ctor.range.into_inner();
assert!(pat_lo <= ctor_lo && ctor_hi <= pat_hi);
vec![]
smallvec![]
})
}
_ => None,
Expand All @@ -1539,7 +1543,7 @@ fn constructor_intersects_pattern<'p, 'a: 'p, 'tcx: 'a>(
// conveniently handled by `IntRange`. For these cases, the constructor may not be a range
// so intersection actually devolves into being covered by the pattern.
match constructor_covered_by_range(tcx, ctor, pat) {
Ok(true) => Some(vec![]),
Ok(true) => Some(smallvec![]),
Ok(false) | Err(ErrorReported) => None,
}
}
Expand Down Expand Up @@ -1610,9 +1614,9 @@ fn constructor_covered_by_range<'a, 'tcx>(
fn patterns_for_variant<'p, 'a: 'p, 'tcx: 'a>(
subpatterns: &'p [FieldPattern<'tcx>],
wild_patterns: &[&'p Pattern<'tcx>])
-> Vec<&'p Pattern<'tcx>>
-> SmallVec<[&'p Pattern<'tcx>; 2]>
{
let mut result = wild_patterns.to_owned();
let mut result = SmallVec::from_slice(wild_patterns);

for subpat in subpatterns {
result[subpat.field.index()] = &subpat.pattern;
Expand All @@ -1635,15 +1639,16 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
r: &[&'p Pattern<'tcx>],
constructor: &Constructor<'tcx>,
wild_patterns: &[&'p Pattern<'tcx>],
) -> Option<Vec<&'p Pattern<'tcx>>> {
) -> Option<SmallVec<[&'p Pattern<'tcx>; 2]>> {
let pat = &r[0];

let head: Option<Vec<&Pattern>> = match *pat.kind {
PatternKind::AscribeUserType { ref subpattern, .. } =>
specialize(cx, ::std::slice::from_ref(&subpattern), constructor, wild_patterns),
let head = match *pat.kind {
PatternKind::AscribeUserType { ref subpattern, .. } => {
specialize(cx, ::std::slice::from_ref(&subpattern), constructor, wild_patterns)
}

PatternKind::Binding { .. } | PatternKind::Wild => {
Some(wild_patterns.to_owned())
Some(SmallVec::from_slice(wild_patterns))
}

PatternKind::Variant { adt_def, variant_index, ref subpatterns, .. } => {
Expand All @@ -1660,7 +1665,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
}

PatternKind::Deref { ref subpattern } => {
Some(vec![subpattern])
Some(smallvec![subpattern])
}

PatternKind::Constant { value } => {
Expand Down Expand Up @@ -1696,7 +1701,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
if wild_patterns.len() as u64 == n {
// convert a constant slice/array pattern to a list of patterns.
match (n, opt_ptr) {
(0, _) => Some(Vec::new()),
(0, _) => Some(SmallVec::new()),
(_, Some(ptr)) => {
let alloc = cx.tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id);
let layout = cx.tcx.layout_of(cx.param_env.and(ty)).ok()?;
Expand Down Expand Up @@ -1765,7 +1770,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
match slice_pat_covered_by_constructor(
cx.tcx, pat.span, constructor, prefix, slice, suffix
) {
Ok(true) => Some(vec![]),
Ok(true) => Some(smallvec![]),
Ok(false) => None,
Err(ErrorReported) => None
}
Expand Down
Loading

0 comments on commit e2c329c

Please sign in to comment.