Accept output arguments to benchmark functions

This patch adds the ability to accept output arguments to functions
being benchmarked, by nesting the argument type in <> in the args
directive.  It includes the sincos implementation as an example, where
the function would have the following args directive:

  ## args: double:<double *>:<double *>

This simply adds a definition for a static variable whose pointer gets
passed into the function, so it's not yet possible to pass something
more complicated like a pre-allocated string or array.  That would be
a good feature to add if a function needs it.

The values in the input file will map only to the input arguments.  So
if I had a directive like this for a function foo:

  ## args: int:<int *>:int:<int *>

and I have a value list like this:

1, 2
3, 4
5, 6

then the function calls generated would be:

foo (1, &out1, 2, &out2);
foo (3, &out1, 4, &out2);
foo (5, &out1, 6, &out2);
This commit is contained in:
Siddhesh Poyarekar 2013-12-05 10:12:59 +05:30
parent 232983e9a7
commit 9298ecba15
5 changed files with 56 additions and 91 deletions

View File

@ -1,5 +1,11 @@
2013-12-05 Siddhesh Poyarekar <siddhesh@redhat.com>
* benchtests/README: Add note about output arguments.
* benchtests/bench-sincos.c: Remove file.
* benchtests/sincos-inputs: New file.
* scripts/bench.pl: Identify output arguments and define
static variables for them.
* debug/stpncpy_chk.c (__stpncpy_chk): Remove unused variables.
[BZ #15941]

View File

@ -48,7 +48,8 @@ one to add `foo' to the bench tests:
- args: This should be assigned a colon separated list of types of the input
arguments. This directive may be skipped if the function does not take any
inputs.
inputs. One may identify output arguments by nesting them in <>. The
generator will create variables to get outputs from the calling function.
- ret: This should be assigned the type that the function returns. This
directive may be skipped if the function does not return a value.
- includes: This should be assigned a comma-separated list of headers that

View File

@ -1,86 +0,0 @@
/* Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
extern void sincos (double, double *, double *);
#define CALL_BENCH_FUNC(v, i, j, k) sincos ( variants[v].in[i].arg0, &j, &k);
struct args
{
volatile double arg0;
};
struct args in0[12] =
{
{ 0.9 },
{ 2.3 },
{ 3.7 },
{ 3.9 },
{ 4.0 },
{ 4.7 },
{ 5.9 },
{ 0x1.000000cf4a2a1p0 },
{ 0x1.0000010b239a8p0 },
{ 0x1.00000162a932ap0 },
{ 0x1.000002d452a11p0 },
{ 0x1.000005bc7d86cp0 }
};
struct args in1[12] =
{
{ 0.93340582292648832662962377071381 },
{ 2.3328432680770916363144351635128 },
{ 3.7439477503636453548097051680088 },
{ 3.9225160069792437411706487182528 },
{ 4.0711651639931289992091478779912 },
{ 4.7858438478542097982426639646292 },
{ 5.9840767662578002727968851104379 },
{ 0x1.000000cf4a2a2p0 },
{ 0x1.0000010b239a9p0 },
{ 0x1.00000162a932bp0 },
{ 0x1.000002d452a10p0 },
{ 0x1.000005bc7d86dp0 }
};
struct _variants
{
const char *name;
int count;
struct args *in;
};
struct _variants variants[2] =
{
{"sincos()", 12, in0},
{"sincos(768bits)", 12, in1},
};
#define NUM_VARIANTS 2
#define NUM_SAMPLES(i) (variants[i].count)
#define VARIANT(i) (variants[i].name)
#define BENCH_FUNC(v, j) \
({ \
volatile double iptr; \
volatile double iptr2; \
CALL_BENCH_FUNC (v, j, iptr, iptr2); \
})
#define FUNCNAME "sincos"
#include "bench-skeleton.c"

27
benchtests/sincos-inputs Normal file
View File

@ -0,0 +1,27 @@
## includes: math.h
## args: double:<double *>:<double *>
0.9
2.3
3.7
3.9
4.0
4.7
5.9
0x1.000000cf4a2a1p0
0x1.0000010b239a8p0
0x1.00000162a932ap0
0x1.000002d452a11p0
0x1.000005bc7d86cp0
## name: 768bits
0.93340582292648832662962377071381
2.3328432680770916363144351635128
3.7439477503636453548097051680088
3.9225160069792437411706487182528
4.0711651639931289992091478779912
4.7858438478542097982426639646292
5.9840767662578002727968851104379
0x1.000000cf4a2a2p0
0x1.0000010b239a9p0
0x1.00000162a932bp0
0x1.000002d452a10p0
0x1.000005bc7d86dp0

View File

@ -93,6 +93,13 @@ LINE:while (<INPUTS>) {
my $bench_func = "#define CALL_BENCH_FUNC(v, i) $func (";
# Output variables. These include the return value as well as any pointers
# that may get passed into the function, denoted by the <> around the type.
my $outvars = "";
if ($ret ne "void") {
$outvars = "static volatile $ret ret;\n";
}
# Print the definitions and macros.
foreach $incl (@include_headers) {
@ -124,8 +131,18 @@ if (@args > 0) {
$bench_func = "$bench_func,";
}
$_ = $arg;
if (/<(.*)\*>/) {
# Output variables. These have to be pointers, so dereference once by
# dropping one *.
$outvars = $outvars . "static $1 out$num;\n";
$bench_func = "$bench_func &out$num";
}
else {
$arg_struct = "$arg_struct volatile $arg arg$num;";
$bench_func = "$bench_func variants[v].in[i].arg$num";
}
$num = $num + 1;
}
@ -172,12 +189,12 @@ else {
print "#define VARIANT(v) FUNCNAME \"()\"\n"
}
# Print the output variable definitions.
print "$outvars\n";
# In some cases not storing a return value seems to result in the function call
# being optimized out.
if ($ret ne "void") {
print "static volatile $ret ret;\n";
$getret = "ret = ";
}