Reorganise optimisation level settings, and make the insn shrink pass optional (#1044)
This patch: * removes the "default" opt level, on the basis that it has no definition and is referred to nowhere in the compiler. * renames the "fastest" level to "none". The resulting set of transformations is unchanged. * renames the "best" level to "speed_and_size". The resulting set of transformations is unchanged. * adds a new level, "speed". This is the same as "speed_and_size" except that it omits transformations aimed only at reducing code size. Currently it omits only the insn shrinking pass.
This commit is contained in:
@@ -8,11 +8,12 @@ pub fn define() -> SettingGroup {
|
|||||||
r#"
|
r#"
|
||||||
Optimization level:
|
Optimization level:
|
||||||
|
|
||||||
- default: Very profitable optimizations enabled, none slow.
|
- none: Minimise compile time by disabling most optimizations.
|
||||||
- best: Enable all optimizations
|
- speed: Generate the fastest possible code
|
||||||
- fastest: Optimize for compile time by disabling most optimizations.
|
- speed_and_size: like "speed", but also perform transformations
|
||||||
|
aimed at reducing code size.
|
||||||
"#,
|
"#,
|
||||||
vec!["default", "best", "fastest"],
|
vec!["none", "speed", "speed_and_size"],
|
||||||
);
|
);
|
||||||
|
|
||||||
settings.add_bool(
|
settings.add_bool(
|
||||||
|
|||||||
@@ -132,18 +132,18 @@ impl Context {
|
|||||||
self.verify_if(isa)?;
|
self.verify_if(isa)?;
|
||||||
debug!("Compiling:\n{}", self.func.display(isa));
|
debug!("Compiling:\n{}", self.func.display(isa));
|
||||||
|
|
||||||
|
let opt_level = isa.flags().opt_level();
|
||||||
|
|
||||||
self.compute_cfg();
|
self.compute_cfg();
|
||||||
if isa.flags().opt_level() != OptLevel::Fastest {
|
if opt_level != OptLevel::None {
|
||||||
self.preopt(isa)?;
|
self.preopt(isa)?;
|
||||||
}
|
}
|
||||||
if isa.flags().enable_nan_canonicalization() {
|
if isa.flags().enable_nan_canonicalization() {
|
||||||
self.canonicalize_nans(isa)?;
|
self.canonicalize_nans(isa)?;
|
||||||
}
|
}
|
||||||
self.legalize(isa)?;
|
self.legalize(isa)?;
|
||||||
if isa.flags().opt_level() != OptLevel::Fastest {
|
if opt_level != OptLevel::None {
|
||||||
self.postopt(isa)?;
|
self.postopt(isa)?;
|
||||||
}
|
|
||||||
if isa.flags().opt_level() == OptLevel::Best {
|
|
||||||
self.compute_domtree();
|
self.compute_domtree();
|
||||||
self.compute_loop_analysis();
|
self.compute_loop_analysis();
|
||||||
self.licm(isa)?;
|
self.licm(isa)?;
|
||||||
@@ -151,13 +151,15 @@ impl Context {
|
|||||||
}
|
}
|
||||||
self.compute_domtree();
|
self.compute_domtree();
|
||||||
self.eliminate_unreachable_code(isa)?;
|
self.eliminate_unreachable_code(isa)?;
|
||||||
if isa.flags().opt_level() != OptLevel::Fastest {
|
if opt_level != OptLevel::None {
|
||||||
self.dce(isa)?;
|
self.dce(isa)?;
|
||||||
}
|
}
|
||||||
self.regalloc(isa)?;
|
self.regalloc(isa)?;
|
||||||
self.prologue_epilogue(isa)?;
|
self.prologue_epilogue(isa)?;
|
||||||
if isa.flags().opt_level() == OptLevel::Best {
|
if opt_level == OptLevel::Speed || opt_level == OptLevel::SpeedAndSize {
|
||||||
self.redundant_reload_remover(isa)?;
|
self.redundant_reload_remover(isa)?;
|
||||||
|
}
|
||||||
|
if opt_level == OptLevel::SpeedAndSize {
|
||||||
self.shrink_instructions(isa)?;
|
self.shrink_instructions(isa)?;
|
||||||
}
|
}
|
||||||
let result = self.relax_branches(isa);
|
let result = self.relax_branches(isa);
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
//! use cranelift_codegen::settings::{self, Configurable};
|
//! use cranelift_codegen::settings::{self, Configurable};
|
||||||
//!
|
//!
|
||||||
//! let mut b = settings::builder();
|
//! let mut b = settings::builder();
|
||||||
//! b.set("opt_level", "fastest");
|
//! b.set("opt_level", "speed_and_size");
|
||||||
//!
|
//!
|
||||||
//! let f = settings::Flags::new(b);
|
//! let f = settings::Flags::new(b);
|
||||||
//! assert_eq!(f.opt_level(), settings::OptLevel::Fastest);
|
//! assert_eq!(f.opt_level(), settings::OptLevel::SpeedAndSize);
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::constant_hash::{probe, simple_hash};
|
use crate::constant_hash::{probe, simple_hash};
|
||||||
@@ -378,7 +378,7 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
f.to_string(),
|
f.to_string(),
|
||||||
"[shared]\n\
|
"[shared]\n\
|
||||||
opt_level = \"default\"\n\
|
opt_level = \"none\"\n\
|
||||||
libcall_call_conv = \"isa_default\"\n\
|
libcall_call_conv = \"isa_default\"\n\
|
||||||
baldrdash_prologue_words = 0\n\
|
baldrdash_prologue_words = 0\n\
|
||||||
probestack_size_log2 = 12\n\
|
probestack_size_log2 = 12\n\
|
||||||
@@ -398,7 +398,7 @@ mod tests {
|
|||||||
probestack_func_adjusts_sp = false\n\
|
probestack_func_adjusts_sp = false\n\
|
||||||
jump_tables_enabled = true\n"
|
jump_tables_enabled = true\n"
|
||||||
);
|
);
|
||||||
assert_eq!(f.opt_level(), super::OptLevel::Default);
|
assert_eq!(f.opt_level(), super::OptLevel::None);
|
||||||
assert_eq!(f.enable_simd(), false);
|
assert_eq!(f.enable_simd(), false);
|
||||||
assert_eq!(f.baldrdash_prologue_words(), 0);
|
assert_eq!(f.baldrdash_prologue_words(), 0);
|
||||||
}
|
}
|
||||||
@@ -428,13 +428,15 @@ mod tests {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
b.set("opt_level", "true"),
|
b.set("opt_level", "true"),
|
||||||
Err(BadValue("any among default, best, fastest".to_string()))
|
Err(BadValue(
|
||||||
|
"any among none, speed, speed_and_size".to_string()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
assert_eq!(b.set("opt_level", "best"), Ok(()));
|
assert_eq!(b.set("opt_level", "speed"), Ok(()));
|
||||||
assert_eq!(b.set("enable_simd", "0"), Ok(()));
|
assert_eq!(b.set("enable_simd", "0"), Ok(()));
|
||||||
|
|
||||||
let f = Flags::new(b);
|
let f = Flags::new(b);
|
||||||
assert_eq!(f.enable_simd(), false);
|
assert_eq!(f.enable_simd(), false);
|
||||||
assert_eq!(f.opt_level(), super::OptLevel::Best);
|
assert_eq!(f.opt_level(), super::OptLevel::Speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; binary emission of 32-bit code.
|
; binary emission of 32-bit code.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set allones_funcaddrs
|
set allones_funcaddrs
|
||||||
target i686 haswell
|
target i686 haswell
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; binary emission of 64-bit code.
|
; binary emission of 64-bit code.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set allones_funcaddrs
|
set allones_funcaddrs
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target x86_64 baseline
|
target x86_64 baseline
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; binary emission of x86-32 code.
|
; binary emission of x86-32 code.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target i686 haswell
|
target i686 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; Binary emission of 64-bit floating point code.
|
; Binary emission of 64-bit floating point code.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; binary emission of 64-bit code.
|
; binary emission of 64-bit code.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set is_pic
|
set is_pic
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; binary emission of x86-64 code.
|
; binary emission of x86-64 code.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
test compile
|
test compile
|
||||||
|
set opt_level=speed_and_size
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|
||||||
function u0:0(i8) -> i8 fast {
|
function u0:0(i8) -> i8 fast {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
test compile
|
test compile
|
||||||
|
set opt_level=speed_and_size
|
||||||
target x86_64
|
target x86_64
|
||||||
feature !"basic-blocks"
|
feature !"basic-blocks"
|
||||||
; regex: V=v\d+
|
; regex: V=v\d+
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; Test legalization of a non-colocated call in 64-bit non-PIC mode.
|
; Test legalization of a non-colocated call in 64-bit non-PIC mode.
|
||||||
test legalizer
|
test legalizer
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
function %call() {
|
function %call() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; Check that floating-point and integer constants equal to zero are optimized correctly.
|
; Check that floating-point and integer constants equal to zero are optimized correctly.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target i686
|
target i686
|
||||||
|
|
||||||
function %foo() -> f32 fast {
|
function %foo() -> f32 fast {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; Check that floating-point constants equal to zero are optimized correctly.
|
; Check that floating-point constants equal to zero are optimized correctly.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|
||||||
function %zero_const_32bit_no_rex() -> f32 fast {
|
function %zero_const_32bit_no_rex() -> f32 fast {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ test compile
|
|||||||
|
|
||||||
set enable_pinned_reg=true
|
set enable_pinned_reg=true
|
||||||
set use_pinned_reg_as_heap_base=true
|
set use_pinned_reg_as_heap_base=true
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
|
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test compile
|
test compile
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set is_pic
|
set is_pic
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set avoid_div_traps
|
set avoid_div_traps
|
||||||
set baldrdash_prologue_words=3
|
set baldrdash_prologue_words=3
|
||||||
set allones_funcaddrs
|
set allones_funcaddrs
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set enable_simd
|
set enable_simd
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test compile
|
test compile
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set probestack_enabled=false
|
set probestack_enabled=false
|
||||||
set enable_simd
|
set enable_simd
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test shrink
|
test shrink
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|
||||||
function %test_multiple_uses(i32 [%rdi]) -> i32 {
|
function %test_multiple_uses(i32 [%rdi]) -> i32 {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|
||||||
; Test that instruction shrinking eliminates REX prefixes when possible.
|
; Test that instruction shrinking eliminates REX prefixes when possible.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; binary emission of stack address instructions on x86-64.
|
; binary emission of stack address instructions on x86-64.
|
||||||
test binemit
|
test binemit
|
||||||
set opt_level=fastest
|
set opt_level=none
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
; The binary encodings can be verified with the command:
|
; The binary encodings can be verified with the command:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
; legalization of stack load and store instructions on x86-64.
|
; legalization of stack load and store instructions on x86-64.
|
||||||
test legalizer
|
test legalizer
|
||||||
set opt_level=fastest
|
set opt_level=none
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
function %stack_load_and_store() {
|
function %stack_load_and_store() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test binemit
|
test binemit
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set enable_simd
|
set enable_simd
|
||||||
target x86_64
|
target x86_64
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
test compile
|
test compile
|
||||||
set opt_level=best
|
set opt_level=speed_and_size
|
||||||
set is_pic
|
set is_pic
|
||||||
target x86_64 haswell
|
target x86_64 haswell
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ impl SubTest for TestBinEmit {
|
|||||||
recipe_constraints.satisfied(inst, &divert, &func)
|
recipe_constraints.satisfied(inst, &divert, &func)
|
||||||
});
|
});
|
||||||
|
|
||||||
if opt_level == OptLevel::Best {
|
if opt_level == OptLevel::SpeedAndSize {
|
||||||
// Get the smallest legal encoding
|
// Get the smallest legal encoding
|
||||||
legal_encodings
|
legal_encodings
|
||||||
.min_by_key(|&e| encinfo.byte_size(e, inst, &divert, &func))
|
.min_by_key(|&e| encinfo.byte_size(e, inst, &divert, &func))
|
||||||
|
|||||||
Reference in New Issue
Block a user