Skip to content

Commit 360db51

Browse files
committed
Create stable metric to measure long computation in Const Eval
This patch adds a `MirPass` that tracks the number of back-edges and function calls in the CFG, adds a new MIR instruction to increment a counter every time they are encountered during Const Eval, and emit a warning if a configured limit is breached.
1 parent c8e6a9e commit 360db51

File tree

37 files changed

+233
-9
lines changed

37 files changed

+233
-9
lines changed

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
393393
| mir::StatementKind::AscribeUserType(..)
394394
| mir::StatementKind::Coverage(..)
395395
| mir::StatementKind::Intrinsic(..)
396+
| mir::StatementKind::ConstEvalCounter
396397
| mir::StatementKind::Nop => {}
397398
}
398399
}

compiler/rustc_borrowck/src/invalidation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
9191
LocalMutationIsAllowed::Yes,
9292
);
9393
}
94-
StatementKind::Nop
94+
StatementKind::ConstEvalCounter
95+
| StatementKind::Nop
9596
| StatementKind::Retag { .. }
9697
| StatementKind::Deinit(..)
9798
| StatementKind::SetDiscriminant { .. } => {

compiler/rustc_borrowck/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
620620
flow_state,
621621
);
622622
}
623-
StatementKind::Nop
623+
StatementKind::ConstEvalCounter
624+
| StatementKind::Nop
624625
| StatementKind::Retag { .. }
625626
| StatementKind::Deinit(..)
626627
| StatementKind::SetDiscriminant { .. } => {

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12581258
| StatementKind::StorageDead(..)
12591259
| StatementKind::Retag { .. }
12601260
| StatementKind::Coverage(..)
1261+
| StatementKind::ConstEvalCounter
12611262
| StatementKind::Nop => {}
12621263
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
12631264
bug!("Statement not allowed in this MIR phase")

compiler/rustc_codegen_ssa/src/mir/statement.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
9191
mir::StatementKind::FakeRead(..)
9292
| mir::StatementKind::Retag { .. }
9393
| mir::StatementKind::AscribeUserType(..)
94+
| mir::StatementKind::ConstEvalCounter
9495
| mir::StatementKind::Nop => {}
9596
}
9697
}

compiler/rustc_const_eval/src/const_eval/eval_queries.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ use crate::interpret::{
2222
RefTracking, StackPopCleanup,
2323
};
2424

25+
use tracing::info;
26+
2527
const NOTE_ON_UNDEFINED_BEHAVIOR_ERROR: &str = "The rules on what exactly is undefined behavior aren't clear, \
2628
so this check might be overzealous. Please open an issue on the rustc \
2729
repository if you believe it should not be considered undefined behavior.";
@@ -33,6 +35,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
3335
body: &'mir mir::Body<'tcx>,
3436
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
3537
debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env);
38+
info!("HERE body is {:#?}", body);
3639
let tcx = *ecx.tcx;
3740
assert!(
3841
cid.promoted.is_some()

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
369369
}
370370
}
371371

372+
#[instrument(skip(ecx), ret)]
372373
fn load_mir(
373374
ecx: &InterpCx<'mir, 'tcx, Self>,
374375
instance: ty::InstanceDef<'tcx>,

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
4646

4747
/// The recursion limit (cached from `tcx.recursion_limit(())`)
4848
pub recursion_limit: Limit,
49+
50+
pub const_eval_limit: u32,
51+
pub const_eval_counter: u32,
4952
}
5053

5154
// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
@@ -408,6 +411,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
408411
param_env,
409412
memory: Memory::new(),
410413
recursion_limit: tcx.recursion_limit(),
414+
const_eval_limit: 20,
415+
const_eval_counter: 0,
411416
}
412417
}
413418

compiler/rustc_const_eval/src/interpret/place.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,17 @@ where
293293
Prov: Provenance + 'static,
294294
M: Machine<'mir, 'tcx, Provenance = Prov>,
295295
{
296+
pub fn increment_const_eval_counter(&mut self) {
297+
self.const_eval_counter = self.const_eval_counter + 1;
298+
if self.const_eval_counter == self.const_eval_limit {
299+
let mut warn = self.tcx.sess.struct_warn(format!(
300+
"Const eval counter limit ({}) has been crossed",
301+
self.const_eval_limit
302+
));
303+
warn.emit();
304+
}
305+
}
306+
296307
/// Take a value, which represents a (thin or wide) reference, and make it a place.
297308
/// Alignment is just based on the type. This is the inverse of `MemPlace::to_ref()`.
298309
///

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
129129
// FIXME(#73156): Handle source code coverage in const eval
130130
Coverage(..) => {}
131131

132+
// FIXME(bryangarza): Update this to do some logic!!!
133+
ConstEvalCounter => {
134+
self.increment_const_eval_counter();
135+
}
136+
132137
// Defined to do nothing. These are added by optimization passes, to avoid changing the
133138
// size of MIR constantly.
134139
Nop => {}

0 commit comments

Comments
 (0)