PR jit/66628: add gcc_jit_context_add_command_line_option

gcc/jit/ChangeLog:
	PR jit/66628
	* docs/cp/topics/contexts.rst (Additional command-line options):
	New section.
	* docs/topics/compatibility.rst: New file.
	* docs/topics/contexts.rst (Additional command-line options): New
	section.
	* docs/topics/index.rst: Add compatibility.rst.
	* docs/_build/texinfo/libgccjit.texi: Regenerate.
	* jit-playback.c (make_fake_args): Add call to
	append_command_line_options.
	* jit-recording.c: Within namespace gcc::jit...
	(recording::context::~context): Free the optnames within
	m_command_line_options.
	(recording::context::set_bool_option): Likewise.
	(recording::context::add_command_line_option): New method.
	(recording::context::append_command_line_options): New method.
	(recording::context::dump_reproducer_to_file): Add command-line
	options.
	* jit-recording.h: Within namespace gcc::jit...
	(recording::context::add_command_line_option): New method.
	(recording::context::append_command_line_options): New method.
	(recording::context::m_command_line_options): New field.
	* libgccjit++.h (gccjit::context::add_command_line_option): New
	method.
	* libgccjit.c (gcc_jit_context_add_command_line_option): New API
	entrypoint.
	* libgccjit.h (gcc_jit_context_add_command_line_option): New API
	entrypoint.
	(LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option): New
	macro.
	* libgccjit.map: Put existing symbols within LIBGCCJIT_ABI_0; add
	LIBGCCJIT_ABI_1 and gcc_jit_context_add_command_line_option.

gcc/testsuite/ChangeLog:
	PR jit/66628
	* jit.dg/all-non-failing-tests.h: Add note about
	test-extra-options.c.
	* jit.dg/test-extra-options.c: New testcase.

From-SVN: r225205
This commit is contained in:
David Malcolm 2015-06-30 19:27:19 +00:00 committed by David Malcolm
parent a6314e15e0
commit fa22c20d5a
16 changed files with 1047 additions and 394 deletions

View File

@ -1,3 +1,38 @@
2015-06-30 David Malcolm <dmalcolm@redhat.com>
PR jit/66628
* docs/cp/topics/contexts.rst (Additional command-line options):
New section.
* docs/topics/compatibility.rst: New file.
* docs/topics/contexts.rst (Additional command-line options): New
section.
* docs/topics/index.rst: Add compatibility.rst.
* docs/_build/texinfo/libgccjit.texi: Regenerate.
* jit-playback.c (make_fake_args): Add call to
append_command_line_options.
* jit-recording.c: Within namespace gcc::jit...
(recording::context::~context): Free the optnames within
m_command_line_options.
(recording::context::set_bool_option): Likewise.
(recording::context::add_command_line_option): New method.
(recording::context::append_command_line_options): New method.
(recording::context::dump_reproducer_to_file): Add command-line
options.
* jit-recording.h: Within namespace gcc::jit...
(recording::context::add_command_line_option): New method.
(recording::context::append_command_line_options): New method.
(recording::context::m_command_line_options): New field.
* libgccjit++.h (gccjit::context::add_command_line_option): New
method.
* libgccjit.c (gcc_jit_context_add_command_line_option): New API
entrypoint.
* libgccjit.h (gcc_jit_context_add_command_line_option): New API
entrypoint.
(LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option): New
macro.
* libgccjit.map: Put existing symbols within LIBGCCJIT_ABI_0; add
LIBGCCJIT_ABI_1 and gcc_jit_context_add_command_line_option.
2015-06-30 David Malcolm <dmalcolm@redhat.com>
* jit-recording.c

File diff suppressed because it is too large Load Diff

View File

@ -196,3 +196,22 @@ Integer options
This is a thin wrapper around the C API
:c:func:`gcc_jit_context_set_int_option`; the options have the same
meaning.
Additional command-line options
*******************************
.. function:: void \
gccjit::context::add_command_line_option (const char *optname)
Add an arbitrary gcc command-line option to the context for use
when compiling.
This is a thin wrapper around the C API
:c:func:`gcc_jit_context_add_command_line_option`.
This entrypoint was added in :ref:`LIBGCCJIT_ABI_1`; you can test for
its presence using
.. code-block:: c
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option

View File

