From: David Malcolm Date: Wed, 6 May 2015 20:13:50 +0000 (+0000) Subject: jit: add test-benchmark.c X-Git-Tag: upstream/12.2.0~55224 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5631585aa6c408bcf716e2762cf53c1d25cee066;p=platform%2Fupstream%2Fgcc.git jit: add test-benchmark.c gcc/testsuite/ChangeLog: * jit.dg/harness.h (set_options): Wrap with #ifndef TEST_ESCHEWS_SET_OPTIONS. * jit.dg/jit.exp (is_testcase_meant_to_generate_a_reproducer): Special-case test-benchmark.c as a negative. * jit.dg/test-benchmark.c: New file. From-SVN: r222863 --- diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7c4781c..669efb5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-05-06 David Malcolm + + * jit.dg/harness.h (set_options): Wrap with + #ifndef TEST_ESCHEWS_SET_OPTIONS. + * jit.dg/jit.exp (is_testcase_meant_to_generate_a_reproducer): + Special-case test-benchmark.c as a negative. + * jit.dg/test-benchmark.c: New file. + 2015-05-06 Yvan Roux PR target/64208 diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h index 907da56..6b59fb5 100644 --- a/gcc/testsuite/jit.dg/harness.h +++ b/gcc/testsuite/jit.dg/harness.h @@ -230,6 +230,7 @@ check_string_contains (const char *funcname, test, funcname, name, expected_substring); } +#ifndef TEST_ESCHEWS_SET_OPTIONS static void set_options (gcc_jit_context *ctxt, const char *argv0) { /* Set up options. */ @@ -262,6 +263,7 @@ static void set_options (gcc_jit_context *ctxt, const char *argv0) GCC_JIT_BOOL_OPTION_DUMP_SUMMARY, 0); } +#endif /* #ifndef TEST_ESCHEWS_SET_OPTIONS */ /* Concatenate two strings. The result must be released using "free". */ diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp index d13f6b5..39e37c2 100644 --- a/gcc/testsuite/jit.dg/jit.exp +++ b/gcc/testsuite/jit.dg/jit.exp @@ -308,12 +308,16 @@ verbose "tests: $tests" proc is_testcase_meant_to_generate_a_reproducer {name} { # We expect most testcases to generate a reproducer. # The exceptions are the tutorials (which don't have a "test-" - # prefix), and test-threads.c (which is unique). + # prefix), and test-threads.c and test-benchmark.c (which are each + # unique). verbose "is_testcase_meant_to_generate_a_reproducer: $name" if { [string match "*test-*" $name] } { if { [string match "*test-threads.c" $name] } { return 0 } + if { [string match "*test-benchmark.c" $name] } { + return 0 + } return 1 } return 0 diff --git a/gcc/testsuite/jit.dg/test-benchmark.c b/gcc/testsuite/jit.dg/test-benchmark.c new file mode 100644 index 0000000..324ba93 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-benchmark.c @@ -0,0 +1,240 @@ +/* A simple benchmark: how long does it take to use libgccjit to + compile and run a simple function? */ +#include +#include +#include +#include + +#include "libgccjit.h" + +#define TEST_ESCHEWS_SET_OPTIONS +#define TEST_ESCHEWS_TEST_JIT +#define TEST_PROVIDES_MAIN +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* + Simple sum-of-squares, to test conditionals and looping + + int loop_test (int n) + { + int i; + int sum = 0; + for (i = 0; i < n ; i ++) + { + sum += i * i; + } + return sum; + */ + gcc_jit_type *the_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *return_type = the_type; + + gcc_jit_param *n = + gcc_jit_context_new_param (ctxt, NULL, the_type, "n"); + gcc_jit_param *params[1] = {n}; + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + return_type, + "loop_test", + 1, params, 0); + + /* Build locals: */ + gcc_jit_lvalue *i = + gcc_jit_function_new_local (func, NULL, the_type, "i"); + gcc_jit_lvalue *sum = + gcc_jit_function_new_local (func, NULL, the_type, "sum"); + + gcc_jit_block *initial = + gcc_jit_function_new_block (func, "initial"); + gcc_jit_block *loop_cond = + gcc_jit_function_new_block (func, "loop_cond"); + gcc_jit_block *loop_body = + gcc_jit_function_new_block (func, "loop_body"); + gcc_jit_block *after_loop = + gcc_jit_function_new_block (func, "after_loop"); + + /* sum = 0; */ + gcc_jit_block_add_assignment ( + initial, NULL, + sum, + gcc_jit_context_new_rvalue_from_int (ctxt, the_type, 0)); + + /* i = 0; */ + gcc_jit_block_add_assignment ( + initial, NULL, + i, + gcc_jit_context_new_rvalue_from_int (ctxt, the_type, 0)); + + gcc_jit_block_end_with_jump (initial, NULL, loop_cond); + + /* if (i >= n) */ + gcc_jit_block_end_with_conditional ( + loop_cond, NULL, + gcc_jit_context_new_comparison ( + ctxt, NULL, + GCC_JIT_COMPARISON_GE, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_param_as_rvalue (n)), + after_loop, + loop_body); + + /* sum += i * i */ + gcc_jit_block_add_assignment ( + loop_body, NULL, + sum, + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_PLUS, the_type, + gcc_jit_lvalue_as_rvalue (sum), + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_MULT, the_type, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_lvalue_as_rvalue (i)))); + + /* i++ */ + gcc_jit_block_add_assignment ( + loop_body, NULL, + i, + gcc_jit_context_new_binary_op ( + ctxt, NULL, + GCC_JIT_BINARY_OP_PLUS, the_type, + gcc_jit_lvalue_as_rvalue (i), + gcc_jit_context_new_rvalue_from_int ( + ctxt, + the_type, + 1))); + + gcc_jit_block_end_with_jump (loop_body, NULL, loop_cond); + + /* return sum */ + gcc_jit_block_end_with_return ( + after_loop, + NULL, + gcc_jit_lvalue_as_rvalue (sum)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + typedef int (*loop_test_fn_type) (int); + if (!result) + { + fail ("%s: %s: !result", test, __func__); + return; + } + loop_test_fn_type loop_test = + (loop_test_fn_type)gcc_jit_result_get_code (result, "loop_test"); + if (!loop_test) + { + fail ("%s: %s: !loop_test", test, __func__); + return; + } + int val = loop_test (100); + if (val != 328350) + fail ("%s: %s: val != 328350", test, __func__); +} + +/* Run one iteration of the test. */ +static void +test_jit (const char *argv0, int opt_level) +{ + gcc_jit_context *ctxt; + gcc_jit_result *result; + + ctxt = gcc_jit_context_acquire (); + if (!ctxt) + { + fail ("gcc_jit_context_acquire failed"); + return; + } + + /* Set up options. */ + gcc_jit_context_set_str_option ( + ctxt, + GCC_JIT_STR_OPTION_PROGNAME, + argv0); + + /* Set up options for benchmarking. */ + gcc_jit_context_set_int_option ( + ctxt, + GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL, + opt_level); + /* Generating debuginfo takes time; turn it off. */ + gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DEBUGINFO, + 0); + /* This option is extremely slow; turn it off. */ + gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_SELFCHECK_GC, + 0); + + /* Turn this on to get detailed timings. */ + if (0) + gcc_jit_context_set_bool_option ( + ctxt, + GCC_JIT_BOOL_OPTION_DUMP_SUMMARY, + 1); + + create_code (ctxt, NULL); + + result = gcc_jit_context_compile (ctxt); + verify_code (ctxt, result); + + gcc_jit_context_release (ctxt); + gcc_jit_result_release (result); +} + +/* Taken from timevar.c. */ +static double ticks_to_msec; +#define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */ +#define TICKS_TO_MSEC (1 / (double)TICKS_PER_SECOND) +static double get_wallclock_time (void) +{ + struct tms tms; + return times (&tms) * ticks_to_msec; +} + +/* Time 100 iterations, at each optimization level + (for 400 iterations in all). */ + +int +main (int argc, char **argv) +{ + int opt_level; + int num_iterations = 100; + + ticks_to_msec = TICKS_TO_MSEC; + + for (opt_level = 0; opt_level < 4; opt_level++) + { + int i; + double start_time, end_time, elapsed_time; + start_time = get_wallclock_time (); + for (i = 1; i <= num_iterations; i++) + { + snprintf (test, sizeof (test), + "%s iteration %d of %d", + extract_progname (argv[0]), + i, num_iterations); + test_jit (argv[0], opt_level); + } + end_time = get_wallclock_time (); + elapsed_time = end_time - start_time; + pass ("%s: survived %i iterations at optlevel %i", + argv[0], num_iterations, opt_level); + note (("%s: %i iterations at optlevel %i" + " took a total of %.3fs (%.3fs per iteration)"), + argv[0], num_iterations, opt_level, + elapsed_time, elapsed_time / num_iterations); + } + totals (); + + return 0; +}