119 lines
3.6 KiB
Rust
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)
|
|
}
|