@ -0,0 +1,90 @@
.. Copyright (C) 2015 Free Software Foundation, Inc.
Originally contributed by David Malcolm <dmalcolm@redhat.com>
This is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program 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
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see
<http://www.gnu.org/licenses/>.
.. default-domain:: c
ABI and API compatibility
=========================
The libgccjit developers strive for ABI and API backward-compatibility:
programs built against libgccjit.so stand a good chance of running
without recompilation against newer versions of libgccjit.so, and
ought to recompile without modification against newer versions of
libgccjit.h.
.. note:: The libgccjit++.h C++ API is more experimental, and less
locked-down at this time.
API compatibility is achieved by extending the API rather than changing
it. For ABI compatiblity, we avoid bumping the SONAME, and instead use
symbol versioning to tag each symbol, so that a binary linked against
libgccjit.so is tagged according to the symbols that it uses.
For example, :func:`gcc_jit_context_add_command_line_option` was added in
``LIBGCCJIT_ABI_1``. If a client program uses it, this can be detected
from metadata by using ``objdump``:
.. code-block:: bash
$ objdump -p testsuite/jit/test-extra-options.c.exe | tail -n 8
Version References:
required from libgccjit.so.0:
0x00824161 0x00 04 LIBGCCJIT_ABI_1
0x00824160 0x00 03 LIBGCCJIT_ABI_0
required from libc.so.6:
0x09691a75 0x00 02 GLIBC_2.2.5
You can see the symbol tags provided by libgccjit.so using ``objdump``:
.. code-block:: bash
$ objdump -p libgccjit.so | less
[...snip...]
Version definitions:
1 0x01 0x0ff81f20 libgccjit.so.0
2 0x00 0x00824160 LIBGCCJIT_ABI_0
3 0x00 0x00824161 LIBGCCJIT_ABI_1
LIBGCCJIT_ABI_0
[...snip...]
ABI symbol tags
***************
The initial release of libgccjit (in gcc 5.1) did not use symbol versioning.
Newer releases use the following tags.
.. _LIBGCCJIT_ABI_0:
``LIBGCCJIT_ABI_0``
-------------------
All entrypoints in the initial release of libgccjit are tagged with
``LIBGCCJIT_ABI_0``, to signify the transition to symbol versioning.
Binaries built against older copies of ``libgccjit.so`` should
continue to work, with this being handled transparently by the linker
(see `this post
<https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html>`_)
.. _LIBGCCJIT_ABI_1:
``LIBGCCJIT_ABI_1``
-------------------
``LIBGCCJIT_ABI_1`` covers the addition of
:func:`gcc_jit_context_add_command_line_option`

View File

@ -462,3 +462,39 @@ Integer options
-O0 through -O3.
The default value is 0 (unoptimized).
Additional command-line options
*******************************
.. function:: void gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,\
const char *optname)
Add an arbitrary gcc command-line option to the context, for use
by :func:`gcc_jit_context_compile` and
:func:`gcc_jit_context_compile_to_file`.
The parameter ``optname`` must be non-NULL. The underlying buffer is
copied, so that it does not need to outlive the call.
Extra options added by `gcc_jit_context_add_command_line_option` are
applied *after* the regular options above, potentially overriding them.
Options from parent contexts are inherited by child contexts; options
from the parent are applied *before* those from the child.
For example:
.. code-block:: c
gcc_jit_context_add_command_line_option (ctxt, "-ffast-math");
gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm");
Note that only some options are likely to be meaningful; there is no
"frontend" within libgccjit, so typically only those affecting
optimization and code-generation are likely to be useful.
This entrypoint was added in :ref:`LIBGCCJIT_ABI_1`; you can test for
its presence using
.. code-block:: c
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option

View File

@ -28,3 +28,4 @@ Topic Reference
functions.rst
locations.rst
compilation.rst
compatibility.rst

View File

@ -2139,6 +2139,10 @@ make_fake_args (vec <char *> *argvec,
}
}
/* Add any user-provided extra options, starting with any from
parent contexts. */
m_recording_ctxt->append_command_line_options (argvec);
#undef ADD_ARG
#undef ADD_ARG_TAKE_OWNERSHIP
}

View File

