initial sketch of codegen mode for compiletest; doesn't measure / compare / ratchet the disassembly yet
This commit is contained in:
parent
278ed50e0a
commit
e14cd392a4
|
@ -15,6 +15,7 @@ pub enum mode {
|
|||
mode_run_pass,
|
||||
mode_pretty,
|
||||
mode_debug_info,
|
||||
mode_codegen
|
||||
}
|
||||
|
||||
pub struct config {
|
||||
|
@ -27,6 +28,12 @@ pub struct config {
|
|||
// The rustc executable
|
||||
rustc_path: Path,
|
||||
|
||||
// The clang executable
|
||||
clang_path: Option<Path>,
|
||||
|
||||
// The llvm binaries path
|
||||
llvm_bin_path: Option<Path>,
|
||||
|
||||
// The directory containing the tests to run
|
||||
src_base: Path,
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ extern mod extra;
|
|||
use std::os;
|
||||
|
||||
use extra::getopts;
|
||||
use extra::getopts::groups::{optopt, optflag, reqopt};
|
||||
use extra::test;
|
||||
|
||||
use common::config;
|
||||
|
@ -27,6 +28,7 @@ use common::mode_run_fail;
|
|||
use common::mode_compile_fail;
|
||||
use common::mode_pretty;
|
||||
use common::mode_debug_info;
|
||||
use common::mode_codegen;
|
||||
use common::mode;
|
||||
use util::logv;
|
||||
|
||||
|
@ -45,31 +47,54 @@ pub fn main() {
|
|||
}
|
||||
|
||||
pub fn parse_config(args: ~[~str]) -> config {
|
||||
let opts =
|
||||
~[getopts::reqopt("compile-lib-path"),
|
||||
getopts::reqopt("run-lib-path"),
|
||||
getopts::reqopt("rustc-path"), getopts::reqopt("src-base"),
|
||||
getopts::reqopt("build-base"), getopts::reqopt("aux-base"),
|
||||
getopts::reqopt("stage-id"),
|
||||
getopts::reqopt("mode"), getopts::optflag("ignored"),
|
||||
getopts::optopt("runtool"), getopts::optopt("rustcflags"),
|
||||
getopts::optflag("verbose"),
|
||||
getopts::optopt("logfile"),
|
||||
getopts::optflag("jit"),
|
||||
getopts::optflag("newrt"),
|
||||
getopts::optopt("target"),
|
||||
getopts::optopt("adb-path"),
|
||||
getopts::optopt("adb-test-dir")
|
||||
|
||||
let groups : ~[getopts::groups::OptGroup] =
|
||||
~[reqopt("", "compile-lib-path", "path to host shared libraries", "PATH"),
|
||||
reqopt("", "run-lib-path", "path to target shared libraries", "PATH"),
|
||||
reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH"),
|
||||
optopt("", "clang-path", "path to executable for codegen tests", "PATH"),
|
||||
optopt("", "llvm-bin-path", "path to directory holding llvm binaries", "DIR"),
|
||||
reqopt("", "src-base", "directory to scan for test files", "PATH"),
|
||||
reqopt("", "build-base", "directory to deposit test outputs", "PATH"),
|
||||
reqopt("", "aux-base", "directory to find auxiliary test files", "PATH"),
|
||||
reqopt("", "stage-id", "the target-stage identifier", "stageN-TARGET"),
|
||||
reqopt("", "mode", "which sort of compile tests to run",
|
||||
"(compile-fail|run-fail|run-pass|pretty|debug-info)"),
|
||||
optflag("", "ignored", "run tests marked as ignored / xfailed"),
|
||||
optopt("", "runtool", "supervisor program to run tests under \
|
||||
(eg. emulator, valgrind)", "PROGRAM"),
|
||||
optopt("", "rustcflags", "flags to pass to rustc", "FLAGS"),
|
||||
optflag("", "verbose", "run tests verbosely, showing all output"),
|
||||
optopt("", "logfile", "file to log test execution to", "FILE"),
|
||||
optflag("", "jit", "run tests under the JIT"),
|
||||
optflag("", "newrt", "run tests on the new runtime / scheduler"),
|
||||
optopt("", "target", "the target to build for", "TARGET"),
|
||||
optopt("", "adb-path", "path to the android debugger", "PATH"),
|
||||
optopt("", "adb-test-dir", "path to tests for the android debugger", "PATH"),
|
||||
optflag("h", "help", "show this message"),
|
||||
];
|
||||
|
||||
assert!(!args.is_empty());
|
||||
let argv0 = copy args[0];
|
||||
let args_ = args.tail();
|
||||
if args[1] == ~"-h" || args[1] == ~"--help" {
|
||||
let message = fmt!("Usage: %s [OPTIONS] [TESTNAME...]", argv0);
|
||||
io::println(getopts::groups::usage(message, groups));
|
||||
fail!()
|
||||
}
|
||||
|
||||
let matches =
|
||||
&match getopts::getopts(args_, opts) {
|
||||
&match getopts::groups::getopts(args_, groups) {
|
||||
Ok(m) => m,
|
||||
Err(f) => fail!(getopts::fail_str(f))
|
||||
};
|
||||
|
||||
if getopts::opt_present(matches, "h") || getopts::opt_present(matches, "help") {
|
||||
let message = fmt!("Usage: %s [OPTIONS] [TESTNAME...]", argv0);
|
||||
io::println(getopts::groups::usage(message, groups));
|
||||
fail!()
|
||||
}
|
||||
|
||||
fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
|
||||
Path(getopts::opt_str(m, nm))
|
||||
}
|
||||
|
@ -78,6 +103,8 @@ pub fn parse_config(args: ~[~str]) -> config {
|
|||
compile_lib_path: getopts::opt_str(matches, "compile-lib-path"),
|
||||
run_lib_path: getopts::opt_str(matches, "run-lib-path"),
|
||||
rustc_path: opt_path(matches, "rustc-path"),
|
||||
clang_path: getopts::opt_maybe_str(matches, "clang-path").map(|s| Path(*s)),
|
||||
llvm_bin_path: getopts::opt_maybe_str(matches, "llvm-bin-path").map(|s| Path(*s)),
|
||||
src_base: opt_path(matches, "src-base"),
|
||||
build_base: opt_path(matches, "build-base"),
|
||||
aux_base: opt_path(matches, "aux-base"),
|
||||
|
@ -159,6 +186,7 @@ pub fn str_mode(s: ~str) -> mode {
|
|||
~"run-pass" => mode_run_pass,
|
||||
~"pretty" => mode_pretty,
|
||||
~"debug-info" => mode_debug_info,
|
||||
~"codegen" => mode_codegen,
|
||||
_ => fail!("invalid mode")
|
||||
}
|
||||
}
|
||||
|
@ -170,6 +198,7 @@ pub fn mode_str(mode: mode) -> ~str {
|
|||
mode_run_pass => ~"run-pass",
|
||||
mode_pretty => ~"pretty",
|
||||
mode_debug_info => ~"debug-info",
|
||||
mode_codegen => ~"codegen",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ pub fn run(config: config, testfile: ~str) {
|
|||
mode_run_fail => run_rfail_test(&config, &props, &testfile),
|
||||
mode_run_pass => run_rpass_test(&config, &props, &testfile),
|
||||
mode_pretty => run_pretty_test(&config, &props, &testfile),
|
||||
mode_debug_info => run_debuginfo_test(&config, &props, &testfile)
|
||||
mode_debug_info => run_debuginfo_test(&config, &props, &testfile),
|
||||
mode_codegen => run_codegen_test(&config, &props, &testfile)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,3 +836,118 @@ fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// codegen tests (vs. clang)
|
||||
|
||||
fn make_o_name(config: &config, testfile: &Path) -> Path {
|
||||
output_base_name(config, testfile).with_filetype("o")
|
||||
}
|
||||
|
||||
fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
|
||||
if suffix.len() == 0 {
|
||||
copy *p
|
||||
} else {
|
||||
let stem = p.filestem().get();
|
||||
p.with_filestem(stem + "-" + suffix)
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_test_and_save_bitcode(config: &config, props: &TestProps,
|
||||
testfile: &Path) -> ProcRes {
|
||||
let link_args = ~[~"-L", aux_output_dir_name(config, testfile).to_str()];
|
||||
let llvm_args = ~[~"-c", ~"--lib", ~"--save-temps"];
|
||||
let args = make_compile_args(config, props,
|
||||
link_args + llvm_args,
|
||||
make_o_name, testfile);
|
||||
compose_and_run_compiler(config, props, testfile, args, None)
|
||||
}
|
||||
|
||||
fn compile_cc_with_clang_and_save_bitcode(config: &config, _props: &TestProps,
|
||||
testfile: &Path) -> ProcRes {
|
||||
let bitcodefile = output_base_name(config, testfile).with_filetype("bc");
|
||||
let bitcodefile = append_suffix_to_stem(&bitcodefile, "clang");
|
||||
let ProcArgs = ProcArgs {
|
||||
prog: config.clang_path.get_ref().to_str(),
|
||||
args: ~[~"-c",
|
||||
~"-emit-llvm",
|
||||
~"-o", bitcodefile.to_str(),
|
||||
testfile.with_filetype("cc").to_str() ]
|
||||
};
|
||||
compose_and_run(config, testfile, ProcArgs, ~[], "", None)
|
||||
}
|
||||
|
||||
fn extract_function_from_bitcode(config: &config, _props: &TestProps,
|
||||
fname: &str, testfile: &Path,
|
||||
suffix: &str) -> ProcRes {
|
||||
let bitcodefile = output_base_name(config, testfile).with_filetype("bc");
|
||||
let bitcodefile = append_suffix_to_stem(&bitcodefile, suffix);
|
||||
let extracted_bc = append_suffix_to_stem(&bitcodefile, "extract");
|
||||
let ProcArgs = ProcArgs {
|
||||
prog: config.llvm_bin_path.get_ref().push("llvm-extract").to_str(),
|
||||
args: ~[~"-func=" + fname,
|
||||
~"-o=" + extracted_bc.to_str(),
|
||||
bitcodefile.to_str() ]
|
||||
};
|
||||
compose_and_run(config, testfile, ProcArgs, ~[], "", None)
|
||||
}
|
||||
|
||||
fn disassemble_extract(config: &config, _props: &TestProps,
|
||||
testfile: &Path, suffix: &str) -> ProcRes {
|
||||
let bitcodefile = output_base_name(config, testfile).with_filetype("bc");
|
||||
let bitcodefile = append_suffix_to_stem(&bitcodefile, suffix);
|
||||
let extracted_bc = append_suffix_to_stem(&bitcodefile, "extract");
|
||||
let extracted_ll = extracted_bc.with_filetype("ll");
|
||||
let ProcArgs = ProcArgs {
|
||||
prog: config.llvm_bin_path.get_ref().push("llvm-dis").to_str(),
|
||||
args: ~[~"-o=" + extracted_ll.to_str(),
|
||||
extracted_bc.to_str() ]
|
||||
};
|
||||
compose_and_run(config, testfile, ProcArgs, ~[], "", None)
|
||||
}
|
||||
|
||||
|
||||
fn run_codegen_test(config: &config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
if config.llvm_bin_path.is_none() {
|
||||
fatal(~"missing --llvm-bin-path");
|
||||
}
|
||||
|
||||
if config.clang_path.is_none() {
|
||||
fatal(~"missing --clang-path");
|
||||
}
|
||||
|
||||
let mut ProcRes = compile_test_and_save_bitcode(config, props, testfile);
|
||||
if ProcRes.status != 0 {
|
||||
fatal_ProcRes(~"compilation failed!", &ProcRes);
|
||||
}
|
||||
|
||||
ProcRes = extract_function_from_bitcode(config, props, "test", testfile, "");
|
||||
if ProcRes.status != 0 {
|
||||
fatal_ProcRes(~"extracting 'test' function failed", &ProcRes);
|
||||
}
|
||||
|
||||
ProcRes = disassemble_extract(config, props, testfile, "");
|
||||
if ProcRes.status != 0 {
|
||||
fatal_ProcRes(~"disassembling extract failed", &ProcRes);
|
||||
}
|
||||
|
||||
|
||||
let mut ProcRes = compile_cc_with_clang_and_save_bitcode(config, props, testfile);
|
||||
if ProcRes.status != 0 {
|
||||
fatal_ProcRes(~"compilation failed!", &ProcRes);
|
||||
}
|
||||
|
||||
ProcRes = extract_function_from_bitcode(config, props, "test", testfile, "clang");
|
||||
if ProcRes.status != 0 {
|
||||
fatal_ProcRes(~"extracting 'test' function failed", &ProcRes);
|
||||
}
|
||||
|
||||
ProcRes = disassemble_extract(config, props, testfile, "clang");
|
||||
if ProcRes.status != 0 {
|
||||
fatal_ProcRes(~"disassembling extract failed", &ProcRes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue