Enable egraph-based optimization by default. (#5587)

This PR follows up on #5382 and #5391, which rebuilt the egraph-based optimization framework to be more performant, by enabling it by default.

Based on performance results in #5382 (my measurements on SpiderMonkey and bjorn3's independent confirmation with cg_clif), it seems that this is reasonable to enable. Now that we have been fuzzing compiler configurations with egraph opts (#5388) for 6 weeks, having fixed a few fuzzbugs that came up (#5409, #5420, #5438) and subsequently received no further reports from OSS-Fuzz, I believe it is stable enough to rely on.

This PR enables `use_egraphs`, and also normalizes its meaning: previously it forced optimization (it basically meant "turn on the egraph optimization machinery"), now it runs egraph opts if the opt level indicates (it means "use egraphs to optimize if we are going to optimize"). The conditionals in the top-level pass driver are a little subtle, but will get simpler once we can remove the non-egraph path (which we plan to do eventually!).

Fixes #5181.
This commit is contained in:
Chris Fallin
2023-01-19 15:46:53 -08:00
committed by GitHub
parent 704f5a5772
commit 1faff8c2ce
20 changed files with 43 additions and 33 deletions

View File

@@ -58,10 +58,12 @@ pub(crate) fn define() -> SettingGroup {
"Enable egraph-based optimization.",
r#"
This enables an optimization phase that converts CLIF to an egraph (equivalence graph)
representation, performs various rewrites, and then converts it back. This can result in
better optimization, but is currently considered experimental.
representation, performs various rewrites, and then converts it back. This should result in
better optimization, but the traditional optimization pass structure is also still
available by setting this to `false`. The `false` setting will eventually be
deprecated and removed.
"#,
false,
true,
);
settings.add_bool(

View File

@@ -185,20 +185,22 @@ impl Context {
self.compute_domtree();
self.eliminate_unreachable_code(isa)?;
if isa.flags().use_egraphs() || opt_level != OptLevel::None {
if opt_level != OptLevel::None {
self.dce(isa)?;
}
self.remove_constant_phis(isa)?;
if opt_level != OptLevel::None {
if isa.flags().use_egraphs() {
self.egraph_pass()?;
} else if opt_level != OptLevel::None && isa.flags().enable_alias_analysis() {
} else if isa.flags().enable_alias_analysis() {
for _ in 0..2 {
self.replace_redundant_loads()?;
self.simple_gvn(isa)?;
}
}
}
Ok(())
}

View File

@@ -16,7 +16,7 @@ pub use crate::machinst::{
ABIArg, ABIArgSlot, InputSourceInst, Lower, LowerBackend, RealReg, Reg, RelocDistance, Sig,
VCodeInst, Writable,
};
pub use crate::settings::TlsModel;
pub use crate::settings::{OptLevel, TlsModel};
pub type Unit = ();
pub type ValueSlice = (ValueList, usize);
@@ -131,7 +131,9 @@ macro_rules! isle_lower_prelude_methods {
// use. This lowers register pressure. (Only do this if we are
// not using egraph-based compilation; the egraph framework
// more efficiently rematerializes constants where needed.)
if !self.backend.flags().use_egraphs() {
if !(self.backend.flags().use_egraphs()
&& self.backend.flags().opt_level() != OptLevel::None)
{
let inputs = self.lower_ctx.get_value_as_source_or_const(val);
if inputs.constant.is_some() {
let insn = match inputs.inst {

View File

@@ -528,7 +528,7 @@ probestack_strategy = "outline"
regalloc_checker = false
regalloc_verbose_logs = false
enable_alias_analysis = true
use_egraphs = false
use_egraphs = true
enable_verifier = true
is_pic = false
use_colocated_libcalls = false

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=none
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=none
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=none
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=none
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=speed_and_size
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,6 +1,6 @@
test interpret
test run
set opt_level=speed_and_size
set opt_level=speed
set use_egraphs=true
set enable_llvm_abi_extensions=true
target x86_64

View File

@@ -1,6 +1,6 @@
test interpret
test run
set opt_level=speed_and_size
set opt_level=speed
set use_egraphs=true
target aarch64

View File

@@ -1,4 +1,5 @@
test compile
set opt_level=speed
set use_egraphs=true
target x86_64
target aarch64

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=none
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=none
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,4 +1,5 @@
test compile precise-output
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,4 +1,5 @@
test compile precise-output
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -1,5 +1,5 @@
test optimize
set opt_level=none
set opt_level=speed
set use_egraphs=true
target x86_64

View File

@@ -4,7 +4,8 @@
;;!
;;! settings = [
;;! "enable_heap_access_spectre_mitigation=true",
;;! "opt_level=speed_and_size"
;;! "opt_level=speed_and_size",
;;! "use_egraphs=false"
;;! ]
;;!
;;! [globals.vmctx]

View File

@@ -4,7 +4,8 @@
;;!
;;! settings = [
;;! "enable_heap_access_spectre_mitigation=true",
;;! "opt_level=speed_and_size"
;;! "opt_level=speed_and_size",
;;! "use_egraphs=false"
;;! ]
;;!
;;! [globals.vmctx]

View File

@@ -832,14 +832,13 @@ impl Config {
/// Configures the Cranelift code generator to use its
/// "egraph"-based mid-end optimizer.
///
/// This optimizer is intended to replace the compiler's more
/// traditional pipeline of optimization passes with a unified
/// code-rewriting system. It is not yet on by default, but it is
/// intended to become the default in a future version. It may
/// result in faster code, at the cost of slightly more
/// compilation-time work.
/// This optimizer has replaced the compiler's more traditional
/// pipeline of optimization passes with a unified code-rewriting
/// system. It is on by default, but the traditional optimization
/// pass structure is still available for now (it is deprecrated and
/// will be removed in a future version).
///
/// The default value for this is `false`.
/// The default value for this is `true`.
#[cfg(compiler)]
#[cfg_attr(nightlydoc, doc(cfg(feature = "cranelift")))] // see build.rs
pub fn cranelift_use_egraphs(&mut self, enable: bool) -> &mut Self {