Commit 6a3603e3 by David Malcolm Committed by David Malcolm

PR jit/66546: Add gcc_jit_context_set_bool_allow_unreachable_blocks

gcc/jit/ChangeLog:
	PR jit/66546
	* docs/cp/topics/contexts.rst
	(gccjit::context::set_bool_allow_unreachable_blocks): New.
	* docs/topics/compatibility.rst (LIBGCCJIT_ABI_2): New.
	* docs/topics/contexts.rst (Options): Add notes discussing the
	transition from enums to entrypoints for new options.
	(gcc_jit_context_set_bool_allow_unreachable_blocks): New.
	* docs/_build/texinfo/libgccjit.texi: Regenerate.
	* jit-common.h (gcc::jit::inner_bool_option): New enum.
	* jit-recording.c: Within namespace gcc::jit...
	(recording::context::context): Handle m_inner_bool_options.
	(recording::context::set_inner_bool_option): New.
	(inner_bool_option_reproducer_strings): New.
	(recording::context::log_all_options): Log the "inner" bool
	options.
	(recording::context::log_inner_bool_option): New.
	(recording::context::dump_reproducer_to_file): Write initializers
	for "inner" bool options.
	(recording::function::validate): Don't check for block
	reachability if INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS is set.
	* jit-recording.h: Within namespace gcc::jit...
	(recording::context::set_inner_bool_option): New.
	(recording::context::get_inner_bool_option): New.
	(recording::context::log_inner_bool_option): New.
	(recording::context::m_inner_bool_options): New.
	* libgccjit++.h
	(gccjit::context::set_bool_allow_unreachable_blocks): New.
	* libgccjit.c
	(gcc_jit_context_set_bool_allow_unreachable_blocks): New.
	* libgccjit.h: Add note about options present in the
	initial release of libgccjit.
	(gcc_jit_context_set_bool_allow_unreachable_blocks): New API
	entrypoint.
	(LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks):
	New macro.
	* libgccjit.map (LIBGCCJIT_ABI_2): New, containing...
	(gcc_jit_context_set_bool_allow_unreachable_blocks): ...this new
	entrypoint.

gcc/testsuite/ChangeLog:
	PR jit/66546
	* jit.dg/all-non-failing-tests.h: Add note about
	test-validly-unreachable-block.c.
	* jit.dg/test-validly-unreachable-block.c: New file.

