Auto merge of #48864 - oli-obk:miri_incremental_regression, r=eddyb

Cache const eval queries

fixes #48846 (I think, still running more perf tests, but tuple-stress stops recomputing any constants)

r? @michaelwoerister
This commit is contained in:
bors 2018-03-14 15:39:59 +00:00
commit 11d9959641
4 changed files with 38 additions and 3 deletions

View File

@ -178,6 +178,18 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String {
format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id()))
}
#[inline]
fn cache_on_disk(_key: Self::Key) -> bool {
true
}
#[inline]
fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
id: SerializedDepNodeIndex)
-> Option<Self::Value> {
tcx.on_disk_query_result_cache.try_load_query_result(tcx, id).map(Ok)
}
}
impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> {

View File

@ -86,7 +86,7 @@ pub use self::on_disk_cache::OnDiskCache;
// the driver creates (using several `rustc_*` crates).
//
// The result of query must implement Clone. They must also implement ty::maps::values::Value
// which produces an appropiate error value if the query resulted in a query cycle.
// which produces an appropriate error value if the query resulted in a query cycle.
// Queries marked with `fatal_cycle` do not need that implementation
// as they will raise an fatal error on query cycles instead.
define_maps! { <'tcx>

View File

@ -221,6 +221,24 @@ impl<'sess> OnDiskCache<'sess> {
encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
encode_query_results::<check_match, _>(tcx, enc, qri)?;
encode_query_results::<trans_fn_attrs, _>(tcx, enc, qri)?;
// const eval is special, it only encodes successfully evaluated constants
use ty::maps::plumbing::GetCacheInternal;
for (key, entry) in const_eval::get_cache_internal(tcx).map.iter() {
use ty::maps::config::QueryDescription;
if const_eval::cache_on_disk(key.clone()) {
if let Ok(ref value) = entry.value {
let dep_node = SerializedDepNodeIndex::new(entry.index.index());
// Record position of the cache entry
qri.push((dep_node, AbsoluteBytePos::new(enc.position())));
// Encode the type check tables with the SerializedDepNodeIndex
// as tag.
enc.encode_tagged(dep_node, value)?;
}
}
}
}
// Encode diagnostics
@ -563,6 +581,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, '
tcx.interpret_interner.intern_at_reserved(alloc_id, allocation);
if let Some(glob) = Option::<DefId>::decode(self)? {
trace!("connecting alloc {:?} with {:?}", alloc_id, glob);
tcx.interpret_interner.cache(glob, alloc_id);
}

View File

@ -110,6 +110,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
span = mir.span;
let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?;
let alloc = tcx.interpret_interner.get_cached(cid.instance.def_id());
let is_static = tcx.is_static(cid.instance.def_id()).is_some();
let alloc = match alloc {
Some(alloc) => {
assert!(cid.promoted.is_none());
@ -123,7 +124,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
layout.align,
None,
)?;
if tcx.is_static(cid.instance.def_id()).is_some() {
if is_static {
tcx.interpret_interner.cache(cid.instance.def_id(), ptr.alloc_id);
}
let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
@ -151,8 +152,11 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
}
};
let ptr = MemoryPointer::new(alloc, 0).into();
// always try to read the value and report errors
let value = match ecx.try_read_value(ptr, layout.align, layout.ty)? {
Some(val) => val,
// if it's a constant (so it needs no address, directly compute its value)
Some(val) if !is_static => val,
// point at the allocation
_ => Value::ByRef(ptr, layout.align),
};
Ok((value, ptr, layout.ty))