Skip to content

Commit e14cd39

Browse files
committed
initial sketch of codegen mode for compiletest; doesn't measure / compare / ratchet the disassembly yet
1 parent 278ed50 commit e14cd39

File tree

3 files changed

+169
-17
lines changed

3 files changed

+169
-17
lines changed

src/compiletest/common.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub enum mode {
1515
mode_run_pass,
1616
mode_pretty,
1717
mode_debug_info,
18+
mode_codegen
1819
}
1920

2021
pub struct config {
@@ -27,6 +28,12 @@ pub struct config {
2728
// The rustc executable
2829
rustc_path: Path,
2930

31+
// The clang executable
32+
clang_path: Option<Path>,
33+
34+
// The llvm binaries path
35+
llvm_bin_path: Option<Path>,
36+
3037
// The directory containing the tests to run
3138
src_base: Path,
3239

src/compiletest/compiletest.rs

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern mod extra;
1919
use std::os;
2020

2121
use extra::getopts;
22+
use extra::getopts::groups::{optopt, optflag, reqopt};
2223
use extra::test;
2324

2425
use common::config;
@@ -27,6 +28,7 @@ use common::mode_run_fail;
2728
use common::mode_compile_fail;
2829
use common::mode_pretty;
2930
use common::mode_debug_info;
31+
use common::mode_codegen;
3032
use common::mode;
3133
use util::logv;
3234

@@ -45,31 +47,54 @@ pub fn main() {
4547
}
4648

4749
pub fn parse_config(args: ~[~str]) -> config {
48-
let opts =
49-
~[getopts::reqopt("compile-lib-path"),
50-
getopts::reqopt("run-lib-path"),
51-
getopts::reqopt("rustc-path"), getopts::reqopt("src-base"),
52-
getopts::reqopt("build-base"), getopts::reqopt("aux-base"),
53-
getopts::reqopt("stage-id"),
54-
getopts::reqopt("mode"), getopts::optflag("ignored"),
55-
getopts::optopt("runtool"), getopts::optopt("rustcflags"),
56-
getopts::optflag("verbose"),
57-
getopts::optopt("logfile"),
58-
getopts::optflag("jit"),
59-
getopts::optflag("newrt"),
60-
getopts::optopt("target"),
61-
getopts::optopt("adb-path"),
62-
getopts::optopt("adb-test-dir")
50+
51+
let groups : ~[getopts::groups::OptGroup] =
52+
~[reqopt("", "compile-lib-path", "path to host shared libraries", "PATH"),
53+
reqopt("", "run-lib-path", "path to target shared libraries", "PATH"),
54+
reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH"),
55+
optopt("", "clang-path", "path to executable for codegen tests", "PATH"),
56+
optopt("", "llvm-bin-path", "path to directory holding llvm binaries", "DIR"),
57+
reqopt("", "src-base", "directory to scan for test files", "PATH"),
58+
reqopt("", "build-base", "directory to deposit test outputs", "PATH"),
59+
reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
60+
reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
61+
reqopt("", "mode", "which sort of compile tests to run",
62+
"(compile-fail|run-fail|run-pass|pretty|debug-info)"),
63+
optflag("", "ignored", "run tests marked as ignored / xfailed"),
64+
optopt("", "runtool", "supervisor program to run tests under \
65+
(eg. emulator, valgrind)", "PROGRAM"),
66+
optopt("", "rustcflags", "flags to pass to rustc", "FLAGS"),
67+
optflag("", "verbose", "run tests verbosely, showing all output"),
68+
optopt("", "logfile", "file to log test execution to", "FILE"),
69+
optflag("", "jit", "run tests under the JIT"),
70+
optflag("", "newrt", "run tests on the new runtime / scheduler"),
71+
optopt("", "target", "the target to build for", "TARGET"),
72+
optopt("", "adb-path", "path to the android debugger", "PATH"),
73+
optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"),
74+
optflag("h", "help", "show this message"),
6375
];
6476

6577
assert!(!args.is_empty());
78+
let argv0 = copy args[0];
6679
let args_ = args.tail();
80+
if args[1] == ~"-h" || args[1] == ~"--help" {
81+
let message = fmt!("Usage: %s [OPTIONS] [TESTNAME...]", argv0);
82+
io::println(getopts::groups::usage(message, groups));
83+
fail!()
84+
}
85+
6786
let matches =
68-
&match getopts::getopts(args_, opts) {
87+
&match getopts::groups::getopts(args_, groups) {
6988
Ok(m) => m,
7089
Err(f) => fail!(getopts::fail_str(f))
7190
};
7291

92+
if getopts::opt_present(matches, "h") || getopts::opt_present(matches, "help") {
93+
let message = fmt!("Usage: %s [OPTIONS] [TESTNAME...]", argv0);
94+
io::println(getopts::groups::usage(message, groups));
95+
fail!()
96+
}
97+
7398
fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
7499
Path(getopts::opt_str(m, nm))
75100
}
@@ -78,6 +103,8 @@ pub fn parse_config(args: ~[~str]) -> config {
78103
compile_lib_path: getopts::opt_str(matches, "compile-lib-path"),
79104
run_lib_path: getopts::opt_str(matches, "run-lib-path"),
80105
rustc_path: opt_path(matches, "rustc-path"),
106+
clang_path: getopts::opt_maybe_str(matches, "clang-path").map(|s| Path(*s)),
107+
llvm_bin_path: getopts::opt_maybe_str(matches, "llvm-bin-path").map(|s| Path(*s)),
81108
src_base: opt_path(matches, "src-base"),
82109
build_base: opt_path(matches, "build-base"),
83110
aux_base: opt_path(matches, "aux-base"),
@@ -159,6 +186,7 @@ pub fn str_mode(s: ~str) -> mode {
159186
~"run-pass" => mode_run_pass,
160187
~"pretty" => mode_pretty,
161188
~"debug-info" => mode_debug_info,
189+
~"codegen" => mode_codegen,
162190
_ => fail!("invalid mode")
163191
}
164192
}
@@ -170,6 +198,7 @@ pub fn mode_str(mode: mode) -> ~str {
170198
mode_run_pass => ~"run-pass",
171199
mode_pretty => ~"pretty",
172200
mode_debug_info => ~"debug-info",
201+
mode_codegen => ~"codegen",
173202
}
174203
}
175204

src/compiletest/runtest.rs

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ pub fn run(config: config, testfile: ~str) {
3939
mode_run_fail => run_rfail_test(&config, &props, &testfile),
4040
mode_run_pass => run_rpass_test(&config, &props, &testfile),
4141
mode_pretty => run_pretty_test(&config, &props, &testfile),
42-
mode_debug_info => run_debuginfo_test(&config, &props, &testfile)
42+
mode_debug_info => run_debuginfo_test(&config, &props, &testfile),
43+
mode_codegen => run_codegen_test(&config, &props, &testfile)
4344
}
4445
}
4546

@@ -835,3 +836,118 @@ fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
835836
}
836837
}
837838
}
839+
840+
// codegen tests (vs. clang)
841+
842+
fn make_o_name(config: &config, testfile: &Path) -> Path {
843+
output_base_name(config, testfile).with_filetype("o")
844+
}
845+
846+
fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
847+
if suffix.len() == 0 {
848+
copy *p
849+
} else {
850+
let stem = p.filestem().get();
851+
p.with_filestem(stem + "-" + suffix)
852+
}
853+
}
854+
855+
fn compile_test_and_save_bitcode(config: &config, props: &TestProps,
856+
testfile: &Path) -> ProcRes {
857+
let link_args = ~[~"-L", aux_output_dir_name(config, testfile).to_str()];
858+
let llvm_args = ~[~"-c", ~"--lib", ~"--save-temps"];
859+
let args = make_compile_args(config, props,
860+
link_args + llvm_args,
861+
make_o_name, testfile);
862+
compose_and_run_compiler(config, props, testfile, args, None)
863+
}
864+
865+
fn compile_cc_with_clang_and_save_bitcode(config: &config, _props: &TestProps,
866+
testfile: &Path) -> ProcRes {
867+
let bitcodefile = output_base_name(config, testfile).with_filetype("bc");
868+
let bitcodefile = append_suffix_to_stem(&bitcodefile, "clang");
869+
let ProcArgs = ProcArgs {
870+
prog: config.clang_path.get_ref().to_str(),
871+
args: ~[~"-c",
872+
~"-emit-llvm",
873+
~"-o", bitcodefile.to_str(),
874+
testfile.with_filetype("cc").to_str() ]
875+
};
876+
compose_and_run(config, testfile, ProcArgs, ~[], "", None)
877+
}
878+
879+
fn extract_function_from_bitcode(config: &config, _props: &TestProps,
880+
fname: &str, testfile: &Path,
881+
suffix: &str) -> ProcRes {
882+
let bitcodefile = output_base_name(config, testfile).with_filetype("bc");
883+
let bitcodefile = append_suffix_to_stem(&bitcodefile, suffix);
884+
let extracted_bc = append_suffix_to_stem(&bitcodefile, "extract");
885+
let ProcArgs = ProcArgs {
886+
prog: config.llvm_bin_path.get_ref().push("llvm-extract").to_str(),
887+
args: ~[~"-func=" + fname,
888+
~"-o=" + extracted_bc.to_str(),
889+
bitcodefile.to_str() ]
890+
};
891+
compose_and_run(config, testfile, ProcArgs, ~[], "", None)
892+
}
893+
894+
fn disassemble_extract(config: &config, _props: &TestProps,
895+
testfile: &Path, suffix: &str) -> ProcRes {
896+
let bitcodefile = output_base_name(config, testfile).with_filetype("bc");
897+
let bitcodefile = append_suffix_to_stem(&bitcodefile, suffix);
898+
let extracted_bc = append_suffix_to_stem(&bitcodefile, "extract");
899+
let extracted_ll = extracted_bc.with_filetype("ll");
900+
let ProcArgs = ProcArgs {
901+
prog: config.llvm_bin_path.get_ref().push("llvm-dis").to_str(),
902+
args: ~[~"-o=" + extracted_ll.to_str(),
903+
extracted_bc.to_str() ]
904+
};
905+
compose_and_run(config, testfile, ProcArgs, ~[], "", None)
906+
}
907+
908+
909+
fn run_codegen_test(config: &config, props: &TestProps, testfile: &Path) {
910+
911+
if config.llvm_bin_path.is_none() {
912+
fatal(~"missing --llvm-bin-path");
913+
}
914+
915+
if config.clang_path.is_none() {
916+
fatal(~"missing --clang-path");
917+
}
918+
919+
let mut ProcRes = compile_test_and_save_bitcode(config, props, testfile);
920+
if ProcRes.status != 0 {
921+
fatal_ProcRes(~"compilation failed!", &ProcRes);
922+
}
923+
924+
ProcRes = extract_function_from_bitcode(config, props, "test", testfile, "");
925+
if ProcRes.status != 0 {
926+
fatal_ProcRes(~"extracting 'test' function failed", &ProcRes);
927+
}
928+
929+
ProcRes = disassemble_extract(config, props, testfile, "");
930+
if ProcRes.status != 0 {
931+
fatal_ProcRes(~"disassembling extract failed", &ProcRes);
932+
}
933+
934+
935+
let mut ProcRes = compile_cc_with_clang_and_save_bitcode(config, props, testfile);
936+
if ProcRes.status != 0 {
937+
fatal_ProcRes(~"compilation failed!", &ProcRes);
938+
}
939+
940+
ProcRes = extract_function_from_bitcode(config, props, "test", testfile, "clang");
941+
if ProcRes.status != 0 {
942+
fatal_ProcRes(~"extracting 'test' function failed", &ProcRes);
943+
}
944+
945+
ProcRes = disassemble_extract(config, props, testfile, "clang");
946+
if ProcRes.status != 0 {
947+
fatal_ProcRes(~"disassembling extract failed", &ProcRes);
948+
}
949+
950+
951+
952+
}
953+

0 commit comments

Comments
 (0)