Skip to content

Commit 4931b5e

Browse files
Auto merge of #148040 - saethlin:trivial-consts, r=<try>
Add a fast path for lowering trivial consts
2 parents ab92564 + d0ab32e commit 4931b5e

File tree

11 files changed

+122
-9
lines changed

11 files changed

+122
-9
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
292292
tcx: TyCtxt<'tcx>,
293293
key: ty::PseudoCanonicalInput<'tcx, GlobalId<'tcx>>,
294294
) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
295+
if let Some((value, _ty)) = tcx.is_trivial_const(key.value.instance.def_id()) {
296+
return Ok(value);
297+
}
295298
tcx.eval_to_allocation_raw(key).map(|val| turn_into_const_value(tcx, val, key))
296299
}
297300

@@ -356,6 +359,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
356359
typing_env: ty::TypingEnv<'tcx>,
357360
) -> Result<R, ErrorHandled> {
358361
let def = cid.instance.def.def_id();
362+
359363
let is_static = tcx.is_static(def);
360364

361365
let mut ecx = InterpCx::new(
@@ -368,6 +372,18 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
368372
// so we have to reject reading mutable global memory.
369373
CompileTimeMachine::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
370374
);
375+
376+
if let Some((value, ty)) = tcx.is_trivial_const(def) {
377+
let layout = ecx.layout_of(ty).unwrap();
378+
let opty = ecx.const_val_to_op(value, ty, Some(layout)).unwrap();
379+
let res = ecx.allocate(layout, MemoryKind::Stack).unwrap();
380+
ecx.copy_op(&opty, &res).unwrap();
381+
382+
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &res).unwrap();
383+
384+
return Ok(R::make_result(res, &mut ecx));
385+
}
386+
371387
let res = ecx.load_mir(cid.instance.def, cid.promoted);
372388
res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body))
373389
.report_err()

compiler/rustc_interface/src/passes.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,9 @@ fn run_required_analyses(tcx: TyCtxt<'_>) {
10881088

10891089
sess.time("MIR_borrow_checking", || {
10901090
tcx.par_hir_body_owners(|def_id| {
1091+
if tcx.is_trivial_const(def_id).is_some() {
1092+
return;
1093+
}
10911094
if !tcx.is_typeck_child(def_id.to_def_id()) {
10921095
// Child unsafety and borrowck happens together with the parent
10931096
tcx.ensure_ok().check_unsafety(def_id);
@@ -1198,7 +1201,9 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
11981201
if tcx.sess.opts.unstable_opts.validate_mir {
11991202
sess.time("ensuring_final_MIR_is_computable", || {
12001203
tcx.par_hir_body_owners(|def_id| {
1201-
tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
1204+
if tcx.is_trivial_const(def_id).is_none() {
1205+
tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
1206+
}
12021207
});
12031208
});
12041209
}

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ provide! { tcx, def_id, other, cdata,
240240
thir_abstract_const => { table }
241241
optimized_mir => { table }
242242
mir_for_ctfe => { table }
243+
is_trivial_const => { table }
243244
closure_saved_names_of_captured_variables => { table }
244245
mir_coroutine_witnesses => { table }
245246
promoted_mir => { table }

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1791,8 +1791,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
17911791
record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses);
17921792
}
17931793
}
1794+
let mut is_trivial = false;
17941795
if encode_const {
1795-
record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id));
1796+
if let Some((val, ty)) = tcx.is_trivial_const(def_id) {
1797+
is_trivial = true;
1798+
record!(self.tables.is_trivial_const[def_id.to_def_id()] <- (val, ty));
1799+
} else {
1800+
is_trivial = false;
1801+
record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- tcx.mir_for_ctfe(def_id));
1802+
}
17961803

17971804
// FIXME(generic_const_exprs): this feels wrong to have in `encode_mir`
17981805
let abstract_const = tcx.thir_abstract_const(def_id);
@@ -1810,7 +1817,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18101817
}
18111818
}
18121819
}
1813-
record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
1820+
if !is_trivial {
1821+
record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
1822+
}
18141823

18151824
if self.tcx.is_coroutine(def_id.to_def_id())
18161825
&& let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id)
@@ -2234,6 +2243,9 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
22342243

