-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Miri: avoid tracking current location three times #72879
Merged
Merged
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
871513d
make miri memory TyCtxtAt a TyCtxt
RalfJung dc6ffae
make miri InterpCx TyCtxtAt a TyCtxt, and separately remember the roo…
RalfJung 0ac6fd0
fix const_prop spans and re-bless tests
RalfJung 32b01c7
avoid computing cur_span all the time
RalfJung 6049650
avoid computing precise span for const_eval query
RalfJung c6512fd
run const_eval_raw with root_span
RalfJung 2210abe
keep root_span and tcx together
RalfJung File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,11 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { | |
pub machine: M, | ||
|
||
/// The results of the type checker, from rustc. | ||
pub tcx: TyCtxtAt<'tcx>, | ||
pub tcx: TyCtxt<'tcx>, | ||
|
||
/// The span of the "root" of the evaluation, i.e., the const | ||
/// we are evaluating (if this is CTFE). | ||
pub(super) root_span: Span, | ||
|
||
/// Bounds in scope for polymorphic evaluations. | ||
pub(crate) param_env: ty::ParamEnv<'tcx>, | ||
|
@@ -196,7 +200,7 @@ where | |
{ | ||
#[inline] | ||
fn tcx(&self) -> TyCtxt<'tcx> { | ||
*self.tcx | ||
self.tcx | ||
} | ||
} | ||
|
||
|
@@ -209,13 +213,13 @@ where | |
} | ||
} | ||
|
||
impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { | ||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { | ||
type Ty = Ty<'tcx>; | ||
type TyAndLayout = InterpResult<'tcx, TyAndLayout<'tcx>>; | ||
|
||
#[inline] | ||
fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout { | ||
self.tcx | ||
self.tcx_at() | ||
.layout_of(self.param_env.and(ty)) | ||
.map_err(|layout| err_inval!(Layout(layout)).into()) | ||
} | ||
|
@@ -292,24 +296,36 @@ pub(super) fn from_known_layout<'tcx>( | |
|
||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ||
pub fn new( | ||
tcx: TyCtxtAt<'tcx>, | ||
tcx: TyCtxt<'tcx>, | ||
root_span: Span, | ||
param_env: ty::ParamEnv<'tcx>, | ||
machine: M, | ||
memory_extra: M::MemoryExtra, | ||
) -> Self { | ||
InterpCx { | ||
machine, | ||
tcx, | ||
root_span, | ||
param_env, | ||
memory: Memory::new(tcx, memory_extra), | ||
vtables: FxHashMap::default(), | ||
} | ||
} | ||
|
||
#[inline(always)] | ||
pub fn set_span(&mut self, span: Span) { | ||
self.tcx.span = span; | ||
self.memory.tcx.span = span; | ||
pub fn cur_span(&self) -> Span { | ||
self.stack() | ||
.last() | ||
.and_then(|f| f.current_source_info()) | ||
.map(|si| si.span) | ||
.unwrap_or(self.root_span) | ||
} | ||
|
||
#[inline(always)] | ||
pub fn tcx_at(&self) -> TyCtxtAt<'tcx> { | ||
// Computing the current span has a non-trivial cost, and for cycle errors | ||
// the "root span" is good enough. | ||
self.tcx.at(self.root_span) | ||
} | ||
|
||
#[inline(always)] | ||
|
@@ -387,12 +403,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
|
||
#[inline] | ||
pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool { | ||
ty.is_sized(self.tcx, self.param_env) | ||
ty.is_sized(self.tcx_at(), self.param_env) | ||
} | ||
|
||
#[inline] | ||
pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { | ||
ty.is_freeze(*self.tcx, self.param_env, DUMMY_SP) | ||
ty.is_freeze(self.tcx, self.param_env, self.root_span) | ||
} | ||
|
||
pub fn load_mir( | ||
|
@@ -403,20 +419,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
// do not continue if typeck errors occurred (can only occur in local crate) | ||
let did = instance.def_id(); | ||
if let Some(did) = did.as_local() { | ||
if self.tcx.has_typeck_tables(did) { | ||
if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors { | ||
if self.tcx_at().has_typeck_tables(did) { | ||
if let Some(error_reported) = self.tcx_at().typeck_tables_of(did).tainted_by_errors | ||
{ | ||
throw_inval!(TypeckError(error_reported)) | ||
} | ||
} | ||
} | ||
trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); | ||
if let Some(promoted) = promoted { | ||
return Ok(&self.tcx.promoted_mir(did)[promoted]); | ||
return Ok(&self.tcx_at().promoted_mir(did)[promoted]); | ||
} | ||
match instance { | ||
ty::InstanceDef::Item(def_id) => { | ||
if self.tcx.is_mir_available(did) { | ||
Ok(self.tcx.optimized_mir(did)) | ||
if self.tcx_at().is_mir_available(did) { | ||
Ok(self.tcx_at().optimized_mir(did)) | ||
} else { | ||
throw_unsup!(NoMirFor(def_id)) | ||
} | ||
|
@@ -457,7 +474,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
trace!("resolve: {:?}, {:#?}", def_id, substs); | ||
trace!("param_env: {:#?}", self.param_env); | ||
trace!("substs: {:#?}", substs); | ||
match ty::Instance::resolve(*self.tcx, self.param_env, def_id, substs) { | ||
match ty::Instance::resolve(self.tcx, self.param_env, def_id, substs) { | ||
Ok(Some(instance)) => Ok(instance), | ||
Ok(None) => throw_inval!(TooGeneric), | ||
|
||
|
@@ -476,7 +493,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
// have to support that case (mostly by skipping all caching). | ||
match frame.locals.get(local).and_then(|state| state.layout.get()) { | ||
None => { | ||
let layout = from_known_layout(self.tcx, layout, || { | ||
let layout = from_known_layout(self.tcx_at(), layout, || { | ||
let local_ty = frame.body.local_decls[local].ty; | ||
let local_ty = | ||
self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty); | ||
|
@@ -561,7 +578,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
let size = size.align_to(align); | ||
|
||
// Check if this brought us over the size limit. | ||
if size.bytes() >= self.tcx.data_layout().obj_size_bound() { | ||
if size.bytes() >= self.tcx.data_layout.obj_size_bound() { | ||
throw_ub!(InvalidMeta("total size is bigger than largest supported object")); | ||
} | ||
Ok(Some((size, align))) | ||
|
@@ -577,7 +594,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
let elem = layout.field(self, 0)?; | ||
|
||
// Make sure the slice is not too big. | ||
let size = elem.size.checked_mul(len, &*self.tcx).ok_or_else(|| { | ||
let size = elem.size.checked_mul(len, self).ok_or_else(|| { | ||
err_ub!(InvalidMeta("slice is bigger than largest supported object")) | ||
})?; | ||
Ok(Some((size, elem.align.abi))) | ||
|
@@ -628,7 +645,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
let mut locals = IndexVec::from_elem(dummy, &body.local_decls); | ||
|
||
// Now mark those locals as dead that we do not want to initialize | ||
match self.tcx.def_kind(instance.def_id()) { | ||
match self.tcx_at().def_kind(instance.def_id()) { | ||
// statics and constants don't have `Storage*` statements, no need to look for them | ||
// | ||
// FIXME: The above is likely untrue. See | ||
|
@@ -843,7 +860,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
} else { | ||
self.param_env | ||
}; | ||
let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.tcx.span))?; | ||
let val = self.tcx.const_eval_global_id(param_env, gid, Some(self.cur_span()))?; | ||
|
||
// Even though `ecx.const_eval` is called from `eval_const_to_op` we can never have a | ||
// recursion deeper than one level, because the `tcx.const_eval` above is guaranteed to not | ||
|
@@ -874,7 +891,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | |
// FIXME: We can hit delay_span_bug if this is an invalid const, interning finds | ||
// that problem, but we never run validation to show an error. Can we ensure | ||
// this does not happen? | ||
let val = self.tcx.const_eval_raw(param_env.and(gid))?; | ||
let val = self.tcx.at(self.cur_span()).const_eval_raw(param_env.and(gid))?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... or this. |
||
self.raw_const_to_mplace(val) | ||
} | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably either this call that is expensive...