Make timing toggle-able

This commit is contained in:
greg 2018-10-01 02:05:07 -07:00
parent c24223f28e
commit 76046b134a
2 changed files with 41 additions and 17 deletions

View File

@ -9,6 +9,7 @@ pub struct LLVMCodeString(pub String);
pub struct EvalOptions { pub struct EvalOptions {
pub execution_method: ExecutionMethod, pub execution_method: ExecutionMethod,
pub debug_passes: HashMap<String, PassDebugOptionsDescriptor>, pub debug_passes: HashMap<String, PassDebugOptionsDescriptor>,
pub debug_timing: bool,
} }
#[derive(Debug, Hash, PartialEq)] #[derive(Debug, Hash, PartialEq)]
@ -55,7 +56,7 @@ impl UnfinishedComputation {
FinishedComputation { FinishedComputation {
artifacts: self.artifacts, artifacts: self.artifacts,
text_output, text_output,
durations: self.durations durations: self.durations,
} }
} }
pub fn output(self, output: Result<String, String>) -> FinishedComputation { pub fn output(self, output: Result<String, String>) -> FinishedComputation {
@ -68,6 +69,22 @@ impl UnfinishedComputation {
} }
impl FinishedComputation { impl FinishedComputation {
fn get_timing(&self) -> Option<String> {
if self.durations.len() != 0 {
let mut buf = String::new();
write!(&mut buf, "Timing: ").unwrap();
for duration in self.durations.iter() {
let timing = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 * 1e-9);
write!(&mut buf, "{}s, ", timing).unwrap()
}
write!(&mut buf, "\n").unwrap();
Some(buf)
} else {
None
}
}
pub fn to_repl(&self) -> String { pub fn to_repl(&self) -> String {
let mut buf = String::new(); let mut buf = String::new();
for (stage, artifact) in self.artifacts.iter() { for (stage, artifact) in self.artifacts.iter() {
@ -77,15 +94,11 @@ impl FinishedComputation {
write!(&mut buf, "{}: {}\n", stage, output).unwrap(); write!(&mut buf, "{}: {}\n", stage, output).unwrap();
} }
let debug_timing = true; match self.get_timing() {
if debug_timing { Some(timing) => write!(&mut buf, "{}", timing).unwrap(),
write!(&mut buf, "Timing: ").unwrap(); None => ()
for duration in self.durations.iter() {
let timing = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 * 1e-9);
write!(&mut buf, "{}s, ", timing).unwrap()
}
write!(&mut buf, "\n").unwrap();
} }
match self.text_output { match self.text_output {
Ok(ref output) => write!(&mut buf, "{}", output).unwrap(), Ok(ref output) => write!(&mut buf, "{}", output).unwrap(),
Err(ref err) => write!(&mut buf, "{} {}", "Error: ".red().bold(), err).unwrap(), Err(ref err) => write!(&mut buf, "{} {}", "Error: ".red().bold(), err).unwrap(),
@ -169,23 +182,23 @@ pub trait ProgrammingLanguageInterface {
#[macro_export] #[macro_export]
macro_rules! pass_chain { macro_rules! pass_chain {
($state:expr, $options:expr; $($pass:path), *) => { ($state:expr, $eval_options:expr; $($pass:path), *) => {
|text_input| { |text_input| {
let mut comp = UnfinishedComputation::default(); let mut comp = UnfinishedComputation::default();
pass_chain_helper! { ($state, comp, $options); text_input $(, $pass)* } pass_chain_helper! { ($state, comp, $eval_options); text_input $(, $pass)* }
} }
}; };
} }
#[macro_export] #[macro_export]
macro_rules! pass_chain_helper { macro_rules! pass_chain_helper {
(($state:expr, $comp:expr, $options:expr); $input:expr, $pass:path $(, $rest:path)*) => { (($state:expr, $comp:expr, $eval_options:expr); $input:expr, $pass:path $(, $rest:path)*) => {
{ {
use std::time; use std::time;
use schala_repl::PassDebugOptionsDescriptor; use schala_repl::PassDebugOptionsDescriptor;
let pass_name = stringify!($pass); let pass_name = stringify!($pass);
let (output, duration) = { let (output, duration) = {
let ref debug_map = $options.debug_passes; let ref debug_map = $eval_options.debug_passes;
let debug_handle = match debug_map.get(pass_name) { let debug_handle = match debug_map.get(pass_name) {
Some(PassDebugOptionsDescriptor { opts }) => { Some(PassDebugOptionsDescriptor { opts }) => {
let ptr = &mut $comp; let ptr = &mut $comp;
@ -199,9 +212,11 @@ macro_rules! pass_chain_helper {
let elapsed = start.elapsed(); let elapsed = start.elapsed();
(pass_output, elapsed) (pass_output, elapsed)
}; };
if $eval_options.debug_timing {
$comp.durations.push(duration); $comp.durations.push(duration);
}
match output { match output {
Ok(result) => pass_chain_helper! { ($state, $comp, $options); result $(, $rest)* }, Ok(result) => pass_chain_helper! { ($state, $comp, $eval_options); result $(, $rest)* },
Err(err) => { Err(err) => {
$comp.output(Err(format!("Pass {} failed with {:?}", pass_name, err))) $comp.output(Err(format!("Pass {} failed with {:?}", pass_name, err)))
} }
@ -209,7 +224,7 @@ macro_rules! pass_chain_helper {
} }
}; };
// Done // Done
(($state:expr, $comp:expr, $options:expr); $final_output:expr) => { (($state:expr, $comp:expr, $eval_options:expr); $final_output:expr) => {
{ {
let final_output: FinishedComputation = $comp.finish(Ok($final_output)); let final_output: FinishedComputation = $comp.finish(Ok($final_output));
final_output final_output

View File

@ -134,7 +134,11 @@ impl Repl {
CommandTree::term("passes", None), CommandTree::term("passes", None),
CommandTree::NonTerminal(format!("show"), passes_directives.clone(), None), CommandTree::NonTerminal(format!("show"), passes_directives.clone(), None),
CommandTree::NonTerminal(format!("hide"), passes_directives.clone(), None), CommandTree::NonTerminal(format!("hide"), passes_directives.clone(), None),
], Some(format!("show or hide pass info for a given pass, or display the names of all passes"))), CommandTree::NonTerminal(format!("timing"), vec![
CommandTree::term("on", None),
CommandTree::term("off", None),
], None),
], Some(format!("show or hide pass debug info for a given pass, or display the names of all passes, or turn timing on/off"))),
CommandTree::NonTerminal(format!("lang"), vec![ CommandTree::NonTerminal(format!("lang"), vec![
CommandTree::term("next", None), CommandTree::term("next", None),
CommandTree::term("prev", None), CommandTree::term("prev", None),
@ -228,6 +232,11 @@ impl Repl {
fn handle_debug(&mut self, commands: Vec<&str>) -> Option<String> { fn handle_debug(&mut self, commands: Vec<&str>) -> Option<String> {
let passes = self.get_cur_language().get_passes(); let passes = self.get_cur_language().get_passes();
match commands.get(1) { match commands.get(1) {
Some(&"timing") => match commands.get(2) {
Some(&"on") => { self.options.debug_timing = true; None }
Some(&"off") => { self.options.debug_timing = false; None }
_ => return Some(format!(r#"Argument to "timing" must be "on" or "off""#)),
},
Some(&"passes") => Some( Some(&"passes") => Some(
passes.into_iter() passes.into_iter()
.map(|desc| { .map(|desc| {