diff --git a/cranelift/src/clif-util.rs b/cranelift/src/clif-util.rs index 5dc8347302..2948c544f9 100644 --- a/cranelift/src/clif-util.rs +++ b/cranelift/src/clif-util.rs @@ -29,6 +29,9 @@ mod print_cfg; mod run; mod utils; +#[cfg(feature = "peepmatic-souper")] +mod souper_to_peepmatic; + #[cfg(feature = "wasm")] mod wasm; @@ -50,6 +53,15 @@ fn add_single_input_file_arg<'a>() -> clap::Arg<'a, 'a> { .help("Specify a file to be used. Use '-' for stdin.") } +fn add_output_arg<'a>() -> clap::Arg<'a, 'a> { + Arg::with_name("output") + .required(true) + .default_value("-") + .value_name("output") + .short("o") + .help("Specify output file to be used. Use '-' for stdout.") +} + fn add_pass_arg<'a>() -> clap::Arg<'a, 'a> { Arg::with_name("pass") .required(true) @@ -247,6 +259,12 @@ fn main() { .arg(add_set_flag()) .arg(add_target_flag()) .arg(add_verbose_flag()), + ) + .subcommand( + SubCommand::with_name("souper-to-peepmatic") + .about("Convert Souper optimizations into Peepmatic DSL.") + .arg(add_single_input_file_arg()) + .arg(add_output_arg()), ); let res_util = match app_cmds.get_matches().subcommand() { @@ -362,6 +380,24 @@ fn main() { rest_cmd.is_present("verbose"), ) } + ("souper-to-peepmatic", Some(rest_cmd)) => { + #[cfg(feature = "peepmatic-souper")] + { + use std::path::Path; + souper_to_peepmatic::run( + Path::new(rest_cmd.value_of("single-file").unwrap()), + Path::new(rest_cmd.value_of("output").unwrap()), + ) + } + #[cfg(not(feature = "peepmatic-souper"))] + { + Err( + "Error: clif-util was compiled without suport for the `souper-to-peepmatic` \ + subcommand" + .into(), + ) + } + } _ => Err("Invalid subcommand.".to_owned()), }; diff --git a/cranelift/src/souper_to_peepmatic.rs b/cranelift/src/souper_to_peepmatic.rs new file mode 100644 index 0000000000..755b34c8d5 --- /dev/null +++ b/cranelift/src/souper_to_peepmatic.rs @@ -0,0 +1,32 @@ +use std::io::{Read, Write}; +use std::path::Path; + +pub fn run(input: &Path, output: &Path) -> Result<(), String> { + let peepmatic_dsl = if input == Path::new("-") { + let stdin = std::io::stdin(); + let mut stdin = stdin.lock(); + let mut souper_dsl = vec![]; + stdin + .read_to_end(&mut souper_dsl) + .map_err(|e| format!("failed to read from stdin: {}", e))?; + let souper_dsl = + String::from_utf8(souper_dsl).map_err(|e| format!("stdin is not UTF-8: {}", e))?; + peepmatic_souper::convert_str(&souper_dsl, Some(Path::new("stdin"))) + .map_err(|e| e.to_string())? + } else { + peepmatic_souper::convert_file(input).map_err(|e| e.to_string())? + }; + + if output == Path::new("-") { + let stdout = std::io::stdout(); + let mut stdout = stdout.lock(); + stdout + .write_all(peepmatic_dsl.as_bytes()) + .map_err(|e| format!("error writing to stdout: {}", e))?; + } else { + std::fs::write(output, peepmatic_dsl.as_bytes()) + .map_err(|e| format!("error writing to {}: {}", output.display(), e))?; + } + + Ok(()) +}