Replace terminator-based const eval limit
- Remove logic that limits const eval based on terminators, and use the stable metric instead (back edges + fn calls) - Add unstable flag `tiny-const-eval-limit` to add UI tests that do not have to go up to the regular 2M step limit
This commit is contained in:
parent
8d99b0fc8d
commit
eea42733ac
17 changed files with 138 additions and 61 deletions
|
@ -561,8 +561,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
|||
throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
|
||||
}
|
||||
|
||||
fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
|
||||
// The step limit has already been hit in a previous call to `before_terminator`.
|
||||
fn increment_const_eval_counter(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
|
||||
// The step limit has already been hit in a previous call to `increment_const_eval_counter`.
|
||||
if ecx.machine.steps_remaining == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
|
|
@ -46,9 +46,6 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
|
|||
|
||||
/// The recursion limit (cached from `tcx.recursion_limit(())`)
|
||||
pub recursion_limit: Limit,
|
||||
|
||||
pub const_eval_limit: u32,
|
||||
pub const_eval_counter: u32,
|
||||
}
|
||||
|
||||
// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
|
||||
|
@ -411,8 +408,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
param_env,
|
||||
memory: Memory::new(),
|
||||
recursion_limit: tcx.recursion_limit(),
|
||||
const_eval_limit: 20,
|
||||
const_eval_counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -243,10 +243,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
ecx.stack_mut()[frame].locals[local].access_mut()
|
||||
}
|
||||
|
||||
/// Called before a basic block terminator is executed.
|
||||
/// You can use this to detect endlessly running programs.
|
||||
/// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction.
|
||||
/// You can use this to detect long or endlessly running programs.
|
||||
#[inline]
|
||||
fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
|
||||
fn increment_const_eval_counter(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -293,17 +293,6 @@ where
|
|||
Prov: Provenance + 'static,
|
||||
M: Machine<'mir, 'tcx, Provenance = Prov>,
|
||||
{
|
||||
pub fn increment_const_eval_counter(&mut self) {
|
||||
self.const_eval_counter = self.const_eval_counter + 1;
|
||||
if self.const_eval_counter == self.const_eval_limit {
|
||||
let mut warn = self.tcx.sess.struct_warn(format!(
|
||||
"Const eval counter limit ({}) has been crossed",
|
||||
self.const_eval_limit
|
||||
));
|
||||
warn.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/// Take a value, which represents a (thin or wide) reference, and make it a place.
|
||||
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
|
||||
///
|
||||
|
|
|
@ -62,8 +62,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
return Ok(true);
|
||||
}
|
||||
|
||||
M::before_terminator(self)?;
|
||||
|
||||
let terminator = basic_block.terminator();
|
||||
self.terminator(terminator)?;
|
||||
Ok(true)
|
||||
|
@ -130,7 +128,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
Coverage(..) => {}
|
||||
|
||||
ConstEvalCounter => {
|
||||
self.increment_const_eval_counter();
|
||||
M::increment_const_eval_counter(self)?;
|
||||
}
|
||||
|
||||
// Defined to do nothing. These are added by optimization passes, to avoid changing the
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue