Skip to content

Commit 64687bb

Browse files
committed
Auto merge of #64673 - Mark-Simulacrum:opt-match-ck, r=<try>
Optimize match checking to avoid layout queries In code with large, single-value match statements, we were previously spending a lot of time running layout_of for the primitive types (integers, chars) -- which is essentially useless. This optimizes the code to avoid those query calls by directly obtaining the size for these types, when possible. We fallback to the (slower) previous code if that fails, so this is not a behavior change. r? @Centril who I believe knows this code enough, but if not feel free to re-assign
2 parents 4ff32c0 + 9c62117 commit 64687bb

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/librustc/ty/sty.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_macros::HashStable;
1313
use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, Kind, UnpackedKind};
1414
use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable};
1515
use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
16-
use crate::ty::layout::VariantIdx;
16+
use crate::ty::layout::{Size, Integer, IntegerExt, VariantIdx};
1717
use crate::util::captures::Captures;
1818
use crate::mir::interpret::{Scalar, GlobalId};
1919

@@ -24,6 +24,7 @@ use std::marker::PhantomData;
2424
use std::ops::Range;
2525
use rustc_target::spec::abi;
2626
use syntax::ast::{self, Ident};
27+
use syntax::attr::{SignedInt, UnsignedInt};
2728
use syntax::symbol::{kw, InternedString};
2829

2930
use self::InferTy::*;
@@ -2298,8 +2299,21 @@ impl<'tcx> Const<'tcx> {
22982299
ty: Ty<'tcx>,
22992300
) -> Option<u128> {
23002301
assert_eq!(self.ty, ty);
2302+
// This is purely an optimization -- layout_of is a pretty expensive operation,
2303+
// but if we can determine the size without calling it, we don't need all that complexity
2304+
// (hashing, caching, etc.). As such, try to skip it.
2305+
let size = match ty.sty {
2306+
ty::Bool => Size::from_bytes(1),
2307+
ty::Char => Size::from_bytes(4),
2308+
ty::Int(ity) => {
2309+
Integer::from_attr(&tcx, SignedInt(ity)).size()
2310+
}
2311+
ty::Uint(uty) => {
2312+
Integer::from_attr(&tcx, UnsignedInt(uty)).size()
2313+
}
2314+
_ => tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size,
2315+
};
23012316
// if `ty` does not depend on generic parameters, use an empty param_env
2302-
let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
23032317
self.eval(tcx, param_env).val.try_to_bits(size)
23042318
}
23052319

0 commit comments

Comments
 (0)