Skip to content

Commit d46ed83

Browse files
authored
Auto merge of #34715 - scottcarr:mir-test, r=nikomatsakis
Add MIR Optimization Tests I've starting working on the infrastructure for testing MIR optimizations. The plan now is to have a set of test cases (written in Rust), compile them with -Z dump-mir, and check the MIR before and after each pass.
2 parents 62690b3 + 8f9844d commit d46ed83

File tree

11 files changed

+242
-5
lines changed

11 files changed

+242
-5
lines changed

mk/tests.mk

+12-2
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,8 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
277277
check-stage$(1)-T-$(2)-H-$(3)-ui-exec \
278278
check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
279279
check-stage$(1)-T-$(2)-H-$(3)-doc-error-index-exec \
280-
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec
280+
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec \
281+
check-stage$(1)-T-$(2)-H-$(3)-mir-opt-exec
281282

282283
ifndef CFG_DISABLE_CODEGEN_TESTS
283284
check-stage$(1)-T-$(2)-H-$(3)-exec: \
@@ -458,6 +459,7 @@ UI_RS := $(call rwildcard,$(S)src/test/ui/,*.rs) \
458459
$(call rwildcard,$(S)src/test/ui/,*.stdout) \
459460
$(call rwildcard,$(S)src/test/ui/,*.stderr)
460461
RUSTDOCCK_RS := $(call rwildcard,$(S)src/test/rustdoc/,*.rs)
462+
MIR_OPT_RS := $(call rwildcard,$(S)src/test/mir-opt/,*.rs)
461463

462464
RPASS_TESTS := $(RPASS_RS)
463465
RPASS_VALGRIND_TESTS := $(RPASS_VALGRIND_RS)
@@ -475,6 +477,7 @@ CODEGEN_UNITS_TESTS := $(CODEGEN_UNITS_RS)
475477
INCREMENTAL_TESTS := $(INCREMENTAL_RS)
476478
RMAKE_TESTS := $(RMAKE_RS)
477479
UI_TESTS := $(UI_RS)
480+
MIR_OPT_TESTS := $(MIR_OPT_RS)
478481
RUSTDOCCK_TESTS := $(RUSTDOCCK_RS)
479482

480483
CTEST_SRC_BASE_rpass = run-pass
@@ -552,6 +555,11 @@ CTEST_BUILD_BASE_ui = ui
552555
CTEST_MODE_ui = ui
553556
CTEST_RUNTOOL_ui = $(CTEST_RUNTOOL)
554557

558+
CTEST_SRC_BASE_mir-opt = mir-opt
559+
CTEST_BUILD_BASE_mir-opt = mir-opt
560+
CTEST_MODE_mir-opt = mir-opt
561+
CTEST_RUNTOOL_mir-opt = $(CTEST_RUNTOOL)
562+
555563
CTEST_SRC_BASE_rustdocck = rustdoc
556564
CTEST_BUILD_BASE_rustdocck = rustdoc
557565
CTEST_MODE_rustdocck = rustdoc
@@ -684,6 +692,7 @@ CTEST_DEPS_incremental_$(1)-T-$(2)-H-$(3) = $$(INCREMENTAL_TESTS)
684692
CTEST_DEPS_rmake_$(1)-T-$(2)-H-$(3) = $$(RMAKE_TESTS) \
685693
$$(CSREQ$(1)_T_$(3)_H_$(3)) $$(SREQ$(1)_T_$(2)_H_$(3))
686694
CTEST_DEPS_ui_$(1)-T-$(2)-H-$(3) = $$(UI_TESTS)
695+
CTEST_DEPS_mir-opt_$(1)-T-$(2)-H-$(3) = $$(MIR_OPT_TESTS)
687696
CTEST_DEPS_rustdocck_$(1)-T-$(2)-H-$(3) = $$(RUSTDOCCK_TESTS) \
688697
$$(HBIN$(1)_H_$(3))/rustdoc$$(X_$(3)) \
689698
$(S)src/etc/htmldocck.py
@@ -755,7 +764,7 @@ endef
755764

