peepmatic: Make peepmatic optional to enable

Rather than outright replacing parts of our existing peephole optimizations
passes, this makes peepmatic an optional cargo feature that can be enabled. This
allows us to take a conservative approach with enabling peepmatic everywhere,
while also allowing us to get it in-tree and make it easier to collaborate on
improving it quickly.
This commit is contained in:
Nick Fitzgerald
2020-05-08 12:15:23 -07:00
parent 6e135b3aea
commit 52c6ece5f3
25 changed files with 2284 additions and 100 deletions

View File

@@ -45,6 +45,7 @@ mod test_domtree;
mod test_interpret;
mod test_legalizer;
mod test_licm;
mod test_peepmatic;
mod test_postopt;
mod test_preopt;
mod test_print_cfg;
@@ -128,6 +129,7 @@ fn new_subtest(parsed: &TestCommand) -> subtest::SubtestResult<Box<dyn subtest::
"interpret" => test_interpret::subtest(parsed),
"legalizer" => test_legalizer::subtest(parsed),
"licm" => test_licm::subtest(parsed),
"peepmatic" => test_peepmatic::subtest(parsed),
"postopt" => test_postopt::subtest(parsed),
"preopt" => test_preopt::subtest(parsed),
"print-cfg" => test_print_cfg::subtest(parsed),

View File

@@ -0,0 +1,56 @@
//! Test command for `peepmatic`-generated peephole optimizers.
use crate::subtest::{run_filecheck, Context, SubTest, SubtestResult};
use cranelift_codegen;
use cranelift_codegen::ir::Function;
use cranelift_codegen::print_errors::pretty_error;
use cranelift_reader::TestCommand;
use std::borrow::Cow;
struct TestPreopt;
pub fn subtest(parsed: &TestCommand) -> SubtestResult<Box<dyn SubTest>> {
assert_eq!(parsed.command, "peepmatic");
if parsed.options.is_empty() {
Ok(Box::new(TestPreopt))
} else {
Err(format!("No options allowed on {}", parsed))
}
}
impl SubTest for TestPreopt {
fn name(&self) -> &'static str {
"peepmatic"
}
fn is_mutating(&self) -> bool {
true
}
fn needs_isa(&self) -> bool {
true
}
fn run(&self, func: Cow<Function>, context: &Context) -> SubtestResult<()> {
let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned());
let isa = context.isa.expect("preopt needs an ISA");
comp_ctx.compute_cfg();
comp_ctx
.preopt(isa)
.map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?;
let text = &comp_ctx.func.display(isa).to_string();
log::debug!("After peepmatic-based simple_preopt:\n{}", text);
// Only actually run the filecheck if peepmatic is enabled, because it
// can generate slightly different code (alias a result vs replace an
// instruction) than the non-peepmatic versions of peephole
// optimizations. Note that the non-`peepmatic` results can be tested
// with the `test simple_preopt` subtest.
if cfg!(feature = "enable-peepmatic") {
run_filecheck(&text, context)
} else {
Ok(())
}
}
}

View File

@@ -39,6 +39,16 @@ impl SubTest for TestSimplePreopt {
.map_err(|e| pretty_error(&comp_ctx.func, context.isa, Into::into(e)))?;
let text = &comp_ctx.func.display(isa).to_string();
log::debug!("After simple_preopt:\n{}", text);
run_filecheck(&text, context)
// Only actually run the filecheck if peepmatic is *not* enabled,
// because it can generate slightly different code (alias a result vs
// replace an instruction) than the non-peepmatic versions of peephole
// optimizations. Note that the `peepmatic`-based results can be tested
// with the `test peepmatic` subtest.
if cfg!(feature = "enable-peepmatic") {
Ok(())
} else {
run_filecheck(&text, context)
}
}
}