From-SVN: r225206
parent fa22c20d
2015-06-30 David Malcolm <dmalcolm@redhat.com> 2015-06-30 David Malcolm <dmalcolm@redhat.com>
PR jit/66546
* docs/cp/topics/contexts.rst
(gccjit::context::set_bool_allow_unreachable_blocks): New.
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_2): New.
* docs/topics/contexts.rst (Options): Add notes discussing the
transition from enums to entrypoints for new options.
(gcc_jit_context_set_bool_allow_unreachable_blocks): New.
* docs/_build/texinfo/libgccjit.texi: Regenerate.
* jit-common.h (gcc::jit::inner_bool_option): New enum.
* jit-recording.c: Within namespace gcc::jit...
(recording::context::context): Handle m_inner_bool_options.
(recording::context::set_inner_bool_option): New.
(inner_bool_option_reproducer_strings): New.
(recording::context::log_all_options): Log the "inner" bool
options.
(recording::context::log_inner_bool_option): New.
(recording::context::dump_reproducer_to_file): Write initializers
for "inner" bool options.
(recording::function::validate): Don't check for block
reachability if INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS is set.
* jit-recording.h: Within namespace gcc::jit...
(recording::context::set_inner_bool_option): New.
(recording::context::get_inner_bool_option): New.
(recording::context::log_inner_bool_option): New.
(recording::context::m_inner_bool_options): New.
* libgccjit++.h
(gccjit::context::set_bool_allow_unreachable_blocks): New.
* libgccjit.c
(gcc_jit_context_set_bool_allow_unreachable_blocks): New.
* libgccjit.h: Add note about options present in the
initial release of libgccjit.
(gcc_jit_context_set_bool_allow_unreachable_blocks): New API
entrypoint.
(LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks):
New macro.
* libgccjit.map (LIBGCCJIT_ABI_2): New, containing...
(gcc_jit_context_set_bool_allow_unreachable_blocks): ...this new
entrypoint.
2015-06-30 David Malcolm <dmalcolm@redhat.com>
PR jit/66628 PR jit/66628
* docs/cp/topics/contexts.rst (Additional command-line options): * docs/cp/topics/contexts.rst (Additional command-line options):
New section. New section.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -184,6 +184,23 @@ Boolean options ...@@ -184,6 +184,23 @@ Boolean options
:c:func:`gcc_jit_context_set_bool_option`; the options have the same :c:func:`gcc_jit_context_set_bool_option`; the options have the same
meaning. meaning.
.. function:: void \
gccjit::context::set_bool_allow_unreachable_blocks (int bool_value)
By default, libgccjit will issue an error about unreachable blocks
within a function.
This entrypoint can be used to disable that error; it is a thin wrapper
around the C API
:c:func:`gcc_jit_context_set_bool_allow_unreachable_blocks`.
This entrypoint was added in :ref:`LIBGCCJIT_ABI_2`; you can test for
its presence using
.. code-block:: c
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
Integer options Integer options
*************** ***************
......
...@@ -88,3 +88,10 @@ continue to work, with this being handled transparently by the linker ...@@ -88,3 +88,10 @@ continue to work, with this being handled transparently by the linker
------------------- -------------------
``LIBGCCJIT_ABI_1`` covers the addition of ``LIBGCCJIT_ABI_1`` covers the addition of
:func:`gcc_jit_context_add_command_line_option` :func:`gcc_jit_context_add_command_line_option`
.. _LIBGCCJIT_ABI_2:
``LIBGCCJIT_ABI_2``
-------------------
``LIBGCCJIT_ABI_2`` covers the addition of
:func:`gcc_jit_context_set_bool_allow_unreachable_blocks`
...@@ -293,6 +293,15 @@ future activies on a context to the given `FILE *`. ...@@ -293,6 +293,15 @@ future activies on a context to the given `FILE *`.
Options Options
------- -------
Options present in the initial release of libgccjit were handled using
enums, whereas those added subsequently have their own per-option API
entrypoints.
Adding entrypoints for each new option means that client code that use
the new options can be identified directly from binary metadata, which
would not be possible if we instead extended the various
``enum gcc_jit_*_option``.
String Options String Options
************** **************
...@@ -304,7 +313,7 @@ String Options ...@@ -304,7 +313,7 @@ String Options
.. type:: enum gcc_jit_str_option .. type:: enum gcc_jit_str_option
There is currently just one string option: There is just one string option specified this way:
.. macro:: GCC_JIT_STR_OPTION_PROGNAME .. macro:: GCC_JIT_STR_OPTION_PROGNAME
...@@ -441,6 +450,22 @@ Boolean options ...@@ -441,6 +450,22 @@ Boolean options
If true, the :type:`gcc_jit_context` will not clean up intermediate files If true, the :type:`gcc_jit_context` will not clean up intermediate files
written to the filesystem, and will display their location on stderr. written to the filesystem, and will display their location on stderr.
.. function:: void \
gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt, \
int bool_value)
By default, libgccjit will issue an error about unreachable blocks
within a function.
This entrypoint can be used to disable that error.
This entrypoint was added in :ref:`LIBGCCJIT_ABI_2`; you can test for
its presence using
.. code-block:: c
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
Integer options Integer options
*************** ***************
...@@ -452,7 +477,7 @@ Integer options ...@@ -452,7 +477,7 @@ Integer options
.. type:: enum gcc_jit_int_option .. type:: enum gcc_jit_int_option
There is currently just one integer option: There is just one integer option specified this way:
.. macro:: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL .. macro:: GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL
......
...@@ -185,6 +185,16 @@ private: ...@@ -185,6 +185,16 @@ private:
FILE *m_file; FILE *m_file;
}; };
/* A hidden enum of boolean options that are only exposed via API
entrypoints, rather than via gcc_jit_context_set_bool_option. */
enum inner_bool_option
{
INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS,
NUM_INNER_BOOL_OPTIONS
};
} // namespace gcc::jit } // namespace gcc::jit
} // namespace gcc } // namespace gcc
......
...@@ -489,6 +489,9 @@ recording::context::context (context *parent_ctxt) ...@@ -489,6 +489,9 @@ recording::context::context (context *parent_ctxt)
memcpy (m_bool_options, memcpy (m_bool_options,
parent_ctxt->m_bool_options, parent_ctxt->m_bool_options,
sizeof (m_bool_options)); sizeof (m_bool_options));
memcpy (m_inner_bool_options,
parent_ctxt->m_inner_bool_options,
sizeof (m_inner_bool_options));
set_logger (parent_ctxt->get_logger ()); set_logger (parent_ctxt->get_logger ());
} }
else else
...@@ -496,6 +499,7 @@ recording::context::context (context *parent_ctxt) ...@@ -496,6 +499,7 @@ recording::context::context (context *parent_ctxt)
memset (m_str_options, 0, sizeof (m_str_options)); memset (m_str_options, 0, sizeof (m_str_options));
memset (m_int_options, 0, sizeof (m_int_options)); memset (m_int_options, 0, sizeof (m_int_options));
memset (m_bool_options, 0, sizeof (m_bool_options)); memset (m_bool_options, 0, sizeof (m_bool_options));
memset (m_inner_bool_options, 0, sizeof (m_inner_bool_options));
} }
memset (m_basic_types, 0, sizeof (m_basic_types)); memset (m_basic_types, 0, sizeof (m_basic_types));
...@@ -1141,6 +1145,16 @@ recording::context::set_bool_option (enum gcc_jit_bool_option opt, ...@@ -1141,6 +1145,16 @@ recording::context::set_bool_option (enum gcc_jit_bool_option opt,
log_bool_option (opt); log_bool_option (opt);
} }
void
recording::context::set_inner_bool_option (enum inner_bool_option inner_opt,
int value)
{
gcc_assert (inner_opt >= 0 && inner_opt < NUM_INNER_BOOL_OPTIONS);
m_inner_bool_options[inner_opt] = value ? true : false;
log_inner_bool_option (inner_opt);
}
/* Add the given optname to this context's list of extra options. /* Add the given optname to this context's list of extra options.
Implements the post-error-checking part of Implements the post-error-checking part of
...@@ -1418,6 +1432,10 @@ static const char * const ...@@ -1418,6 +1432,10 @@ static const char * const
"GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES" "GCC_JIT_BOOL_OPTION_KEEP_INTERMEDIATES"
}; };
static const char * const
inner_bool_option_reproducer_strings[NUM_INNER_BOOL_OPTIONS] = {
"gcc_jit_context_set_bool_allow_unreachable_blocks"
};
/* Write the current value of all options to the log file (if any). */ /* Write the current value of all options to the log file (if any). */
...@@ -1437,6 +1455,8 @@ recording::context::log_all_options () const ...@@ -1437,6 +1455,8 @@ recording::context::log_all_options () const
for (opt_idx = 0; opt_idx < GCC_JIT_NUM_BOOL_OPTIONS; opt_idx++) for (opt_idx = 0; opt_idx < GCC_JIT_NUM_BOOL_OPTIONS; opt_idx++)
log_bool_option ((enum gcc_jit_bool_option)opt_idx); log_bool_option ((enum gcc_jit_bool_option)opt_idx);
for (opt_idx = 0; opt_idx < NUM_INNER_BOOL_OPTIONS; opt_idx++)
log_inner_bool_option ((enum inner_bool_option)opt_idx);
} }
/* Write the current value of the given string option to the /* Write the current value of the given string option to the
...@@ -1484,6 +1504,19 @@ recording::context::log_bool_option (enum gcc_jit_bool_option opt) const ...@@ -1484,6 +1504,19 @@ recording::context::log_bool_option (enum gcc_jit_bool_option opt) const
m_bool_options[opt] ? "true" : "false"); m_bool_options[opt] ? "true" : "false");
} }
/* Write the current value of the given "inner" bool option to the
log file (if any). */
void
recording::context::log_inner_bool_option (enum inner_bool_option opt) const
{
gcc_assert (opt < NUM_INNER_BOOL_OPTIONS);
if (get_logger ())
log ("%s: %s",
inner_bool_option_reproducer_strings[opt],
m_inner_bool_options[opt] ? "true" : "false");
}
/* Write C source code to PATH that attempts to replay the API /* Write C source code to PATH that attempts to replay the API
calls made to this context (and its parents), for use in calls made to this context (and its parents), for use in
minimizing test cases for libgccjit. minimizing test cases for libgccjit.
...@@ -1623,6 +1656,11 @@ recording::context::dump_reproducer_to_file (const char *path) ...@@ -1623,6 +1656,11 @@ recording::context::dump_reproducer_to_file (const char *path)
r.get_identifier (contexts[ctxt_idx]), r.get_identifier (contexts[ctxt_idx]),
bool_option_reproducer_strings[opt_idx], bool_option_reproducer_strings[opt_idx],
m_bool_options[opt_idx]); m_bool_options[opt_idx]);
for (int opt_idx = 0; opt_idx < NUM_INNER_BOOL_OPTIONS; opt_idx++)
r.write (" %s (%s, %i);\n",
inner_bool_option_reproducer_strings[opt_idx],
r.get_identifier (contexts[ctxt_idx]),
m_inner_bool_options[opt_idx]);
if (!m_command_line_options.is_empty ()) if (!m_command_line_options.is_empty ())
{ {
...@@ -3452,7 +3490,9 @@ recording::function::validate () ...@@ -3452,7 +3490,9 @@ recording::function::validate ()
} }
/* Check that all blocks are reachable. */ /* Check that all blocks are reachable. */
if (m_blocks.length () > 0 && 0 == num_invalid_blocks) if (!m_ctxt->get_inner_bool_option
(INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS)
&& m_blocks.length () > 0 && 0 == num_invalid_blocks)
{ {
/* Iteratively walk the graph of blocks, marking their "m_is_reachable" /* Iteratively walk the graph of blocks, marking their "m_is_reachable"
flag, starting at the initial block. */ flag, starting at the initial block. */
......
...@@ -196,6 +196,10 @@ public: ...@@ -196,6 +196,10 @@ public:
int value); int value);
void void
set_inner_bool_option (enum inner_bool_option inner_opt,
int value);
void
add_command_line_option (const char *optname); add_command_line_option (const char *optname);
void void
...@@ -223,6 +227,12 @@ public: ...@@ -223,6 +227,12 @@ public:
return m_bool_options[opt]; return m_bool_options[opt];
} }
int
get_inner_bool_option (enum inner_bool_option opt) const
{
return m_inner_bool_options[opt];
}
result * result *
compile (); compile ();
...@@ -266,6 +276,7 @@ private: ...@@ -266,6 +276,7 @@ private:
void log_str_option (enum gcc_jit_str_option opt) const; void log_str_option (enum gcc_jit_str_option opt) const;
void log_int_option (enum gcc_jit_int_option opt) const; void log_int_option (enum gcc_jit_int_option opt) const;
void log_bool_option (enum gcc_jit_bool_option opt) const; void log_bool_option (enum gcc_jit_bool_option opt) const;
void log_inner_bool_option (enum inner_bool_option opt) const;
void validate (); void validate ();
...@@ -287,6 +298,7 @@ private: ...@@ -287,6 +298,7 @@ private:
char *m_str_options[GCC_JIT_NUM_STR_OPTIONS]; char *m_str_options[GCC_JIT_NUM_STR_OPTIONS];
int m_int_options[GCC_JIT_NUM_INT_OPTIONS]; int m_int_options[GCC_JIT_NUM_INT_OPTIONS];
bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS]; bool m_bool_options[GCC_JIT_NUM_BOOL_OPTIONS];
bool m_inner_bool_options[NUM_INNER_BOOL_OPTIONS];
auto_vec <char *> m_command_line_options; auto_vec <char *> m_command_line_options;
/* Dumpfiles that were requested via gcc_jit_context_enable_dump. */ /* Dumpfiles that were requested via gcc_jit_context_enable_dump. */
......
...@@ -120,6 +120,8 @@ namespace gccjit ...@@ -120,6 +120,8 @@ namespace gccjit
void set_bool_option (enum gcc_jit_bool_option opt, void set_bool_option (enum gcc_jit_bool_option opt,
int value); int value);
void set_bool_allow_unreachable_blocks (int bool_value);
void add_command_line_option (const char *optname); void add_command_line_option (const char *optname);
location location
...@@ -602,7 +604,13 @@ context::set_bool_option (enum gcc_jit_bool_option opt, ...@@ -602,7 +604,13 @@ context::set_bool_option (enum gcc_jit_bool_option opt,
int value) int value)
{ {
gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value); gcc_jit_context_set_bool_option (m_inner_ctxt, opt, value);
}
inline void
context::set_bool_allow_unreachable_blocks (int bool_value)
{
gcc_jit_context_set_bool_allow_unreachable_blocks (m_inner_ctxt,
bool_value);
} }
inline void inline void
......
...@@ -2185,6 +2185,23 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt, ...@@ -2185,6 +2185,23 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
/* Public entrypoint. See description in libgccjit.h. /* Public entrypoint. See description in libgccjit.h.
After error-checking, the real work is done by the After error-checking, the real work is done by the
gcc::jit::recording::context::set_inner_bool_option method in
jit-recording.c. */
void
gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt,
int bool_value)
{
RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL context");
JIT_LOG_FUNC (ctxt->get_logger ());
ctxt->set_inner_bool_option (
gcc::jit::INNER_BOOL_OPTION_ALLOW_UNREACHABLE_BLOCKS,
bool_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 gcc::jit::recording::context::add_command_line_option method in
jit-recording.c. */ jit-recording.c. */
......
...@@ -140,6 +140,9 @@ gcc_jit_context_acquire (void); ...@@ -140,6 +140,9 @@ gcc_jit_context_acquire (void);
extern void extern void
gcc_jit_context_release (gcc_jit_context *ctxt); gcc_jit_context_release (gcc_jit_context *ctxt);
/* Options present in the initial release of libgccjit.
These were handled using enums. */
/* Options taking string values. */ /* Options taking string values. */
enum gcc_jit_str_option enum gcc_jit_str_option
{ {
...@@ -243,6 +246,31 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt, ...@@ -243,6 +246,31 @@ gcc_jit_context_set_bool_option (gcc_jit_context *ctxt,
enum gcc_jit_bool_option opt, enum gcc_jit_bool_option opt,
int value); int value);
/* Options added after the initial release of libgccjit.
These are handled by providing an entrypoint per option,
rather than by extending the enum gcc_jit_*_option,
so that client code that use these new options can be identified
from binary metadata. */
/* By default, libgccjit will issue an error about unreachable blocks
within a function.
This option can be used to disable that error.
This entrypoint was added in LIBGCCJIT_ABI_2; you can test for
its presence using
#ifdef LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
*/
extern void
gcc_jit_context_set_bool_allow_unreachable_blocks (gcc_jit_context *ctxt,
int bool_value);
/* Pre-canned feature macro to indicate the presence of
gcc_jit_context_set_bool_allow_unreachable_blocks. This can be
tested for with #ifdef. */
#define LIBGCCJIT_HAVE_gcc_jit_context_set_bool_allow_unreachable_blocks
/* Add an arbitrary gcc command-line option to the context. /* Add an arbitrary gcc command-line option to the context.
The context takes a copy of the string, so the The context takes a copy of the string, so the
(const char *) optname is not needed anymore after the call (const char *) optname is not needed anymore after the call
......
...@@ -114,3 +114,9 @@ LIBGCCJIT_ABI_1 { ...@@ -114,3 +114,9 @@ LIBGCCJIT_ABI_1 {
global: global:
gcc_jit_context_add_command_line_option; gcc_jit_context_add_command_line_option;
} LIBGCCJIT_ABI_0; } LIBGCCJIT_ABI_0;
# Add support for disabling the check for unreachable blocks (PR jit/66546).
LIBGCCJIT_ABI_2 {
global:
gcc_jit_context_set_bool_allow_unreachable_blocks;
} LIBGCCJIT_ABI_1;
2015-06-30 David Malcolm <dmalcolm@redhat.com> 2015-06-30 David Malcolm <dmalcolm@redhat.com>
PR jit/66546
* jit.dg/all-non-failing-tests.h: Add note about
test-validly-unreachable-block.c.
* jit.dg/test-validly-unreachable-block.c: New file.
2015-06-30 David Malcolm <dmalcolm@redhat.com>
PR jit/66628 PR jit/66628
* jit.dg/all-non-failing-tests.h: Add note about * jit.dg/all-non-failing-tests.h: Add note about
test-extra-options.c. test-extra-options.c.
......
...@@ -189,6 +189,10 @@ ...@@ -189,6 +189,10 @@
#undef create_code #undef create_code
#undef verify_code #undef verify_code
/* test-validly-unreachable-block.c: We don't use this one, since the use
of gcc_jit_context_set_bool_allow_unreachable_blocks affects the whole
context. */
/* test-volatile.c */ /* test-volatile.c */
#define create_code create_code_volatile #define create_code create_code_volatile
#define verify_code verify_code_volatile #define verify_code verify_code_volatile
......
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "libgccjit.h"
#include "harness.h"
void
create_code (gcc_jit_context *ctxt, void *user_data)
{
/* Let's try to inject the equivalent of:
void
test_fn ()
{
return;
return;
}
where the second block is unreachable, but have it
survive validation (PR jit/66546).
*/
gcc_jit_context_set_bool_allow_unreachable_blocks (ctxt, 1);
gcc_jit_type *void_t =
gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
/* Build the test_fn. */
gcc_jit_function *test_fn =
gcc_jit_context_new_function (ctxt, NULL,
GCC_JIT_FUNCTION_EXPORTED,
void_t,
"test_fn",
0, NULL,
0);
gcc_jit_block *initial =
gcc_jit_function_new_block (test_fn, "a");
gcc_jit_block *unreachable =
gcc_jit_function_new_block (test_fn, "b");
gcc_jit_block_end_with_void_return (initial, NULL);
gcc_jit_block_end_with_void_return (unreachable, NULL);
}
void
verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
{
/* Ensure that the "unreachable blocks" validator was ignored. */
CHECK_NON_NULL (result);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment