Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Codegen compiletests #7623

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ do
make_dir $h/test/perf
make_dir $h/test/pretty
make_dir $h/test/debug-info
make_dir $h/test/codegen
make_dir $h/test/doc-tutorial
make_dir $h/test/doc-tutorial-ffi
make_dir $h/test/doc-tutorial-macros
Expand Down
19 changes: 18 additions & 1 deletion mk/tests.mk
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ check-stage$(1)-T-$(2)-H-$(3)-exec: \
check-stage$(1)-T-$(2)-H-$(3)-crates-exec \
check-stage$(1)-T-$(2)-H-$(3)-bench-exec \
check-stage$(1)-T-$(2)-H-$(3)-debuginfo-exec \
check-stage$(1)-T-$(2)-H-$(3)-codegen-exec \
check-stage$(1)-T-$(2)-H-$(3)-doc-exec \
check-stage$(1)-T-$(2)-H-$(3)-pretty-exec

Expand Down Expand Up @@ -430,6 +431,8 @@ CFAIL_RS := $(wildcard $(S)src/test/compile-fail/*.rs)
BENCH_RS := $(wildcard $(S)src/test/bench/*.rs)
PRETTY_RS := $(wildcard $(S)src/test/pretty/*.rs)
DEBUGINFO_RS := $(wildcard $(S)src/test/debug-info/*.rs)
CODEGEN_RS := $(wildcard $(S)src/test/codegen/*.rs)
CODEGEN_CC := $(wildcard $(S)src/test/codegen/*.cc)

# perf tests are the same as bench tests only they run under
# a performance monitor.
Expand All @@ -443,6 +446,7 @@ BENCH_TESTS := $(BENCH_RS)
PERF_TESTS := $(PERF_RS)
PRETTY_TESTS := $(PRETTY_RS)
DEBUGINFO_TESTS := $(DEBUGINFO_RS)
CODEGEN_TESTS := $(CODEGEN_RS) $(CODEGEN_CC)

CTEST_SRC_BASE_rpass = run-pass
CTEST_BUILD_BASE_rpass = run-pass
Expand Down Expand Up @@ -479,10 +483,19 @@ CTEST_BUILD_BASE_debuginfo = debug-info
CTEST_MODE_debuginfo = debug-info
CTEST_RUNTOOL_debuginfo = $(CTEST_RUNTOOL)

CTEST_SRC_BASE_codegen = codegen
CTEST_BUILD_BASE_codegen = codegen
CTEST_MODE_codegen = codegen
CTEST_RUNTOOL_codegen = $(CTEST_RUNTOOL)

ifeq ($(CFG_GDB),)
CTEST_DISABLE_debuginfo = "no gdb found"
endif

ifeq ($(CFG_CLANG),)
CTEST_DISABLE_codegen = "no clang found"
endif

ifeq ($(CFG_OSTYPE),apple-darwin)
CTEST_DISABLE_debuginfo = "gdb on darwing needs root"
endif
Expand All @@ -507,6 +520,8 @@ CTEST_COMMON_ARGS$(1)-T-$(2)-H-$(3) := \
--compile-lib-path $$(HLIB$(1)_H_$(3)) \
--run-lib-path $$(TLIB$(1)_T_$(2)_H_$(3)) \
--rustc-path $$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
--clang-path $(if $(CFG_CLANG),$(CFG_CLANG),clang) \
--llvm-bin-path $(CFG_LLVM_INST_DIR_$(CFG_BUILD_TRIPLE))/bin \
--aux-base $$(S)src/test/auxiliary/ \
--stage-id stage$(1)-$(2) \
--target $(2) \
Expand All @@ -522,6 +537,7 @@ CTEST_DEPS_cfail_$(1)-T-$(2)-H-$(3) = $$(CFAIL_TESTS)
CTEST_DEPS_bench_$(1)-T-$(2)-H-$(3) = $$(BENCH_TESTS)
CTEST_DEPS_perf_$(1)-T-$(2)-H-$(3) = $$(PERF_TESTS)
CTEST_DEPS_debuginfo_$(1)-T-$(2)-H-$(3) = $$(DEBUGINFO_TESTS)
CTEST_DEPS_codegen_$(1)-T-$(2)-H-$(3) = $$(CODEGEN_TESTS)

endef

Expand Down Expand Up @@ -565,7 +581,7 @@ endif

endef

CTEST_NAMES = rpass rpass-full rfail cfail bench perf debuginfo
CTEST_NAMES = rpass rpass-full rfail cfail bench perf debuginfo codegen

$(foreach host,$(CFG_HOST_TRIPLES), \
$(eval $(foreach target,$(CFG_TARGET_TRIPLES), \
Expand Down Expand Up @@ -674,6 +690,7 @@ TEST_GROUPS = \
bench \
perf \
debuginfo \
codegen \
doc \
$(foreach docname,$(DOC_TEST_NAMES),doc-$(docname)) \
pretty \
Expand Down
7 changes: 7 additions & 0 deletions src/compiletest/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub enum mode {
mode_run_pass,
mode_pretty,
mode_debug_info,
mode_codegen
}

pub struct config {
Expand All @@ -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,

Expand Down
66 changes: 48 additions & 18 deletions src/compiletest/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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);
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);
println(getopts::groups::usage(message, groups));
fail!()
}

fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
Path(getopts::opt_str(m, nm))
}
Expand All @@ -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"),
Expand Down Expand Up @@ -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")
}
}
Expand All @@ -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",
}
}

Expand All @@ -187,8 +216,9 @@ pub fn test_opts(config: &config) -> test::TestOpts {
logfile: copy config.logfile,
run_tests: true,
run_benchmarks: false,
save_results: None,
compare_results: None
ratchet_metrics: None,
ratchet_noise_percent: None,
save_metrics: None,
}
}

Expand Down
118 changes: 117 additions & 1 deletion src/compiletest/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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);
}



}

15 changes: 13 additions & 2 deletions src/libextra/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use std::to_str;
use serialize::Encodable;
use serialize;
use sort::Sort;
use treemap::TreeMap;

/// Represents a json value
pub enum Json {
Expand Down Expand Up @@ -1225,7 +1226,7 @@ impl Ord for Json {
}

/// A trait for converting values to JSON
trait ToJson {
pub trait ToJson {
/// Converts the value of `self` to an instance of JSON
fn to_json(&self) -> Json;
}
Expand Down Expand Up @@ -1330,7 +1331,17 @@ impl<A:ToJson> ToJson for ~[A] {
fn to_json(&self) -> Json { List(self.map(|elt| elt.to_json())) }
}

impl<A:ToJson + Copy> ToJson for HashMap<~str, A> {
impl<A:ToJson> ToJson for HashMap<~str, A> {
fn to_json(&self) -> Json {
let mut d = HashMap::new();
for self.iter().advance |(key, value)| {
d.insert(copy *key, value.to_json());
}
Object(~d)
}
}

impl<A:ToJson> ToJson for TreeMap<~str, A> {
fn to_json(&self) -> Json {
let mut d = HashMap::new();
for self.iter().advance |(key, value)| {
Expand Down
Loading