Skip to content

Commit f280a83

Browse files
committed
Add support for MIR opt unit tests
1 parent c842240 commit f280a83

File tree

5 files changed

+52
-5
lines changed

5 files changed

+52
-5
lines changed

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ fn test_debugging_options_tracking_hash() {
751751
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
752752
tracked!(merge_functions, Some(MergeFunctions::Disabled));
753753
tracked!(mir_emit_retag, true);
754+
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
754755
tracked!(mir_opt_level, Some(4));
755756
tracked!(move_size_limit, Some(4096));
756757
tracked!(mutable_noalias, Some(true));

compiler/rustc_mir_transform/src/pass_manager.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,17 +77,30 @@ pub fn run_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, passes: &[&dyn
7777
let mut cnt = 0;
7878

7979
let validate = tcx.sess.opts.debugging_opts.validate_mir;
80+
let overridden_passes = &tcx.sess.opts.debugging_opts.mir_enable_passes;
81+
trace!("Overridden: {:?}", overridden_passes);
8082

8183
if validate {
8284
validate_body(tcx, body, format!("start of phase transition from {:?}", start_phase));
8385
}
8486

8587
for pass in passes {
86-
if !pass.is_enabled(&tcx.sess) {
87-
continue;
88-
}
89-
9088
let name = pass.name();
89+
90+
if let Some((_, polarity)) = overridden_passes.iter().rev().find(|(s, _)| s == &*name) {
91+
trace!(
92+
"{} {} as requested by flag",
93+
if *polarity { "Running" } else { "Not running" },
94+
name
95+
);
96+
if !polarity {
97+
continue;
98+
}
99+
} else {
100+
if !pass.is_enabled(&tcx.sess) {
101+
continue;
102+
}
103+
}
91104
let dump_enabled = pass.is_mir_dump_enabled();
92105

93106
if dump_enabled {

compiler/rustc_session/src/options.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ mod desc {
369369
pub const parse_opt_langid: &str = "a language identifier";
370370
pub const parse_opt_pathbuf: &str = "a path";
371371
pub const parse_list: &str = "a space-separated list of strings";
372+
pub const parse_list_with_polarity: &str =
373+
"a comma-separated list of strings, with elements beginning with + or -";
372374
pub const parse_opt_comma_list: &str = "a comma-separated list of strings";
373375
pub const parse_number: &str = "a number";
374376
pub const parse_opt_number: &str = parse_number;
@@ -530,6 +532,22 @@ mod parse {
530532
}
531533
}
532534

535+
crate fn parse_list_with_polarity(slot: &mut Vec<(String, bool)>, v: Option<&str>) -> bool {
536+
match v {
537+
Some(s) => {
538+
for s in s.split(",") {
539+
match s.chars().next() {
540+
Some('+') => slot.push((s[1..].to_string(), true)),
541+
Some('-') => slot.push((s[1..].to_string(), false)),
542+
_ => return false,
543+
}
544+
}
545+
true
546+
}
547+
None => false,
548+
}
549+
}
550+
533551
crate fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool {
534552
if let Some(v) = v {
535553
ld.line = false;
@@ -1319,6 +1337,10 @@ options! {
13191337
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
13201338
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
13211339
(default: no)"),
1340+
mir_enable_passes: Vec<(String, bool)> = (Vec::new(), parse_list_with_polarity, [TRACKED],
1341+
"use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be \
1342+
enabled, overriding all other checks. Passes that are not specified are enabled or \
1343+
disabled by other flags as usual."),
13221344
mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
13231345
"MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
13241346
move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],

src/tools/compiletest/src/header.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ pub struct TestProps {
157157
pub should_ice: bool,
158158
// If true, the stderr is expected to be different across bit-widths.
159159
pub stderr_per_bitwidth: bool,
160+
// The MIR opt to unit test, if any
161+
pub mir_unit_test: Option<String>,
160162
}
161163

162164
mod directives {
@@ -189,6 +191,7 @@ mod directives {
189191
pub const STDERR_PER_BITWIDTH: &'static str = "stderr-per-bitwidth";
190192
pub const INCREMENTAL: &'static str = "incremental";
191193
pub const KNOWN_BUG: &'static str = "known-bug";
194+
pub const MIR_UNIT_TEST: &'static str = "unit-test";
192195
// This isn't a real directive, just one that is probably mistyped often
193196
pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
194197
}
@@ -232,6 +235,7 @@ impl TestProps {
232235
assembly_output: None,
233236
should_ice: false,
234237
stderr_per_bitwidth: false,
238+
mir_unit_test: None,
235239
}
236240
}
237241

@@ -392,6 +396,9 @@ impl TestProps {
392396
config.set_name_directive(ln, STDERR_PER_BITWIDTH, &mut self.stderr_per_bitwidth);
393397
config.set_name_directive(ln, INCREMENTAL, &mut self.incremental);
394398
config.set_name_directive(ln, KNOWN_BUG, &mut self.known_bug);
399+
config.set_name_value_directive(ln, MIR_UNIT_TEST, &mut self.mir_unit_test, |s| {
400+
s.trim().to_string()
401+
});
395402
});
396403
}
397404

src/tools/compiletest/src/runtest.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1856,10 +1856,14 @@ impl<'test> TestCx<'test> {
18561856
rustc.args(&[
18571857
"-Copt-level=1",
18581858
"-Zdump-mir=all",
1859-
"-Zmir-opt-level=4",
18601859
"-Zvalidate-mir",
18611860
"-Zdump-mir-exclude-pass-number",
18621861
]);
1862+
if let Some(pass) = &self.props.mir_unit_test {
1863+
rustc.args(&["-Zmir-opt-level=0", &format!("-Zmir-enable-passes=+{}", pass)]);
1864+
} else {
1865+
rustc.arg("-Zmir-opt-level=4");
1866+
}
18631867

18641868
let mir_dump_dir = self.get_mir_dump_dir();
18651869
let _ = fs::remove_dir_all(&mir_dump_dir);

0 commit comments

Comments
 (0)