@ -517,6 +517,10 @@ recording::context::~context ()
for (i = 0; i < GCC_JIT_NUM_STR_OPTIONS; ++i)
free (m_str_options[i]);
char *optname;
FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
free (optname);
if (m_builtins_manager)
delete m_builtins_manager;
@ -1137,6 +1141,33 @@ recording::context::set_bool_option (enum gcc_jit_bool_option opt,
log_bool_option (opt);
}
/* Add the given optname to this context's list of extra options.
Implements the post-error-checking part of
gcc_jit_context_add_command_line_option. */
void
recording::context::add_command_line_option (const char *optname)
{
m_command_line_options.safe_push (xstrdup (optname));
}
/* Add any user-provided extra options, starting with any from
parent contexts.
Called by playback::context::make_fake_args. */
void
recording::context::append_command_line_options (vec <char *> *argvec)
{
if (m_parent_ctxt)
m_parent_ctxt->append_command_line_options (argvec);
int i;
char *optname;
FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
argvec->safe_push (xstrdup (optname));
}
/* Add the given dumpname/out_ptr pair to this context's list of requested
dumps.
@ -1593,6 +1624,17 @@ recording::context::dump_reproducer_to_file (const char *path)
bool_option_reproducer_strings[opt_idx],
m_bool_options[opt_idx]);
if (!m_command_line_options.is_empty ())
{
int i;
char *optname;
r.write (" /* User-provided command-line options. */\n");
FOR_EACH_VEC_ELT (m_command_line_options, i, optname)
r.write (" gcc_jit_context_add_command_line_option (%s, \"%s\");\n",
r.get_identifier (contexts[ctxt_idx]),
optname);
}
if (m_requested_dumps.length ())
{
r.write (" /* Requested dumps. */\n");

View File

@ -195,6 +195,12 @@ public:
set_bool_option (enum gcc_jit_bool_option opt,
int value);
void
add_command_line_option (const char *optname);
void
append_command_line_options (vec <char *> *argvec);
void
enable_dump (const char *dumpname,
char **out_ptr);
@ -281,6 +287,7 @@ private:
char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
auto_vec <char *> m_command_line_options;
/* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
auto_vec<requested_dump> m_requested_dumps;

View File

@ -120,6 +120,8 @@ namespace gccjit
void set_bool_option (enum gcc_jit_bool_option opt,
int value);
void add_command_line_option (const char *optname);
location
new_location (const std::string &filename,
int line,
@ -603,6 +605,12 @@ context::set_bool_option (enum gcc_jit_bool_option opt,
}
inline void
context::add_command_line_option (const char *optname)
{
gcc_jit_context_add_command_line_option (m_inner_ctxt, optname);
}
inline location
context::new_location (const std::string &filename,
int line,

View File

@ -2182,6 +2182,25 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
ctxt->set_bool_option (opt, value);
}
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the
gcc::jit::recording::context::add_command_line_option method in
jit-recording.c. */
void
gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
const char *optname)
{
RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
JIT_LOG_FUNC (ctxt->get_logger ());
RETURN_IF_FAIL (optname, ctxt, NULL, "NULL optname");
if (ctxt->get_logger ())
ctxt->get_logger ()->log ("optname: %s", optname);
ctxt->add_command_line_option (optname);
}
/* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the

View File

@ -243,6 +243,29 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
enum gcc_jit_bool_option opt,
int value);
/* Add an arbitrary gcc command-line option to the context.
The context takes a copy of the string, so the
(const char *) optname is not needed anymore after the call
returns.
Note that only some options are likely to be meaningful; there is no
"frontend" within libgccjit, so typically only those affecting
optimization and code-generation are likely to be useful.
This entrypoint was added in LIBGCCJIT_ABI_1; you can test for
its presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
*/
extern void
gcc_jit_context_add_command_line_option (gcc_jit_context *ctxt,
const char *optname);
/* Pre-canned feature-test macro for detecting the presence of
gcc_jit_context_add_command_line_option within libgccjit.h. */
#define LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
/* Compile the context to in-memory machine code.
This can be called more that once on a given context,

View File

@ -17,6 +17,9 @@
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>. */
# The initial release of the library.
LIBGCCJIT_ABI_0
{
global:
# Keep this list sorted alphabetically:
@ -104,4 +107,10 @@
gcc_jit_type_get_volatile;
local: *;
};
};
# Add support for adding arbitrary command-line options (PR jit/66628).
LIBGCCJIT_ABI_1 {
global:
gcc_jit_context_add_command_line_option;
} LIBGCCJIT_ABI_0;

View File

@ -1,3 +1,10 @@
2015-06-30 David Malcolm <dmalcolm@redhat.com>
PR jit/66628
* jit.dg/all-non-failing-tests.h: Add note about
test-extra-options.c.
* jit.dg/test-extra-options.c: New testcase.
2015-06-30 Vladimir Makarov <vmakarov@redhat.com>
PR debug/66691

View File

@ -95,6 +95,9 @@
#undef create_code
#undef verify_code
/* test-extra-options.c: We don't use this one, since the extra options
affect the whole context. */
/* test-factorial.c */
#define create_code create_code_factorial
#define verify_code verify_code_factorial

