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
This commit is contained in:
parent
d2463960a4
commit
5631585aa6
4 changed files with 255 additions and 1 deletions
|
@ -1,3 +1,11 @@
|
|||
2015-05-06 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* 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 <yvan.roux@linaro.org>
|
||||
|
||||
PR target/64208
|
||||
|
|
|
@ -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". */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
240
gcc/testsuite/jit.dg/test-benchmark.c
Normal file
240
gcc/testsuite/jit.dg/test-benchmark.c
Normal file
|
@ -0,0 +1,240 @@
|
|||
/* A simple benchmark: how long does it take to use libgccjit to
|
||||
compile and run a simple function? */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
#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;
|
||||
}
|
Loading…
Add table
Reference in a new issue