]> git.lizzy.rs Git - rust.git/commitdiff
initial sketch of codegen mode for compiletest; doesn't measure / compare / ratchet...
authorGraydon Hoare <graydon@mozilla.com>
Sat, 6 Jul 2013 07:44:40 +0000 (00:44 -0700)
committerGraydon Hoare <graydon@mozilla.com>
Thu, 11 Jul 2013 20:15:52 +0000 (13:15 -0700)
src/compiletest/common.rs
src/compiletest/compiletest.rs
src/compiletest/runtest.rs

index 38289f6274180a63c401d0f1754e9481f2f25f75..df00286c87f2504943308d139497ad5e2ca3a25c 100644 (file)
@@ -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,
 
index 7d9a7c3ea75dcc75f49b1eadba8af12a6dd7d897..5d3f81fd884566eceb6472fa9db69b1374086058 100644 (file)
@@ -19,6 +19,7 @@
 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_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 @@ fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
         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",
     }
 }
 
index 91016ba91fa555a8c5c7ea6d971394cc096d7867..dee07c6de495df1345a7193eaab60044795c26f9 100644 (file)
@@ -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);
+    }
+
+
+
+}
+