756765
CTEST_NAMES = rpass rpass-valgrind rpass-full rfail-full cfail-full rfail cfail pfail \
757766
debuginfo-gdb debuginfo-lldb codegen codegen-units rustdocck incremental \
758-
rmake ui
767+
rmake ui mir-opt
759768

760769
$(foreach host,$(CFG_HOST), \
761770
$(eval $(foreach target,$(CFG_TARGET), \
@@ -964,6 +973,7 @@ TEST_GROUPS = \
964973
pretty-rfail-full \
965974
pretty-rfail \
966975
pretty-pretty \
976+
mir-opt \
967977
$(NULL)
968978

969979
define DEF_CHECK_FOR_STAGE_AND_TARGET_AND_HOST

src/bootstrap/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,10 @@ impl Build {
388388
check::compiletest(self, &compiler, target.target,
389389
"pretty", "run-pass-valgrind");
390390
}
391+
CheckMirOpt { compiler } => {
392+
check::compiletest(self, &compiler, target.target,
393+
"mir-opt", "mir-opt");
394+
}
391395
CheckCodegen { compiler } => {
392396
check::compiletest(self, &compiler, target.target,
393397
"codegen", "codegen");

src/bootstrap/step.rs

+3
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ macro_rules! targets {
124124
(check_codegen_units, CheckCodegenUnits { compiler: Compiler<'a> }),
125125
(check_incremental, CheckIncremental { compiler: Compiler<'a> }),
126126
(check_ui, CheckUi { compiler: Compiler<'a> }),
127+
(check_mir_opt, CheckMirOpt { compiler: Compiler<'a> }),
127128
(check_debuginfo, CheckDebuginfo { compiler: Compiler<'a> }),
128129
(check_rustdoc, CheckRustdoc { compiler: Compiler<'a> }),
129130
(check_docs, CheckDocs { compiler: Compiler<'a> }),
@@ -450,6 +451,7 @@ impl<'a> Step<'a> {
450451
self.check_pretty_rfail_full(compiler),
451452
self.check_rpass_valgrind(compiler),
452453
self.check_rmake(compiler),
454+
self.check_mir_opt(compiler),
453455

454456
// crates
455457
self.check_crate_rustc(compiler),
@@ -477,6 +479,7 @@ impl<'a> Step<'a> {
477479
Source::CheckTidy { stage } => {
478480
vec![self.tool_tidy(stage)]
479481
}
482+
Source::CheckMirOpt { compiler} |
480483
Source::CheckPrettyRPass { compiler } |
481484
Source::CheckPrettyRFail { compiler } |
482485
Source::CheckRFail { compiler } |

src/librustc/session/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
747747
"set the MIR optimization level (0-3)"),
748748
dump_mir: Option<String> = (None, parse_opt_string,
749749
"dump MIR state at various points in translation"),
750+
dump_mir_dir: Option<String> = (None, parse_opt_string,
751+
"the directory the MIR is dumped into"),
750752
orbit: bool = (false, parse_bool,
751753
"get MIR where it belongs - everywhere; most importantly, in orbit"),
752754
}

src/librustc_mir/pretty.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use std::fmt::Display;
1919
use std::fs;
2020
use std::io::{self, Write};
2121
use syntax::ast::NodeId;
22+
use std::path::{PathBuf, Path};
2223

2324
const INDENT: &'static str = " ";
2425
/// Alignment for lining up comments following MIR statements
@@ -66,9 +67,15 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
6667
_ => String::new()
6768
};
6869

70+
let mut file_path = PathBuf::new();
71+
if let Some(ref file_dir) = tcx.sess.opts.debugging_opts.dump_mir_dir {
72+
let p = Path::new(file_dir);
73+
file_path.push(p);
74+
};
6975
let file_name = format!("rustc.node{}{}.{}.{}.mir",
7076
node_id, promotion_id, pass_name, disambiguator);
71-
let _ = fs::File::create(&file_name).and_then(|mut file| {
77+
file_path.push(&file_name);
78+
let _ = fs::File::create(&file_path).and_then(|mut file| {
7279
try!(writeln!(file, "// MIR for `{}`", node_path));
7380
try!(writeln!(file, "// node_id = {}", node_id));
7481
try!(writeln!(file, "// pass_name = {}", pass_name));

src/test/mir-opt/README.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
This folder contains tests for MIR optimizations.
2+
3+
The test format is:
4+
5+
```
6+
(arbitrary rust code)
7+
// END RUST SOURCE
8+
// START $file_name_of_some_mir_dump_0
9+
// $expected_line_0
10+
// ...
11+
// $expected_line_N
12+
// END $file_name_of_some_mir_dump_0
13+
// ...
14+
// START $file_name_of_some_mir_dump_N
15+
// $expected_line_0
16+
// ...
17+
// $expected_line_N
18+
// END $file_name_of_some_mir_dump_N
19+
```
20+
21+
All the test information is in comments so the test is runnable.
22+
23+
For each $file_name, compiletest expects [$expected_line_0, ...,
24+
$expected_line_N] to appear in the dumped MIR in order. Currently it allows
25+
other non-matched lines before, after and in-between.
26+
27+
Lines match ignoring whitespace, and the prefix "//" is removed.
28+
29+
It also currently strips trailing comments -- partly because the full file path
30+
in "scope comments" is unpredictable and partly because tidy complains about
31+
the lines being too long.
32+
33+
compiletest handles dumping the MIR before and after every pass for you. The
34+
test writer only has to specify the file names of the dumped files (not the
35+
full path to the file) and what lines to expect. I added an option to rustc
36+
that tells it to dump the mir into some directly (rather then always dumping to
37+
the current directory).
38+
39+
Lines match ignoring whitespace, and the prefix "//" is removed of course.
40+
41+
It also currently strips trailing comments -- partly because the full file path
42+
in "scope comments" is unpredictable and partly because tidy complains about
43+
the lines being too long.
44+

src/test/mir-opt/return_an_array.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// this tests move up progration, which is not yet implemented
12+
13+
fn foo() -> [u8; 1024] {
14+
let x = [0; 1024];
15+
return x;
16+
}
17+
18+
fn main() { }

src/test/mir-opt/simplify_if.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
if false {
13+
println!("hello world!");
14+
}
15+
}
16+
17+
// END RUST SOURCE
18+
// START rustc.node4.SimplifyBranches.initial-before.mir
19+
// bb0: {
20+
// if(const false) -> [true: bb1, false: bb2]; // scope 0 at simplify_if.rs:12:5: 14:6
21+
// }
22+
// END rustc.node4.SimplifyBranches.initial-before.mir
23+
// START rustc.node4.SimplifyBranches.initial-after.mir
24+
// bb0: {
25+
// goto -> bb2; // scope 0 at simplify_if.rs:12:5: 14:6
26+
// }
27+
// END rustc.node4.SimplifyBranches.initial-after.mir

src/tools/compiletest/src/common.rs

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub enum Mode {
2929
Incremental,
3030
RunMake,
3131
Ui,
32+
MirOpt,
3233
}
3334

3435
impl FromStr for Mode {
@@ -49,6 +50,7 @@ impl FromStr for Mode {
4950
"incremental" => Ok(Incremental),
5051
"run-make" => Ok(RunMake),
5152
"ui" => Ok(Ui),
53+
"mir-opt" => Ok(MirOpt),
5254
_ => Err(()),
5355
}
5456
}
@@ -71,6 +73,7 @@ impl fmt::Display for Mode {
7173
Incremental => "incremental",
7274
RunMake => "run-make",
7375
Ui => "ui",
76+
MirOpt => "mir-opt",
7477
}, f)
7578
}
7679
}

src/tools/compiletest/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
8686
reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
8787
reqopt("", "mode", "which sort of compile tests to run",
8888
"(compile-fail|parse-fail|run-fail|run-pass|\
89-
run-pass-valgrind|pretty|debug-info|incremental)"),
89+
run-pass-valgrind|pretty|debug-info|incremental|mir-opt)"),
9090
optflag("", "ignored", "run tests marked as ignored"),
9191
optopt("", "runtool", "supervisor program to run tests under \
9292
(eg. emulator, valgrind)", "PROGRAM"),

0 commit comments

Comments
 (0)