Skip to content

Commit 56504a0

Browse files
authored
Rollup merge of #80042 - sivadeilra:cold_bits, r=oli-obk
Split a func into cold/hot parts, reducing binary size I noticed that the Size::bits function is called in many places, and is inlined into them. On x86_64-pc-windows-msvc, this function is inlined 527 times, and compiled separately (non-inlined) 3 times. Each of those inlined calls contains code that panics. This commit moves the `panic!` call into a separate function and marks that function with `#[cold]`. This reduces binary size by 24 KB. Not much, but it's something. Changes like this often reduce pressure on instruction-caches, since it reduces the amount of code that is inlined into hot code paths. Or more precisely, it removes cold code from hot cache lines.
2 parents edcfe7b + 4721b65 commit 56504a0

File tree

1 file changed

+20
-6
lines changed
  • compiler/rustc_target/src/abi

1 file changed

+20
-6
lines changed

compiler/rustc_target/src/abi/mod.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -271,22 +271,38 @@ impl ToJson for Endian {
271271
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
272272
#[derive(HashStable_Generic)]
273273
pub struct Size {
274+
// The top 3 bits are ALWAYS zero.
274275
raw: u64,
275276
}
276277

277278
impl Size {
278279
pub const ZERO: Size = Size { raw: 0 };
279280

280-
#[inline]
281+
/// Rounds `bits` up to the next-higher byte boundary, if `bits` is
282+
/// is not aligned.
281283
pub fn from_bits(bits: impl TryInto<u64>) -> Size {
282284
let bits = bits.try_into().ok().unwrap();
285+
286+
#[cold]
287+
fn overflow(bits: u64) -> ! {
288+
panic!("Size::from_bits({}) has overflowed", bits);
289+
}
290+
291+
// This is the largest value of `bits` that does not cause overflow
292+
// during rounding, and guarantees that the resulting number of bytes
293+
// cannot cause overflow when multiplied by 8.
294+
if bits > 0xffff_ffff_ffff_fff8 {
295+
overflow(bits);
296+
}
297+
283298
// Avoid potential overflow from `bits + 7`.
284-
Size::from_bytes(bits / 8 + ((bits % 8) + 7) / 8)
299+
Size { raw: bits / 8 + ((bits % 8) + 7) / 8 }
285300
}
286301

287302
#[inline]
288303
pub fn from_bytes(bytes: impl TryInto<u64>) -> Size {
289-
Size { raw: bytes.try_into().ok().unwrap() }
304+
let bytes: u64 = bytes.try_into().ok().unwrap();
305+
Size { raw: bytes }
290306
}
291307

292308
#[inline]
@@ -301,9 +317,7 @@ impl Size {
301317

302318
#[inline]
303319
pub fn bits(self) -> u64 {
304-
self.bytes().checked_mul(8).unwrap_or_else(|| {
305-
panic!("Size::bits: {} bytes in bits doesn't fit in u64", self.bytes())
306-
})
320+
self.raw << 3
307321
}
308322

309323
#[inline]

0 commit comments

Comments
 (0)