rust/tests/run-make/mir-opt-bisect-limit/rmake.rs
2026-02-17 21:26:39 +09:00

119 lines
3.6 KiB
Rust

use std::path::Path;
use run_make_support::{CompletedProcess, rfs, rustc};
struct Case {
name: &'static str,
flags: &'static [&'static str],
expect_inline_dump: bool,
expect_running: ExpectedCount,
expect_not_running: ExpectedCount,
}
enum ExpectedCount {
Exactly(usize),
AtLeastOne,
Zero,
}
fn main() {
let cases = [
Case {
name: "limit0",
flags: &["-Zmir-opt-bisect-limit=0"],
expect_inline_dump: false,
expect_running: ExpectedCount::Exactly(0),
expect_not_running: ExpectedCount::AtLeastOne,
},
Case {
name: "limit1",
flags: &["-Zmir-opt-bisect-limit=1"],
expect_inline_dump: false,
expect_running: ExpectedCount::Exactly(1),
expect_not_running: ExpectedCount::AtLeastOne,
},
Case {
name: "huge_limit",
flags: &["-Zmir-opt-bisect-limit=1000000000"],
expect_inline_dump: true,
expect_running: ExpectedCount::AtLeastOne,
expect_not_running: ExpectedCount::Zero,
},
Case {
name: "limit0_with_force_enable_inline",
flags: &["-Zmir-opt-bisect-limit=0", "-Zmir-enable-passes=+Inline"],
expect_inline_dump: false,
expect_running: ExpectedCount::Exactly(0),
expect_not_running: ExpectedCount::AtLeastOne,
},
];
for case in cases {
let (inline_dumped, running_count, not_running_count, output) =
compile_case(case.name, case.flags);
assert_eq!(
inline_dumped, case.expect_inline_dump,
"{}: unexpected Inline dump presence",
case.name
);
assert_expected_count(
running_count,
case.expect_running,
&format!("{}: running count", case.name),
);
assert_expected_count(
not_running_count,
case.expect_not_running,
&format!("{}: NOT running count", case.name),
);
}
}
fn compile_case(dump_dir: &str, extra_flags: &[&str]) -> (bool, usize, usize, CompletedProcess) {
if Path::new(dump_dir).exists() {
rfs::remove_dir_all(dump_dir);
}
rfs::create_dir_all(dump_dir);
let mut cmd = rustc();
cmd.input("main.rs")
.arg("--emit=mir")
.arg("-Zmir-opt-level=2")
.arg("-Copt-level=2")
.arg("-Zthreads=1")
.arg("-Zdump-mir=Inline")
.arg(format!("-Zdump-mir-dir={dump_dir}"));
for &flag in extra_flags {
cmd.arg(flag);
}
let output = cmd.run();
let (running_count, not_running_count) = bisect_line_counts(&output);
(has_inline_dump_file(dump_dir), running_count, not_running_count, output)
}
fn assert_expected_count(actual: usize, expected: ExpectedCount, context: &str) {
match expected {
ExpectedCount::Exactly(n) => assert_eq!(actual, n, "{context}"),
ExpectedCount::AtLeastOne => assert!(actual > 0, "{context}"),
ExpectedCount::Zero => assert_eq!(actual, 0, "{context}"),
}
}
fn has_inline_dump_file(dir: &str) -> bool {
rfs::read_dir(dir)
.flatten()
.any(|entry| entry.file_name().to_string_lossy().contains(".Inline."))
}
fn bisect_line_counts(output: &CompletedProcess) -> (usize, usize) {
let stderr = output.stderr_utf8();
let running_count =
stderr.lines().filter(|line| line.starts_with("BISECT: running pass (")).count();
let not_running_count =
stderr.lines().filter(|line| line.starts_with("BISECT: NOT running pass (")).count();
(running_count, not_running_count)
}