22352244
let reachable_set = tcx.reachable_set(());
22362245
par_for_each_in(tcx.mir_keys(()), |&&def_id| {
2246+
if tcx.is_trivial_const(def_id).is_some() {
2247+
return;
2248+
}
22372249
let (encode_const, encode_opt) = should_encode_mir(tcx, reachable_set, def_id);
22382250

22392251
if encode_const {

compiler/rustc_metadata/src/rmeta/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
2929
use rustc_middle::middle::lib_features::FeatureStability;
3030
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
3131
use rustc_middle::mir;
32+
use rustc_middle::mir::ConstValue;
3233
use rustc_middle::ty::fast_reject::SimplifiedType;
3334
use rustc_middle::ty::{self, Ty, TyCtxt, UnusedGenericParams};
3435
use rustc_middle::util::Providers;
@@ -426,6 +427,7 @@ define_tables! {
426427
object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
427428
optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
428429
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
430+
is_trivial_const: Table<DefIndex, LazyValue<(ConstValue, Ty<'static>)>>,
429431
closure_saved_names_of_captured_variables: Table<DefIndex, LazyValue<IndexVec<FieldIdx, Symbol>>>,
430432
mir_coroutine_witnesses: Table<DefIndex, LazyValue<mir::CoroutineLayout<'static>>>,
431433
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,

compiler/rustc_metadata/src/rmeta/parameterized.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ trivially_parameterized_over_tcx! {
102102
rustc_middle::middle::lib_features::FeatureStability,
103103
rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault,
104104
rustc_middle::mir::ConstQualifs,
105+
rustc_middle::mir::ConstValue,
105106
rustc_middle::ty::AnonConstKind,
106107
rustc_middle::ty::AssocContainer,
107108
rustc_middle::ty::AsyncDestructor,

compiler/rustc_middle/src/mir/graphviz.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ where
1616

1717
let mirs = def_ids
1818
.iter()
19+
.filter(|def_id| tcx.is_trivial_const(*def_id).is_none())
1920
.flat_map(|def_id| {
2021
if tcx.is_const_fn(*def_id) {
2122
vec![tcx.optimized_mir(*def_id), tcx.mir_for_ctfe(*def_id)]

compiler/rustc_middle/src/mir/pretty.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,10 @@ pub fn write_mir_pretty<'tcx>(
353353
// are shared between mir_for_ctfe and optimized_mir
354354
writer.write_mir_fn(tcx.mir_for_ctfe(def_id), w)?;
355355
} else {
356-
let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id));
357-
render_body(w, instance_mir)?;
356+
if tcx.is_trivial_const(def_id).is_none() {
357+
let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id));
358+
render_body(w, instance_mir)?;
359+
}
358360
}
359361
}
360362
Ok(())

compiler/rustc_middle/src/query/erase.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,14 @@ impl EraseType for Result<mir::ConstValue, mir::interpret::ErrorHandled> {
160160
type Result = [u8; size_of::<Result<mir::ConstValue, mir::interpret::ErrorHandled>>()];
161161
}
162162

163+
impl EraseType for Option<mir::ConstValue> {
164+
type Result = [u8; size_of::<Option<mir::ConstValue>>()];
165+
}
166+
167+
impl EraseType for Option<(mir::ConstValue, Ty<'_>)> {
168+
type Result = [u8; size_of::<Option<(mir::ConstValue, Ty<'_>)>>()];
169+
}
170+
163171
impl EraseType for EvalToValTreeResult<'_> {
164172
type Result = [u8; size_of::<EvalToValTreeResult<'static>>()];
165173
}

compiler/rustc_middle/src/query/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2719,6 +2719,12 @@ rustc_queries! {
27192719
separate_provide_extern
27202720
}
27212721

2722+
query is_trivial_const(def_id: DefId) -> Option<(mir::ConstValue, Ty<'tcx>)> {
2723+
desc { |tcx| "checking if `{}` is a trivial const", tcx.def_path_str(def_id) }
2724+
cache_on_disk_if { def_id.is_local() }
2725+
separate_provide_extern
2726+
}
2727+
27222728
/// Checks for the nearest `#[sanitize(xyz = "off")]` or
27232729
/// `#[sanitize(xyz = "on")]` on this def and any enclosing defs, up to the
27242730
/// crate root.

0 commit comments

Comments
 (0)