Skip to content

Commit 8c050fc

Browse files
committed
rustc: compute ty::layout::Niche's available on the fly.
1 parent 5480b47 commit 8c050fc

File tree

1 file changed

+43
-29
lines changed

1 file changed

+43
-29
lines changed

Diff for: src/librustc/ty/layout.rs

+43-29
Original file line numberDiff line numberDiff line change
@@ -2225,24 +2225,50 @@ where
22252225
struct Niche {
22262226
offset: Size,
22272227
scalar: Scalar,
2228-
available: u128,
22292228
}
22302229

22312230
impl Niche {
2232-
fn reserve<'tcx>(
2233-
&self,
2234-
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
2235-
count: u128,
2236-
) -> Option<(u128, Scalar)> {
2237-
if count > self.available {
2238-
return None;
2239-
}
2231+
fn available<C: HasDataLayout>(&self, cx: &C) -> u128 {
2232+
let Scalar { value, valid_range: ref v } = self.scalar;
2233+
let bits = value.size(cx).bits();
2234+
assert!(bits <= 128);
2235+
let max_value = !0u128 >> (128 - bits);
2236+
2237+
// Find out how many values are outside the valid range.
2238+
let niche = v.end().wrapping_add(1)..*v.start();
2239+
niche.end.wrapping_sub(niche.start) & max_value
2240+
}
2241+
2242+
fn reserve<C: HasDataLayout>(&self, cx: &C, count: u128) -> Option<(u128, Scalar)> {
2243+
assert!(count > 0);
2244+
22402245
let Scalar { value, valid_range: ref v } = self.scalar;
22412246
let bits = value.size(cx).bits();
22422247
assert!(bits <= 128);
22432248
let max_value = !0u128 >> (128 - bits);
2249+
2250+
if count > max_value {
2251+
return None;
2252+
}
2253+
2254+
// Compute the range of invalid values being reserved.
22442255
let start = v.end().wrapping_add(1) & max_value;
22452256
let end = v.end().wrapping_add(count) & max_value;
2257+
2258+
// If the `end` of our range is inside the valid range,
2259+
// then we ran out of invalid values.
2260+
// FIXME(eddyb) abstract this with a wraparound range type.
2261+
let valid_range_contains = |x| {
2262+
if v.start() <= v.end() {
2263+
*v.start() <= x && x <= *v.end()
2264+
} else {
2265+
*v.start() <= x || x <= *v.end()
2266+
}
2267+
};
2268+
if valid_range_contains(end) {
2269+
return None;
2270+
}
2271+
22462272
Some((start, Scalar { value, valid_range: *v.start()..=end }))
22472273
}
22482274
}
@@ -2253,25 +2279,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
22532279
// FIXME(eddyb) traverse already optimized enums.
22542280
fn find_niche(&self, layout: TyLayout<'tcx>) -> Result<Option<Niche>, LayoutError<'tcx>> {
22552281
let scalar_niche = |scalar: &Scalar, offset| {
2256-
let Scalar { value, valid_range: ref v } = *scalar;
2257-
2258-
let bits = value.size(self).bits();
2259-
assert!(bits <= 128);
2260-
let max_value = !0u128 >> (128 - bits);
2261-
2262-
// Find out how many values are outside the valid range.
2263-
let available = if v.start() <= v.end() {
2264-
v.start() + (max_value - v.end())
2282+
let niche = Niche { offset, scalar: scalar.clone() };
2283+
if niche.available(self) > 0 {
2284+
Some(niche)
22652285
} else {
2266-
v.start() - v.end() - 1
2267-
};
2268-
2269-
// Give up if there is no niche value available.
2270-
if available == 0 {
2271-
return None;
2286+
None
22722287
}
2273-
2274-
Some(Niche { offset, scalar: scalar.clone(), available })
22752288
};
22762289

22772290
// Locals variables which live across yields are stored
@@ -2293,7 +2306,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
22932306
)
22942307
.chain(iter::once((a, Size::ZERO)))
22952308
.filter_map(|(scalar, offset)| scalar_niche(scalar, offset))
2296-
.max_by_key(|niche| niche.available);
2309+
.max_by_key(|niche| niche.available(self));
22972310
return Ok(niche);
22982311
}
22992312
Abi::Vector { ref element, .. } => {
@@ -2325,8 +2338,9 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
23252338
let mut available = 0;
23262339
for i in 0..layout.fields.count() {
23272340
if let Some(mut c) = self.find_niche(layout.field(self, i)?)? {
2328-
if c.available > available {
2329-
available = c.available;
2341+
let c_available = c.available(self);
2342+
if c_available > available {
2343+
available = c_available;
23302344
c.offset += layout.fields.offset(i);
23312345
niche = Some(c);
23322346
}

0 commit comments

Comments
 (0)