Skip to content

Commit 4bfb230

Browse files
committed
auto merge of #7829 : graydon/rust/codegen-compiletests, r=thestinger
This should get us over the hump of activating basic ratcheting on codegen tests, at least. It also puts in place optional (disabled by default) ratcheting on all #[bench] tests, and records all metrics from them to harvestable .json files in any case.
2 parents 8a1002f + 8e58a27 commit 4bfb230

File tree

6 files changed

+263
-31
lines changed

6 files changed

+263
-31
lines changed

configure

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ opt optimize 1 "build optimized rust code"
372372
opt optimize-cxx 1 "build optimized C++ code"
373373
opt optimize-llvm 1 "build optimized LLVM"
374374
opt debug 0 "build with extra debug fun"
375+
opt ratchet-bench 0 "ratchet benchmarks"
375376
opt fast-make 0 "use .gitmodules as timestamp for submodule deps"
376377
opt manage-submodules 1 "let the build manage the git submodules"
377378
opt mingw-cross 0 "cross-compile for win32 using mingw"

mk/tests.mk

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,21 @@ endif
6060
TEST_LOG_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).log
6161
TEST_OK_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).ok
6262

63+
TEST_RATCHET_FILE=tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4)-metrics.json
64+
TEST_RATCHET_NOISE_PERCENT=10.0
65+
66+
# Whether to ratchet or merely save benchmarks
67+
ifdef CFG_RATCHET_BENCH
68+
CRATE_TEST_BENCH_ARGS=\
69+
--test --bench \
70+
--ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \
71+
--ratchet-noise-percent $(TEST_RATCHET_NOISE_PERCENT)
72+
else
73+
CRATE_TEST_BENCH_ARGS=\
74+
--test --bench \
75+
--save-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4))
76+
endif
77+
6378
define DEF_TARGET_COMMANDS
6479

6580
ifdef CFG_UNIXY_$(1)
@@ -359,11 +374,14 @@ $(foreach host,$(CFG_HOST_TRIPLES), \
359374
define DEF_TEST_CRATE_RULES
360375
check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4))
361376

377+
check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4))
378+
362379
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
363380
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
364381
@$$(call E, run: $$<)
365382
$$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(2),$(3)) $$(TESTARGS) \
366383
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
384+
$$(call CRATE_TEST_BENCH_ARGS,$(1),$(2),$(3),$(4)) \
367385
&& touch $$@
368386
endef
369387

@@ -552,6 +570,7 @@ CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
552570
$$(CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3)) \
553571
--src-base $$(S)src/test/$$(CTEST_SRC_BASE_$(4))/ \
554572
--build-base $(3)/test/$$(CTEST_BUILD_BASE_$(4))/ \
573+
--ratchet-metrics $(call TEST_RATCHET_FILE,$(1),$(2),$(3),$(4)) \
555574
--mode $$(CTEST_MODE_$(4)) \
556575
$$(CTEST_RUNTOOL_$(4))
557576

