Skip to content

Commit 8907237

Browse files
Auto merge of #148040 - saethlin:trivial-consts, r=<try>
Add a fast path for lowering trivial consts
2 parents f435972 + 13c516e commit 8907237

File tree

16 files changed

+148
-69
lines changed

16 files changed

+148
-69
lines changed

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 15 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.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

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

compiler/rustc_interface/src/passes.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,9 +1088,15 @@ 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_typeck_child(def_id.to_def_id()) {
1091+
let not_typeck_child = !tcx.is_typeck_child(def_id.to_def_id());
1092+
if not_typeck_child {
10921093
// Child unsafety and borrowck happens together with the parent
10931094
tcx.ensure_ok().check_unsafety(def_id);
1095+
}
1096+
if tcx.is_trivial_const(def_id) {
1097+
return;
1098+
}
1099+
if not_typeck_child {
10941100
tcx.ensure_ok().mir_borrowck(def_id);
10951101
tcx.ensure_ok().check_transmutes(def_id);
10961102
}
@@ -1198,7 +1204,9 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
11981204
if tcx.sess.opts.unstable_opts.validate_mir {
11991205
sess.time("ensuring_final_MIR_is_computable", || {
12001206
tcx.par_hir_body_owners(|def_id| {
1201-
tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
1207+
if !tcx.is_trivial_const(def_id) {
1208+
tcx.instance_mir(ty::InstanceKind::Item(def_id.into()));
1209+
}
12021210
});
12031211
});
12041212
}

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+
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.trivial_const(def_id) {
1797+
is_trivial = true;
1798+
record!(self.tables.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) {
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+
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))
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: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,16 @@ 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 let Some((val, ty)) = tcx.trivial_const(def_id) {
357+
ty::print::with_forced_impl_filename_line! {
358+
// see notes on #41697 elsewhere
359+
write!(w, "const {}", tcx.def_path_str(def_id))?
360+
}
361+
writeln!(w, ": {} = const {};", ty, Const::Val(val, ty))?;
362+
} else {
363+
let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id));
364+
render_body(w, instance_mir)?;
365+
}
358366
}
359367
}
360368
Ok(())

compiler/rustc_middle/src/query/erase.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ 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, Ty<'_>)> {
164+
type Result = [u8; size_of::<Option<(mir::ConstValue, Ty<'_>)>>()];
165+
}
166+
163167
impl EraseType for EvalToValTreeResult<'_> {
164168
type Result = [u8; size_of::<EvalToValTreeResult<'static>>()];
165169
}

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 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)