Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,20 @@ pub(crate) fn eval_to_valtree<'tcx>(
cid: GlobalId<'tcx>,
) -> EvalToValTreeResult<'tcx> {
crate::assert_typing_mode(typing_env.typing_mode());

// Fast path: a trivial scalar constant of leaf type — e.g. a literal
// array length or const-generic argument, the most common type-level
// consts — would otherwise spin up two interpreter contexts (one to
// allocate and validate, one to read back) just to rebuild a value we
// already know. Build the leaf valtree directly.
if cid.promoted.is_none()
&& let Some((mir::ConstValue::Scalar(Scalar::Int(int)), ty)) =
tcx.trivial_const(cid.instance.def_id())
&& ty.is_primitive()
{
return Ok(ty::ValTree::from_scalar_int(tcx, int));
}

let const_alloc = tcx.eval_to_allocation_raw(typing_env.as_query_input(cid))?;

// FIXME Need to provide a span to `eval_to_valtree`
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2357,6 +2357,13 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
#[instrument(level = "debug", skip(self))]
fn check_false_global_bounds(&mut self) {
let tcx = self.ocx.infcx.tcx;

// No predicates, no possible false global bound; skip building the
// elaborator. This is the case for most items.
if tcx.predicates_of(self.body_def_id).predicates.is_empty() {
return;
}

let mut span = tcx.def_span(self.body_def_id);
let empty_env = ty::ParamEnv::empty();

Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_monomorphize/src/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@
use std::cell::OnceCell;
use std::ops::ControlFlow;

use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_data_structures::sync::{Lock, par_for_each_in};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir as hir;
Expand Down Expand Up @@ -287,17 +287,25 @@ impl<'tcx> UsageMap<'tcx> {
}

/// Internally iterate over all inlined items used by `item`.
///
/// `inlined_memo` caches `instantiation_mode` per item: it is a pure
/// function of the item, but it performs several query lookups, and an
/// inlined item reachable from N roots would otherwise recompute it N
/// times during partitioning.
pub(crate) fn for_each_inlined_used_item<F>(
&self,
tcx: TyCtxt<'tcx>,
item: MonoItem<'tcx>,
inlined_memo: &mut FxHashMap<MonoItem<'tcx>, bool>,
mut f: F,
) where
F: FnMut(MonoItem<'tcx>),
{
let used_items = self.used_map.get(&item).unwrap();
for used_item in used_items.iter() {
let is_inlined = used_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy;
let is_inlined = *inlined_memo.entry(*used_item).or_insert_with(|| {
used_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy
});
if is_inlined {
f(*used_item);
}
Expand Down
27 changes: 19 additions & 8 deletions compiler/rustc_monomorphize/src/partitioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};

use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_data_structures::sync::par_join;
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_hir::LangItem;
Expand Down Expand Up @@ -216,6 +216,7 @@ where
let cgu_name_builder = &mut CodegenUnitNameBuilder::new(cx.tcx);
let cgu_name_cache = &mut UnordMap::default();

let mut inlined_memo = FxHashMap::default();
for mono_item in mono_items {
// Handle only root (GloballyShared) items directly here. Inlined (LocalCopy) items
// are handled at the bottom of the loop based on reachability, with one exception.
Expand Down Expand Up @@ -264,7 +265,13 @@ where
// external crates, and local functions the definition of which is
// marked with `#[inline]`.
let mut reachable_inlined_items = FxIndexSet::default();
get_reachable_inlined_items(cx.tcx, mono_item, cx.usage_map, &mut reachable_inlined_items);
get_reachable_inlined_items(
cx.tcx,
mono_item,
cx.usage_map,
&mut inlined_memo,
&mut reachable_inlined_items,
);

// Add those inlined items. It's possible an inlined item is reachable
// from multiple root items within a CGU, which is fine, it just means
Expand Down Expand Up @@ -301,14 +308,18 @@ where
tcx: TyCtxt<'tcx>,
item: MonoItem<'tcx>,
usage_map: &UsageMap<'tcx>,
inlined_memo: &mut FxHashMap<MonoItem<'tcx>, bool>,
visited: &mut FxIndexSet<MonoItem<'tcx>>,
) {
usage_map.for_each_inlined_used_item(tcx, item, |inlined_item| {
let is_new = visited.insert(inlined_item);
if is_new {
get_reachable_inlined_items(tcx, inlined_item, usage_map, visited);
}
});
let mut worklist = vec![item];
while let Some(item) = worklist.pop() {
usage_map.for_each_inlined_used_item(tcx, item, inlined_memo, |inlined_item| {
let is_new = visited.insert(inlined_item);
if is_new {
worklist.push(inlined_item);
}
});
}
}
}

Expand Down
Loading