From 0d88db1693a07095555d07d14ffdcb373b6bc352 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 13 Mar 2018 16:21:54 +0100 Subject: [PATCH] Reuse the query caching infrastructure for const eval --- src/librustc/ty/maps/config.rs | 6 +-- src/librustc/ty/maps/on_disk_cache.rs | 63 +++--------------------- src/librustc_mir/interpret/const_eval.rs | 8 ++- 3 files changed, 16 insertions(+), 61 deletions(-) diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs index 7e2ece1b334b9..bcd58e993044d 100644 --- a/src/librustc/ty/maps/config.rs +++ b/src/librustc/ty/maps/config.rs @@ -158,15 +158,15 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> { } #[inline] - fn cache_on_disk(key: Self::Key) -> bool { - key.value.instance.def_id().is_local() + fn cache_on_disk(_key: Self::Key) -> bool { + true } #[inline] fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: SerializedDepNodeIndex) -> Option { - tcx.on_disk_query_result_cache.load_constant(tcx, id).map(Ok) + tcx.on_disk_query_result_cache.try_load_query_result(tcx, id).map(Ok) } } diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs index bb0b1975b9e46..35e874b74d9ae 100644 --- a/src/librustc/ty/maps/on_disk_cache.rs +++ b/src/librustc/ty/maps/on_disk_cache.rs @@ -75,10 +75,6 @@ pub struct OnDiskCache<'sess> { // A map from dep-node to the position of any associated diagnostics in // `serialized_data`. prev_diagnostics_index: FxHashMap, - - // A map from dep-node to the position of any associated constants in - // `serialized_data`. - prev_constants_index: FxHashMap, } // This type is used only for (de-)serialization. @@ -88,10 +84,8 @@ struct Footer { prev_cnums: Vec<(u32, String, CrateDisambiguator)>, query_result_index: EncodedQueryResultIndex, diagnostics_index: EncodedQueryResultIndex, - constants_index: EncodedConstantsIndex, } -type EncodedConstantsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedQueryResultIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnosticsIndex = Vec<(SerializedDepNodeIndex, AbsoluteBytePos)>; type EncodedDiagnostics = Vec; @@ -145,7 +139,6 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: RefCell::new(FxHashMap()), query_result_index: footer.query_result_index.into_iter().collect(), prev_diagnostics_index: footer.diagnostics_index.into_iter().collect(), - prev_constants_index: footer.constants_index.into_iter().collect(), synthetic_expansion_infos: RefCell::new(FxHashMap()), } } @@ -161,7 +154,6 @@ impl<'sess> OnDiskCache<'sess> { current_diagnostics: RefCell::new(FxHashMap()), query_result_index: FxHashMap(), prev_diagnostics_index: FxHashMap(), - prev_constants_index: FxHashMap(), synthetic_expansion_infos: RefCell::new(FxHashMap()), } } @@ -229,46 +221,25 @@ impl<'sess> OnDiskCache<'sess> { encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; - } - // encode successful constant evaluations - let constants_index = { - let mut constants_index = EncodedConstantsIndex::new(); - use ty::maps::queries::const_eval; + // const eval is special, it only encodes successfully evaluated constants use ty::maps::plumbing::GetCacheInternal; - use ty::maps::config::QueryDescription; for (key, entry) in const_eval::get_cache_internal(tcx).map.iter() { - if let Ok(ref constant) = entry.value { - if const_eval::cache_on_disk(key.clone()) { - trace!("caching constant {:?} with value {:#?}", key, constant); + 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 - constants_index.push(( - dep_node, - AbsoluteBytePos::new(encoder.position()), - )); - let did = key.value.instance.def_id(); - let constant = if key.value.promoted.is_none() - && tcx.is_static(did).is_some() { - // memorize the allocation for the static, too, so - // we can refer to the static, not just read its value - // since we have had a successful query, the cached value must - // exist, so we can unwrap it - let cached = tcx.interpret_interner.get_cached(did).unwrap(); - (constant, Some(cached)) - } else { - (constant, None) - }; + qri.push((dep_node, AbsoluteBytePos::new(enc.position()))); // Encode the type check tables with the SerializedDepNodeIndex // as tag. - encoder.encode_tagged(dep_node, &constant)?; + enc.encode_tagged(dep_node, value)?; } } } - constants_index - }; + } // Encode diagnostics let diagnostics_index = { @@ -303,7 +274,6 @@ impl<'sess> OnDiskCache<'sess> { prev_cnums, query_result_index, diagnostics_index, - constants_index, })?; // Encode the position of the footer as the last 8 bytes of the @@ -326,25 +296,6 @@ impl<'sess> OnDiskCache<'sess> { }) } - /// Load a constant emitted during the previous compilation session. - pub fn load_constant<'a, 'tcx>(&self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - dep_node_index: SerializedDepNodeIndex) - -> Option<&'tcx ty::Const<'tcx>> { - type Encoded<'tcx> = (ty::Const<'tcx>, Option); - let constant: Option> = self.load_indexed( - tcx, - dep_node_index, - &self.prev_constants_index, - "constants"); - - constant.map(|(c, _alloc_id)| { - // the AllocId decoding already registers the AllocId to its DefId - // so we don't need to take additional actions here - tcx.mk_const(c) - }) - } - /// Load a diagnostic emitted during the previous compilation session. pub fn load_diagnostics<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index ee5874be9d70a..82eb28287b033 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -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))