Add a setting to choose a register allocator algorithm to use with MachBackend;

This commit is contained in:
Benjamin Bouvier
2020-04-17 15:25:49 +02:00
parent 3862c1f3a8
commit 65ef26b989
3 changed files with 60 additions and 23 deletions

View File

@@ -3,6 +3,36 @@ use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder};
pub(crate) fn define() -> SettingGroup { pub(crate) fn define() -> SettingGroup {
let mut settings = SettingGroupBuilder::new("shared"); let mut settings = SettingGroupBuilder::new("shared");
settings.add_enum(
"regalloc",
r#"Register allocator to use with the MachInst backend.
This selects the register allocator as an option among those offered by the `regalloc.rs`
crate. Please report register allocation bugs to the maintainers of this crate whenever
possible.
Note: this only applies to target that use the MachInst backend. As of 2020-04-17, this
means the x86_64 backend doesn't use this yet.
Possible values:
- `backtracking` is a greedy, backtracking register allocator as implemented in
Spidermonkey's optimizing tier IonMonkey. It may take more time to allocate registers, but
it should generate better code in general, resulting in better throughput of generated
code.
- `backtracking_checked` is the backtracking allocator with additional self checks that may
take some time to run, and thus these checks are disabled by default.
- `experimental_linear_scan` is an experimental linear scan allocator. It may take less
time to allocate registers, but generated code's quality may be inferior. As of
2020-04-17, it is still experimental and it should not be used in production settings.
"#,
vec![
"backtracking",
"backtracking_checked",
"experimental_linear_scan",
],
);
settings.add_enum( settings.add_enum(
"opt_level", "opt_level",
r#" r#"

View File

@@ -2,6 +2,7 @@
use crate::ir::Function; use crate::ir::Function;
use crate::machinst::*; use crate::machinst::*;
use crate::settings;
use crate::timing; use crate::timing;
use log::debug; use log::debug;
@@ -25,8 +26,12 @@ where
debug!("vcode from lowering: \n{}", vcode.show_rru(Some(universe))); debug!("vcode from lowering: \n{}", vcode.show_rru(Some(universe)));
// Perform register allocation. // Perform register allocation.
// TODO: select register allocation algorithm from flags. let algorithm = match vcode.flags().regalloc() {
let algorithm = RegAllocAlgorithm::Backtracking; settings::Regalloc::Backtracking => RegAllocAlgorithm::Backtracking,
settings::Regalloc::BacktrackingChecked => RegAllocAlgorithm::BacktrackingChecked,
settings::Regalloc::ExperimentalLinearScan => RegAllocAlgorithm::LinearScan,
};
let result = { let result = {
let _tt = timing::regalloc(); let _tt = timing::regalloc();
allocate_registers( allocate_registers(

View File

@@ -377,27 +377,29 @@ mod tests {
let f = Flags::new(b); let f = Flags::new(b);
assert_eq!( assert_eq!(
f.to_string(), f.to_string(),
"[shared]\n\ r#"[shared]
opt_level = \"none\"\n\ regalloc = "backtracking"
tls_model = \"none\"\n\ opt_level = "none"
libcall_call_conv = \"isa_default\"\n\ tls_model = "none"
baldrdash_prologue_words = 0\n\ libcall_call_conv = "isa_default"
probestack_size_log2 = 12\n\ baldrdash_prologue_words = 0
enable_verifier = true\n\ probestack_size_log2 = 12
is_pic = false\n\ enable_verifier = true
use_colocated_libcalls = false\n\ is_pic = false
avoid_div_traps = false\n\ use_colocated_libcalls = false
enable_float = true\n\ avoid_div_traps = false
enable_nan_canonicalization = false\n\ enable_float = true
enable_pinned_reg = false\n\ enable_nan_canonicalization = false
use_pinned_reg_as_heap_base = false\n\ enable_pinned_reg = false
enable_simd = false\n\ use_pinned_reg_as_heap_base = false
enable_atomics = true\n\ enable_simd = false
enable_safepoints = false\n\ enable_atomics = true
emit_all_ones_funcaddrs = false\n\ enable_safepoints = false
enable_probestack = true\n\ emit_all_ones_funcaddrs = false
probestack_func_adjusts_sp = false\n\ enable_probestack = true
enable_jump_tables = true\n" probestack_func_adjusts_sp = false
enable_jump_tables = true
"#
); );
assert_eq!(f.opt_level(), super::OptLevel::None); assert_eq!(f.opt_level(), super::OptLevel::None);
assert_eq!(f.enable_simd(), false); assert_eq!(f.enable_simd(), false);