From d4fcd32cdc54bae93c53b6646739eb9d650251b8 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 24 Feb 2020 15:18:09 -0600 Subject: [PATCH] Optimize generated code via the CLI by default (#973) * Optimize generated code via the CLI by default This commit updates the behavior of the CLI and adds a new flag. It first enables the `--optimize` flag by default, ensuring that usage of the `wasmtime` CLI will enable cranelift optimizations by default. Next it also adds a `--opt-level` flag which is similar to Rust's `-Copt-level` where it takes a string argument of how to optimize. This is updates to support 0/1/2/s, where 1 is currently the same as 2 but added for consistency with other compilers. The default setting is `--opt-level=2`. When the `-O` flag is not passed the `--opt-level` flag is used, otherwise `-O` takes precedent in the sense that it implies `--opt-level=2` which is the highest optimization level. The thinking is that these flags will in general select the highest optimization level specified as the final optimization level. * Add inline docs * fix a test --- src/commands/wasm2obj.rs | 2 +- src/lib.rs | 35 +++++++++++++++++++++++++++++++---- src/obj.rs | 13 ++++++++++--- tests/debug/obj.rs | 2 +- 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/commands/wasm2obj.rs b/src/commands/wasm2obj.rs index 4d144d3d7d..494857b2a2 100644 --- a/src/commands/wasm2obj.rs +++ b/src/commands/wasm2obj.rs @@ -75,7 +75,7 @@ impl WasmToObjCommand { self.target.as_ref(), strategy, self.common.enable_simd, - self.common.optimize, + self.common.opt_level(), self.common.debug_info, self.output.clone(), &cache_config, diff --git a/src/lib.rs b/src/lib.rs index 1e64ecb98f..dc9b1bfca2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -132,9 +132,18 @@ struct CommonOptions { #[structopt(long)] jitdump: bool, - /// Run optimization passes on translated functions + /// Run optimization passes on translated functions, on by default #[structopt(short = "O", long)] optimize: bool, + + /// Optimization level for generated functions (0 (none), 1, 2 (most), or s + /// (size)) + #[structopt( + long, + parse(try_from_str = parse_opt_level), + default_value = "2", + )] + opt_level: wasmtime::OptLevel, } impl CommonOptions { @@ -148,11 +157,9 @@ impl CommonOptions { .wasm_reference_types(self.enable_reference_types || self.enable_all) .wasm_multi_value(self.enable_multi_value || self.enable_all) .wasm_threads(self.enable_threads || self.enable_all) + .cranelift_opt_level(self.opt_level()) .strategy(pick_compilation_strategy(self.cranelift, self.lightbeam)?)? .profiler(pick_profiling_strategy(self.jitdump)?)?; - if self.optimize { - config.cranelift_opt_level(wasmtime::OptLevel::Speed); - } if !self.disable_cache { match &self.config { Some(path) => { @@ -165,4 +172,24 @@ impl CommonOptions { } Ok(config) } + + fn opt_level(&self) -> wasmtime::OptLevel { + match (self.optimize, self.opt_level.clone()) { + (true, _) => wasmtime::OptLevel::Speed, + (false, other) => other, + } + } +} + +fn parse_opt_level(opt_level: &str) -> Result { + match opt_level { + "s" => Ok(wasmtime::OptLevel::SpeedAndSize), + "0" => Ok(wasmtime::OptLevel::None), + "1" => Ok(wasmtime::OptLevel::Speed), + "2" => Ok(wasmtime::OptLevel::Speed), + other => bail!( + "unknown optimization level `{}`, only 0,1,2,s accepted", + other + ), + } } diff --git a/src/obj.rs b/src/obj.rs index 20c466cfe8..87c8951b24 100644 --- a/src/obj.rs +++ b/src/obj.rs @@ -19,7 +19,7 @@ pub fn compile_to_obj( target: Option<&Triple>, strategy: Strategy, enable_simd: bool, - optimize: bool, + opt_level: wasmtime::OptLevel, debug_info: bool, artifact_name: String, cache_config: &CacheConfig, @@ -38,8 +38,15 @@ pub fn compile_to_obj( flag_builder.enable("enable_simd").unwrap(); } - if optimize { - flag_builder.set("opt_level", "speed").unwrap(); + match opt_level { + wasmtime::OptLevel::None => {} + wasmtime::OptLevel::Speed => { + flag_builder.set("opt_level", "speed").unwrap(); + } + wasmtime::OptLevel::SpeedAndSize => { + flag_builder.set("opt_level", "speed_and_size").unwrap(); + } + other => bail!("unknown optimization level {:?}", other), } let isa = isa_builder.finish(settings::Flags::new(flag_builder)); diff --git a/tests/debug/obj.rs b/tests/debug/obj.rs index f49cdf0def..a800373514 100644 --- a/tests/debug/obj.rs +++ b/tests/debug/obj.rs @@ -16,7 +16,7 @@ pub fn compile_cranelift( target.as_ref(), Strategy::Cranelift, false, - false, + wasmtime::OptLevel::None, true, output .as_ref()