cranelift_filetests/
test_optimize.rs

1//! Test command for testing the optimization phases.
2//!
3//! The `optimize` test command runs each function through the
4//! optimization passes, but not lowering or regalloc. The output for
5//! filecheck purposes is the resulting CLIF.
6//!
7//! Some legalization may be ISA-specific, so this requires an ISA
8//! (for now).
9
10use crate::subtest::{check_precise_output, run_filecheck, Context, SubTest};
11use anyhow::Result;
12use cranelift_codegen::ir;
13use cranelift_control::ControlPlane;
14use cranelift_reader::{TestCommand, TestOption};
15use std::borrow::Cow;
16
17struct TestOptimize {
18    /// Flag indicating that the text expectation, comments after the function,
19    /// must be a precise 100% match on the compiled output of the function.
20    /// This test assertion is also automatically-update-able to allow tweaking
21    /// the code generator and easily updating all affected tests.
22    precise_output: bool,
23}
24
25pub fn subtest(parsed: &TestCommand) -> Result<Box<dyn SubTest>> {
26    assert_eq!(parsed.command, "optimize");
27    let mut test = TestOptimize {
28        precise_output: false,
29    };
30    for option in parsed.options.iter() {
31        match option {
32            TestOption::Flag("precise-output") => test.precise_output = true,
33            _ => anyhow::bail!("unknown option on {}", parsed),
34        }
35    }
36    Ok(Box::new(test))
37}
38
39impl SubTest for TestOptimize {
40    fn name(&self) -> &'static str {
41        "optimize"
42    }
43
44    fn is_mutating(&self) -> bool {
45        true
46    }
47
48    fn needs_isa(&self) -> bool {
49        true
50    }
51
52    fn run(&self, func: Cow<ir::Function>, context: &Context) -> Result<()> {
53        let isa = context.isa.expect("optimize needs an ISA");
54        let mut comp_ctx = cranelift_codegen::Context::for_function(func.into_owned());
55
56        comp_ctx
57            .optimize(isa, &mut ControlPlane::default())
58            .map_err(|e| crate::pretty_anyhow_error(&comp_ctx.func, e))?;
59
60        let clif = format!("{:?}", comp_ctx.func);
61
62        if self.precise_output {
63            let actual: Vec<_> = clif.lines().collect();
64            check_precise_output(&actual, context)
65        } else {
66            run_filecheck(&clif, context)
67        }
68    }
69}