View File

@ -0,0 +1,136 @@
/* Testcase for gcc_jit_context_add_command_line_option (PR jit/66628). */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "libgccjit.h"
#include "harness.h"
#ifndef LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option
#error LIBGCCJIT_HAVE_gcc_jit_context_add_command_line_option was not defined
#endif
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
gcc_jit_context_add_command_line_option (ctxt, "-ffast-math");
gcc_jit_context_add_command_line_option (ctxt, "-fverbose-asm");
/* Let's try to inject the equivalent of:
double
my_dot_product (int n, double *a, double *b)
{
double result = 0.;
for (int i = 0; i < n; i++)
result += a[i] * b[i];
return result
}
and see what the optimizer can do. */
gcc_jit_type *val_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
gcc_jit_type *ptr_type = gcc_jit_type_get_pointer (val_type);
gcc_jit_type *int_type =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
gcc_jit_type *return_type = val_type;
gcc_jit_param *param_n =
gcc_jit_context_new_param (ctxt, NULL, int_type, "n");
gcc_jit_param *param_a =
gcc_jit_context_new_param (ctxt, NULL, ptr_type, "a");
gcc_jit_param *param_b =
gcc_jit_context_new_param (ctxt, NULL, ptr_type, "b");
gcc_jit_param *params[3] = {param_n, param_a, param_b};
gcc_jit_function *func =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_EXPORTED,
return_type,
"my_dot_product",
3, params, 0);
gcc_jit_block *initial = gcc_jit_function_new_block (func, "initial");
gcc_jit_block *loop_test = gcc_jit_function_new_block (func, "loop_test");
gcc_jit_block *loop_body = gcc_jit_function_new_block (func, "loop_body");
gcc_jit_block *final = gcc_jit_function_new_block (func, "final");
/* Build: "double result = 0.;" */
gcc_jit_lvalue *result =
gcc_jit_function_new_local (func, NULL, val_type, "result");
gcc_jit_block_add_assignment (initial, NULL,
result, gcc_jit_context_zero (ctxt, val_type));
/* Build: "for (int i = 0; i < n; i++)" */
gcc_jit_lvalue *i =
gcc_jit_function_new_local (func, NULL, int_type, "i");
gcc_jit_block_add_assignment (initial, NULL,
i, gcc_jit_context_zero (ctxt, int_type));
gcc_jit_block_end_with_jump (initial, NULL, loop_test);
gcc_jit_block_end_with_conditional (
loop_test, NULL,
/* (i < n) */
gcc_jit_context_new_comparison (
ctxt, NULL,
GCC_JIT_COMPARISON_LT,
gcc_jit_lvalue_as_rvalue (i),
gcc_jit_param_as_rvalue (param_n)),
loop_body,
final);
/* Build: "result += a[i] * b[i];" */
gcc_jit_block_add_assignment_op (
loop_body, NULL,
result,
GCC_JIT_BINARY_OP_PLUS,
gcc_jit_context_new_binary_op (
ctxt, NULL,
GCC_JIT_BINARY_OP_MULT,
val_type,
gcc_jit_lvalue_as_rvalue (
gcc_jit_context_new_array_access (
ctxt, NULL,
gcc_jit_param_as_rvalue (param_a),
gcc_jit_lvalue_as_rvalue (i))),
gcc_jit_lvalue_as_rvalue (
gcc_jit_context_new_array_access (
ctxt, NULL,
gcc_jit_param_as_rvalue (param_b),
gcc_jit_lvalue_as_rvalue (i)))));
/* Build: "i++" */
gcc_jit_block_add_assignment_op (
loop_body, NULL,
i,
GCC_JIT_BINARY_OP_PLUS,
gcc_jit_context_one (ctxt, int_type));
gcc_jit_block_end_with_jump (loop_body, NULL, loop_test);
/* Build: "return result;" */
gcc_jit_block_end_with_return (
final,
NULL,
gcc_jit_lvalue_as_rvalue (result));
}
void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
typedef double (*my_dot_product_fn_type) (int n, double *a, double *b);
CHECK_NON_NULL (result);
my_dot_product_fn_type my_dot_product =
(my_dot_product_fn_type)gcc_jit_result_get_code (result,
"my_dot_product");
CHECK_NON_NULL (my_dot_product);
double test_array[] = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.};
double val = my_dot_product (10, test_array, test_array);
note ("my_dot_product returned: %f", val);
CHECK_VALUE (val, 385.0);
}