src/compiletest/common.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ pub struct config {
5858
// Write out a parseable log of tests that were run
5959
logfile: Option<Path>,
6060

61+
// Write out a json file containing any metrics of the run
62+
save_metrics: Option<Path>,
63+
64+
// Write and ratchet a metrics file
65+
ratchet_metrics: Option<Path>,
66+
67+
// Percent change in metrics to consider noise
68+
ratchet_noise_percent: Option<f64>,
69+
6170
// A command line to prefix program execution with,
6271
// for running under valgrind
6372
runtool: Option<~str>,

src/compiletest/compiletest.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
extern mod extra;
1818

1919
use std::os;
20+
use std::f64;
2021

2122
use extra::getopts;
2223
use extra::getopts::groups::{optopt, optflag, reqopt};
@@ -66,6 +67,10 @@ pub fn parse_config(args: ~[~str]) -> config {
6667
optopt("", "rustcflags", "flags to pass to rustc", "FLAGS"),
6768
optflag("", "verbose", "run tests verbosely, showing all output"),
6869
optopt("", "logfile", "file to log test execution to", "FILE"),
70+
optopt("", "save-metrics", "file to save metrics to", "FILE"),
71+
optopt("", "ratchet-metrics", "file to ratchet metrics against", "FILE"),
72+
optopt("", "ratchet-noise-percent",
73+
"percent change in metrics to consider noise", "N"),
6974
optflag("", "jit", "run tests under the JIT"),
7075
optflag("", "newrt", "run tests on the new runtime / scheduler"),
7176
optopt("", "target", "the target to build for", "TARGET"),
@@ -116,6 +121,13 @@ pub fn parse_config(args: ~[~str]) -> config {
116121
Some(copy matches.free[0])
117122
} else { None },
118123
logfile: getopts::opt_maybe_str(matches, "logfile").map(|s| Path(*s)),
124+
save_metrics: getopts::opt_maybe_str(matches, "save-metrics").map(|s| Path(*s)),
125+
ratchet_metrics:
126+
getopts::opt_maybe_str(matches, "ratchet-metrics").map(|s| Path(*s)),
127+
ratchet_noise_percent:
128+
getopts::opt_maybe_str(matches,
129+
"ratchet-noise-percent").map(|s|
130+
f64::from_str(*s).get()),
119131
runtool: getopts::opt_maybe_str(matches, "runtool"),
120132
rustcflags: getopts::opt_maybe_str(matches, "rustcflags"),
121133
jit: getopts::opt_present(matches, "jit"),
@@ -215,10 +227,10 @@ pub fn test_opts(config: &config) -> test::TestOpts {
215227
run_ignored: config.run_ignored,
216228
logfile: copy config.logfile,
217229
run_tests: true,
218-
run_benchmarks: false,
219-
ratchet_metrics: None,
220-
ratchet_noise_percent: None,
221-
save_metrics: None,
230+
run_benchmarks: true,
231+
ratchet_metrics: copy config.ratchet_metrics,
232+
ratchet_noise_percent: copy config.ratchet_noise_percent,
233+
save_metrics: copy config.save_metrics,
222234
}
223235
}
224236

@@ -231,7 +243,13 @@ pub fn make_tests(config: &config) -> ~[test::TestDescAndFn] {
231243
let file = copy *file;
232244
debug!("inspecting file %s", file.to_str());
233245
if is_test(config, file) {
234-
tests.push(make_test(config, file))
246+
let t = do make_test(config, file) {
247+
match config.mode {
248+
mode_codegen => make_metrics_test_closure(config, file),
249+
_ => make_test_closure(config, file)
250+
}
251+
};
252+
tests.push(t)
235253
}
236254
}
237255
tests
@@ -260,14 +278,15 @@ pub fn is_test(config: &config, testfile: &Path) -> bool {
260278
return valid;
261279
}
262280

263-
pub fn make_test(config: &config, testfile: &Path) -> test::TestDescAndFn {
281+
pub fn make_test(config: &config, testfile: &Path,
282+
f: &fn()->test::TestFn) -> test::TestDescAndFn {
264283
test::TestDescAndFn {
265284
desc: test::TestDesc {
266285
name: make_test_name(config, testfile),
267286
ignore: header::is_test_ignored(config, testfile),
268287
should_fail: false
269288
},
270-
testfn: make_test_closure(config, testfile),
289+
testfn: f(),
271290
}
272291
}
273292

@@ -291,3 +310,10 @@ pub fn make_test_closure(config: &config, testfile: &Path) -> test::TestFn {
291310
let testfile = Cell::new(testfile.to_str());
292311
test::DynTestFn(|| { runtest::run(config.take(), testfile.take()) })
293312
}
313+
314+
pub fn make_metrics_test_closure(config: &config, testfile: &Path) -> test::TestFn {
315+
use std::cell::Cell;
316+
let config = Cell::new(copy *config);
317+
let testfile = Cell::new(testfile.to_str());
318+
test::DynMetricFn(|mm| { runtest::run_metrics(config.take(), testfile.take(), mm) })
319+
}

src/compiletest/runtest.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,14 @@ use std::os;
2525
use std::uint;
2626
use std::vec;
2727

28+
use extra::test::MetricMap;
29+
2830
pub fn run(config: config, testfile: ~str) {
31+
let mut _mm = MetricMap::new();
32+
run_metrics(config, testfile, &mut _mm);
33+
}
34+
35+
pub fn run_metrics(config: config, testfile: ~str, mm: &mut MetricMap) {
2936
if config.verbose {
3037
// We're going to be dumping a lot of info. Start on a new line.
3138
io::stdout().write_str("\n\n");
@@ -40,7 +47,7 @@ pub fn run(config: config, testfile: ~str) {
4047
mode_run_pass => run_rpass_test(&config, &props, &testfile),
4148
mode_pretty => run_pretty_test(&config, &props, &testfile),
4249
mode_debug_info => run_debuginfo_test(&config, &props, &testfile),
43-
mode_codegen => run_codegen_test(&config, &props, &testfile)
50+
mode_codegen => run_codegen_test(&config, &props, &testfile, mm)
4451
}
4552
}
4653

@@ -906,7 +913,14 @@ fn disassemble_extract(config: &config, _props: &TestProps,
906913
}
907914

908915

909-
fn run_codegen_test(config: &config, props: &TestProps, testfile: &Path) {
916+
fn count_extracted_lines(p: &Path) -> uint {
917+
let x = io::read_whole_file_str(&p.with_filetype("ll")).get();
918+
x.line_iter().len_()
919+
}
920+
921+
922+
fn run_codegen_test(config: &config, props: &TestProps,
923+
testfile: &Path, mm: &mut MetricMap) {
910924

911925
if config.llvm_bin_path.is_none() {
912926
fatal(~"missing --llvm-bin-path");
@@ -947,7 +961,17 @@ fn run_codegen_test(config: &config, props: &TestProps, testfile: &Path) {
947961
fatal_ProcRes(~"disassembling extract failed", &ProcRes);
948962
}
949963

964+
let base = output_base_name(config, testfile);
965+
let base_extract = append_suffix_to_stem(&base, "extract");
966+
967+
let base_clang = append_suffix_to_stem(&base, "clang");
968+
let base_clang_extract = append_suffix_to_stem(&base_clang, "extract");
950969

970+
let base_lines = count_extracted_lines(&base_extract);
971+
let clang_lines = count_extracted_lines(&base_clang_extract);
951972

973+
mm.insert_metric("clang-codegen-ratio",
974+
(base_lines as f64) / (clang_lines as f64),
975+
0.001);
952976
}
953977

0 commit comments

Comments
 (0)