Skip to content

Commit f81ba2b

Browse files
committed
Auto merge of #57546 - dotdash:match, r=<try>
Avoid layout calculations in assert_bits to speed up match checking assert_bits ensures that the given type matches the type of the constant value, and additionally performs a query for the layout of the given type to get its size. This is then used to assert that it matches the size of the constant. But since the types are already known to be the same, this second check is unnecessary, and skipping it also allows to skip the expensive layout query. For the unicode_normalization crate, the match checking time drops from about 3.8s to about 0.8s for me. Ref #55528 cc unicode-rs/unicode-normalization#29
2 parents d6525ef + 42e996e commit f81ba2b

File tree

5 files changed

+16
-21
lines changed

5 files changed

+16
-21
lines changed

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2278,7 +2278,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
22782278
match tcx.const_eval(param_env.and(cid)) {
22792279
Ok(val) => {
22802280
// FIXME: Find the right type and use it instead of `val.ty` here
2281-
if let Some(b) = val.assert_bits(tcx.global_tcx(), param_env.and(val.ty)) {
2281+
if let Some(b) = val.assert_bits(param_env.and(val.ty)) {
22822282
trace!("discriminants: {} ({:?})", b, repr_type);
22832283
Some(Discr {
22842284
val: b,

src/librustc/ty/sty.rs

+11-16
Original file line numberDiff line numberDiff line change
@@ -2152,20 +2152,19 @@ impl<'tcx> Const<'tcx> {
21522152
}
21532153

21542154
#[inline]
2155-
pub fn assert_bits(
2156-
&self,
2157-
tcx: TyCtxt<'_, '_, '_>,
2158-
ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
2159-
) -> Option<u128> {
2155+
pub fn assert_bits(&self, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> Option<u128> {
21602156
assert_eq!(self.ty, ty.value);
2161-
let ty = tcx.lift_to_global(&ty).unwrap();
2162-
let size = tcx.layout_of(ty).ok()?.size;
2163-
self.val.try_to_bits(size)
2157+
match self.val.try_to_scalar()? {
2158+
Scalar::Bits { bits, .. } => {
2159+
Some(bits)
2160+
}
2161+
Scalar::Ptr(_) => None,
2162+
}
21642163
}
21652164

21662165
#[inline]
21672166
pub fn assert_bool(&self, tcx: TyCtxt<'_, '_, '_>) -> Option<bool> {
2168-
self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.bool)).and_then(|v| match v {
2167+
self.assert_bits(ParamEnv::empty().and(tcx.types.bool)).and_then(|v| match v {
21692168
0 => Some(false),
21702169
1 => Some(true),
21712170
_ => None,
@@ -2174,16 +2173,12 @@ impl<'tcx> Const<'tcx> {
21742173

21752174
#[inline]
21762175
pub fn assert_usize(&self, tcx: TyCtxt<'_, '_, '_>) -> Option<u64> {
2177-
self.assert_bits(tcx, ParamEnv::empty().and(tcx.types.usize)).map(|v| v as u64)
2176+
self.assert_bits(ParamEnv::empty().and(tcx.types.usize)).map(|v| v as u64)
21782177
}
21792178

21802179
#[inline]
2181-
pub fn unwrap_bits(
2182-
&self,
2183-
tcx: TyCtxt<'_, '_, '_>,
2184-
ty: ParamEnvAnd<'tcx, Ty<'tcx>>,
2185-
) -> u128 {
2186-
self.assert_bits(tcx, ty).unwrap_or_else(||
2180+
pub fn unwrap_bits(&self, ty: ParamEnvAnd<'tcx, Ty<'tcx>>) -> u128 {
2181+
self.assert_bits(ty).unwrap_or_else(||
21872182
bug!("expected bits of {}, got {:#?}", ty.value, self))
21882183
}
21892184

src/librustc_mir/build/matches/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
114114
let switch_ty = ty::ParamEnv::empty().and(switch_ty);
115115
indices.entry(value)
116116
.or_insert_with(|| {
117-
options.push(value.unwrap_bits(self.hir.tcx(), switch_ty));
117+
options.push(value.unwrap_bits(switch_ty));
118118
options.len() - 1
119119
});
120120
true

src/librustc_mir/hair/pattern/_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ impl<'tcx> IntRange<'tcx> {
844844
}
845845
ConstantValue(val) if is_integral(val.ty) => {
846846
let ty = val.ty;
847-
if let Some(val) = val.assert_bits(tcx, ty::ParamEnv::empty().and(ty)) {
847+
if let Some(val) = val.assert_bits(ty::ParamEnv::empty().and(ty)) {
848848
let bias = IntRange::signed_bias(tcx, ty);
849849
let val = val ^ bias;
850850
Some(IntRange { range: val..=val, ty })
@@ -1458,7 +1458,7 @@ fn slice_pat_covered_by_const<'tcx>(
14581458
{
14591459
match pat.kind {
14601460
box PatternKind::Constant { value } => {
1461-
let b = value.unwrap_bits(tcx, ty::ParamEnv::empty().and(pat.ty));
1461+
let b = value.unwrap_bits(ty::ParamEnv::empty().and(pat.ty));
14621462
assert_eq!(b as u8 as u128, b);
14631463
if b as u8 != *ch {
14641464
return Ok(false);

src/librustc_mir/transform/simplify_branches.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl MirPass for SimplifyBranches {
3030
discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, ..
3131
} => {
3232
let switch_ty = ParamEnv::empty().and(switch_ty);
33-
let constant = c.literal.map_evaluated(|c| c.assert_bits(tcx, switch_ty));
33+
let constant = c.literal.map_evaluated(|c| c.assert_bits(switch_ty));
3434
if let Some(constant) = constant {
3535
let (otherwise, targets) = targets.split_last().unwrap();
3636
let mut ret = TerminatorKind::Goto { target: *otherwise };

0 commit comments

Comments
 (0)