diff --git a/benches/fibonacci.rs b/benches/fibonacci.rs new file mode 100644 index 0000000000..1f8a2aafc9 --- /dev/null +++ b/benches/fibonacci.rs @@ -0,0 +1,36 @@ +#![feature(custom_attribute, test)] +#![feature(rustc_private)] +#![allow(unused_attributes)] + +extern crate test; +use test::Bencher; + +mod fibonacci_helper; + +#[bench] +fn fib(bencher: &mut Bencher) { + bencher.iter(|| { + fibonacci_helper::main(); + }) +} + +mod miri_helper; + +#[bench] +fn fib_miri(bencher: &mut Bencher) { + miri_helper::run("fibonacci_helper", bencher); +} + +mod fibonacci_helper_iterative; + +#[bench] +fn fib_iter(bencher: &mut Bencher) { + bencher.iter(|| { + fibonacci_helper_iterative::main(); + }) +} + +#[bench] +fn fib_iter_miri(bencher: &mut Bencher) { + miri_helper::run("fibonacci_helper_iterative", bencher); +} diff --git a/benches/fibonacci_helper.rs b/benches/fibonacci_helper.rs new file mode 100644 index 0000000000..cddfff9c2c --- /dev/null +++ b/benches/fibonacci_helper.rs @@ -0,0 +1,16 @@ +#![feature(custom_attribute)] +#![allow(unused_attributes)] + +#[miri_run] +#[inline(never)] +pub fn main() { + assert_eq!(fib(10), 55); +} + +fn fib(n: usize) -> usize { + if n <= 2 { + 1 + } else { + fib(n - 1) + fib(n - 2) + } +} diff --git a/benches/fibonacci_helper_iterative.rs b/benches/fibonacci_helper_iterative.rs new file mode 100644 index 0000000000..486d8c2e8a --- /dev/null +++ b/benches/fibonacci_helper_iterative.rs @@ -0,0 +1,19 @@ +#![feature(custom_attribute)] +#![allow(unused_attributes)] + +#[miri_run] +#[inline(never)] +pub fn main() { + assert_eq!(fib(10), 55); +} + +fn fib(n: usize) -> usize { + let mut a = 0; + let mut b = 1; + for _ in 0..n { + let c = a; + a = b; + b = c + b; + } + a +} diff --git a/benches/miri_helper.rs b/benches/miri_helper.rs new file mode 100644 index 0000000000..54c15a27ed --- /dev/null +++ b/benches/miri_helper.rs @@ -0,0 +1,47 @@ +#![feature(custom_attribute, test)] +#![feature(rustc_private)] +#![allow(unused_attributes)] + +extern crate getopts; +extern crate miri; +extern crate rustc; +extern crate rustc_driver; +extern crate test; + +use self::miri::interpreter; +use self::rustc::session::Session; +use self::rustc_driver::{driver, CompilerCalls}; +use std::cell::RefCell; +use std::rc::Rc; +use std::env::var; +use test::Bencher; + +pub struct MiriCompilerCalls<'a>(Rc>); + +pub fn run(filename: &str, bencher: &mut Bencher) { + let path = var("RUST_SYSROOT").expect("env variable `RUST_SYSROOT` not set"); + rustc_driver::run_compiler(&[ + "miri".to_string(), format!("benches/{}.rs", filename), "--sysroot".to_string(), path.to_string(), + ], &mut MiriCompilerCalls(Rc::new(RefCell::new(bencher)))); +} + +impl<'a> CompilerCalls<'a> for MiriCompilerCalls<'a> { + fn build_controller( + &mut self, + _: &Session, + _: &getopts::Matches + ) -> driver::CompileController<'a> { + let mut control: driver::CompileController<'a> = driver::CompileController::basic(); + + let bencher = self.0.clone(); + + control.after_analysis.callback = Box::new(move |state| { + state.session.abort_if_errors(); + bencher.borrow_mut().iter(|| { + interpreter::interpret_start_points(state.tcx.unwrap(), state.mir_map.unwrap()); + }) + }); + + control + } +} diff --git a/benches/smoke.rs b/benches/smoke.rs new file mode 100644 index 0000000000..43baf486df --- /dev/null +++ b/benches/smoke.rs @@ -0,0 +1,41 @@ +#![feature(custom_attribute, test)] +#![feature(rustc_private)] +#![allow(unused_attributes)] + +extern crate test; +use test::Bencher; + +mod smoke_helper; + +#[bench] +fn noop(bencher: &mut Bencher) { + bencher.iter(|| { + smoke_helper::main(); + }) +} + +/* +// really slow +#[bench] +fn noop_miri_full(bencher: &mut Bencher) { + let path = std::env::var("RUST_SYSROOT").expect("env variable `RUST_SYSROOT` not set"); + bencher.iter(|| { + let mut process = std::process::Command::new("target/release/miri"); + process.arg("benches/smoke_helper.rs") + .arg("--sysroot").arg(&path); + let output = process.output().unwrap(); + if !output.status.success() { + println!("{}", String::from_utf8(output.stdout).unwrap()); + println!("{}", String::from_utf8(output.stderr).unwrap()); + panic!("failed to run miri"); + } + }) +} +*/ + +mod miri_helper; + +#[bench] +fn noop_miri_interpreter(bencher: &mut Bencher) { + miri_helper::run("smoke_helper", bencher); +} diff --git a/benches/smoke_helper.rs b/benches/smoke_helper.rs new file mode 100644 index 0000000000..e8691f244c --- /dev/null +++ b/benches/smoke_helper.rs @@ -0,0 +1,7 @@ +#![feature(custom_attribute)] +#![allow(unused_attributes)] + +#[miri_run] +#[inline(never)] +pub fn main() { +} diff --git a/src/interpreter.rs b/src/interpreter.rs index a7df8748ae..8e8565b50c 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -1365,7 +1365,7 @@ impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> { fn deref(&self) -> &mir::Mir<'tcx> { match *self { CachedMir::Ref(r) => r, - CachedMir::Owned(ref rc) => &rc, + CachedMir::Owned(ref rc) => rc, } } } @@ -1422,12 +1422,16 @@ pub fn interpret_start_points<'a, 'tcx>( if attr.check_name("miri_run") { let item = tcx.map.expect_item(id); - println!("Interpreting: {}", item.name); + if TRACE_EXECUTION { + println!("Interpreting: {}", item.name); + } let mut gecx = GlobalEvalContext::new(tcx, mir_map); let mut fecx = FnEvalContext::new(&mut gecx); match fecx.call_nested(mir) { - Ok(Some(return_ptr)) => fecx.memory.dump(return_ptr.alloc_id), + Ok(Some(return_ptr)) => if TRACE_EXECUTION { + fecx.memory.dump(return_ptr.alloc_id); + }, Ok(None) => println!("(diverging function returned)"), Err(_e) => { // TODO(solson): Detect whether the error was already reported or not. @@ -1435,7 +1439,9 @@ pub fn interpret_start_points<'a, 'tcx>( } } - println!(""); + if TRACE_EXECUTION { + println!(""); + } } } }