Skip to content

Commit

Permalink
Lazily evaluate EvalErrorKind::*.into() calls.
Browse files Browse the repository at this point in the history
eval_context.rs calls `ok_or` in multiple places with an eagerly
evaluated `EvalErrorKind::*.into()` argument, which calls
EvalError::from(), which calls env::var("MIRI_BACKTRACE"), which
allocates a String. This code is hot enough for this to have a
measurable effect on some benchmarks.

This patch changes the `ok_or` calls into `ok_or_else`, thus avoiding
the evaluations when they're not needed. As a result, most of the
rustc-perf benchmarks get a measurable speedup, particularly the
shorter-running ones, where the improvement is as high as 6%.
  • Loading branch information
nnethercote committed Apr 18, 2018
1 parent 23561c6 commit 5070dea
Showing 1 changed file with 5 additions and 5 deletions.
10 changes: 5 additions & 5 deletions src/librustc_mir/interpret/eval_context.rs
Expand Up @@ -260,7 +260,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
self.param_env,
def_id,
substs,
).ok_or(EvalErrorKind::TypeckError.into()) // turn error prop into a panic to expose associated type in const issue
).ok_or_else(|| EvalErrorKind::TypeckError.into()) // turn error prop into a panic to expose associated type in const issue
}

pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
Expand All @@ -279,9 +279,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
trace!("load mir {:?}", instance);
match instance {
ty::InstanceDef::Item(def_id) => {
self.tcx.maybe_optimized_mir(def_id).ok_or_else(|| {
self.tcx.maybe_optimized_mir(def_id).ok_or_else(||
EvalErrorKind::NoMirFor(self.tcx.item_path_str(def_id)).into()
})
)
}
_ => Ok(self.tcx.instance_mir(instance)),
}
Expand Down Expand Up @@ -691,7 +691,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
self.param_env,
def_id,
substs,
).ok_or(EvalErrorKind::TypeckError.into());
).ok_or_else(|| EvalErrorKind::TypeckError.into());
let fn_ptr = self.memory.create_fn_alloc(instance?);
let valty = ValTy {
value: Value::ByVal(PrimVal::Ptr(fn_ptr)),
Expand Down Expand Up @@ -1699,7 +1699,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M

impl<'mir, 'tcx> Frame<'mir, 'tcx> {
pub fn get_local(&self, local: mir::Local) -> EvalResult<'tcx, Value> {
self.locals[local].ok_or(EvalErrorKind::DeadLocal.into())
self.locals[local].ok_or_else(|| EvalErrorKind::DeadLocal.into())
}

fn set_local(&mut self, local: mir::Local, value: Value) -> EvalResult<'tcx> {
Expand Down

0 comments on commit 5070dea

Please sign in to comment.