PR jit/64020: Fixes to handling of builtins
PR jit/64020 * docs/topics/types.rst (Standard types) Add new enum values to the table of enum gcc_jit_types: GCC_JIT_TYPE_COMPLEX_FLOAT, GCC_JIT_TYPE_COMPLEX_DOUBLE, GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE. Widen the left-hand column so that GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE will fit. * docs/_build/texinfo/libgccjit.texi: Regenerate. * jit-builtins.c: Include stringpool.h and jit-playback.h. Move everything out of the gcc::jit::recording namespace into just gcc::jit. (struct builtin_data): Add fields "fnclass", "attr", and "implicit_p". (DEF_BUILTIN): Update macro so populate the new fields. (builtins_manager::builtins_manager): Update for move out of recording namespace. Initialize the m_attributes array. (builtins_manager::get_builtin_function): Likewise. (builtins_manager::get_builtin_function_by_id): New function. (builtins_manager::make_builtin_function): Update for move out of recording namespace. Add fix for PR jit/64020 by detecting specific builtin ids and having them ensure that builtins for other ids are created as necessary. (builtins_manager::get_type): Update for move out of recording namespace. (builtins_manager::make_type): Likewise. Add some missing #undefs. (builtins_manager::make_primitive_type): Update for move out of recording namespace. Implement the three BT_COMPLEX_ cases and BT_DOUBLE_PTR. (builtins_manager::make_fn_type): Update for move out of recording namespace. (builtins_manager::make_ptr_type): Likewise. (builtins_manager::finish_playback): New function. (builtins_manager::get_class): New function. (builtins_manager::implicit_p): New function. (builtins_manager::get_attrs_tree): Two new functions. (builtins_manager::make_attrs_tree): New function. * jit-builtins.h: Move everything out of the gcc::jit::recording namespace into just gcc::jit. (enum built_in_attribute): New. (builtins_manager::builtins_manager): Update decl for namespace change. (builtins_manager::get_builtin_function): Likewise. (builtins_manager::get_class): New. (builtins_manager::implicit_p): New. (builtins_manager::get_attrs_tree): Two new functions. (builtins_manager::make_attrs_tree): New function. (builtins_manager::finish_playback): New. (builtins_manager::get_builtin_function_by_id): New. (builtins_manager::make_builtin_function): Update decl for namespace change. (builtins_manager::get_type): Likewise. (builtins_manager::make_type): Likewise. (builtins_manager::make_primitive_type): Likewise. (builtins_manager::make_fn_type): Likewise. (builtins_manager::make_ptr_type): Likewise. (builtins_manager): Likewise for fields. Add new field "m_attributes". * jit-common.h (NUM_GCC_JIT_TYPES): Update. (builtins_manager): Update forward decl to reflect namespace change. * jit-playback.c: Include attribs.h and jit-builtins.h. (gcc::jit::playback::context::get_tree_node_for_type): Add cases for the new COMPLEX_ types. (gcc::jit::playback::context::new_function): If creating a builtin, set the DECL_BUILT_IN_CLASS and attributes on the fndecl, and call set_builtin_decl. (gcc::jit::playback::context::replay): If we have a builtins_manager, call its finish_playback method when we're done. * jit-playback.h: (gcc::jit::playback::context::get_builtins_manager): New function. * jit-recording.c (gcc::jit::recording::context::get_builtins_manager): New function. (gcc::jit::recording::get_builtin_function): Use get_builtins_manager, in case we're a child context. (gcc::jit::recording::memento_of_get_type::dereference): Add the COMPLEX_ types. (gcc::jit::recording::memento_of_get_type::is_int): Likewise. (gcc::jit::recording::memento_of_get_type::is_float): Likewise. (gcc::jit::recording::memento_of_get_type::is_bool): Likewise. (get_type_strings): Likewise. * jit-recording.h (gcc::jit::recording::context::get_builtins_manager): New. * libgccjit.h (enum gcc_jit_types): Add GCC_JIT_TYPE_COMPLEX_FLOAT, GCC_JIT_TYPE_COMPLEX_DOUBLE, GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE. From-SVN: r218240
This commit is contained in:
parent
23844fd730
commit
eeafb31957
@ -1,3 +1,99 @@
|
||||
2014-12-01 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
PR jit/64020
|
||||
* docs/topics/types.rst (Standard types) Add new enum values to
|
||||
the table of enum gcc_jit_types: GCC_JIT_TYPE_COMPLEX_FLOAT,
|
||||
GCC_JIT_TYPE_COMPLEX_DOUBLE, GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE.
|
||||
Widen the left-hand column so that
|
||||
GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE will fit.
|
||||
* docs/_build/texinfo/libgccjit.texi: Regenerate.
|
||||
|
||||
* jit-builtins.c: Include stringpool.h and jit-playback.h.
|
||||
Move everything out of the gcc::jit::recording namespace into
|
||||
just gcc::jit.
|
||||
(struct builtin_data): Add fields "fnclass", "attr", and
|
||||
"implicit_p".
|
||||
(DEF_BUILTIN): Update macro so populate the new fields.
|
||||
(builtins_manager::builtins_manager): Update for move out of
|
||||
recording namespace. Initialize the m_attributes array.
|
||||
(builtins_manager::get_builtin_function): Likewise.
|
||||
(builtins_manager::get_builtin_function_by_id): New function.
|
||||
(builtins_manager::make_builtin_function): Update for move out of
|
||||
recording namespace. Add fix for PR jit/64020 by detecting
|
||||
specific builtin ids and having them ensure that builtins for
|
||||
other ids are created as necessary.
|
||||
(builtins_manager::get_type): Update for move out of recording
|
||||
namespace.
|
||||
(builtins_manager::make_type): Likewise. Add some missing
|
||||
#undefs.
|
||||
(builtins_manager::make_primitive_type): Update for move out of
|
||||
recording namespace. Implement the three BT_COMPLEX_ cases and
|
||||
BT_DOUBLE_PTR.
|
||||
(builtins_manager::make_fn_type): Update for move out of recording
|
||||
namespace.
|
||||
(builtins_manager::make_ptr_type): Likewise.
|
||||
(builtins_manager::finish_playback): New function.
|
||||
(builtins_manager::get_class): New function.
|
||||
(builtins_manager::implicit_p): New function.
|
||||
(builtins_manager::get_attrs_tree): Two new functions.
|
||||
(builtins_manager::make_attrs_tree): New function.
|
||||
|
||||
* jit-builtins.h: Move everything out of the gcc::jit::recording
|
||||
namespace into just gcc::jit.
|
||||
(enum built_in_attribute): New.
|
||||
(builtins_manager::builtins_manager): Update decl for namespace
|
||||
change.
|
||||
(builtins_manager::get_builtin_function): Likewise.
|
||||
(builtins_manager::get_class): New.
|
||||
(builtins_manager::implicit_p): New.
|
||||
(builtins_manager::get_attrs_tree): Two new functions.
|
||||
(builtins_manager::make_attrs_tree): New function.
|
||||
(builtins_manager::finish_playback): New.
|
||||
(builtins_manager::get_builtin_function_by_id): New.
|
||||
(builtins_manager::make_builtin_function): Update decl for
|
||||
namespace change.
|
||||
(builtins_manager::get_type): Likewise.
|
||||
(builtins_manager::make_type): Likewise.
|
||||
(builtins_manager::make_primitive_type): Likewise.
|
||||
(builtins_manager::make_fn_type): Likewise.
|
||||
(builtins_manager::make_ptr_type): Likewise.
|
||||
(builtins_manager): Likewise for fields. Add new field
|
||||
"m_attributes".
|
||||
|
||||
* jit-common.h (NUM_GCC_JIT_TYPES): Update.
|
||||
(builtins_manager): Update forward decl to reflect namespace
|
||||
change.
|
||||
|
||||
* jit-playback.c: Include attribs.h and jit-builtins.h.
|
||||
(gcc::jit::playback::context::get_tree_node_for_type): Add cases
|
||||
for the new COMPLEX_ types.
|
||||
(gcc::jit::playback::context::new_function): If creating a
|
||||
builtin, set the DECL_BUILT_IN_CLASS and attributes on the fndecl,
|
||||
and call set_builtin_decl.
|
||||
(gcc::jit::playback::context::replay): If we have a
|
||||
builtins_manager, call its finish_playback method when we're done.
|
||||
|
||||
* jit-playback.h:
|
||||
(gcc::jit::playback::context::get_builtins_manager): New function.
|
||||
|
||||
* jit-recording.c
|
||||
(gcc::jit::recording::context::get_builtins_manager): New function.
|
||||
(gcc::jit::recording::get_builtin_function): Use
|
||||
get_builtins_manager, in case we're a child context.
|
||||
(gcc::jit::recording::memento_of_get_type::dereference): Add the
|
||||
COMPLEX_ types.
|
||||
(gcc::jit::recording::memento_of_get_type::is_int): Likewise.
|
||||
(gcc::jit::recording::memento_of_get_type::is_float): Likewise.
|
||||
(gcc::jit::recording::memento_of_get_type::is_bool): Likewise.
|
||||
(get_type_strings): Likewise.
|
||||
|
||||
* jit-recording.h
|
||||
(gcc::jit::recording::context::get_builtins_manager): New.
|
||||
|
||||
* libgccjit.h (enum gcc_jit_types): Add
|
||||
GCC_JIT_TYPE_COMPLEX_FLOAT, GCC_JIT_TYPE_COMPLEX_DOUBLE,
|
||||
GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE.
|
||||
|
||||
2014-12-01 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* jit-builtins.c
|
||||
|
550
gcc/jit/docs/_build/texinfo/libgccjit.texi
vendored
550
gcc/jit/docs/_build/texinfo/libgccjit.texi
vendored
File diff suppressed because it is too large
Load Diff
@ -57,32 +57,35 @@ Standard types
|
||||
|
||||
Access a specific type. The available types are:
|
||||
|
||||
========================================= ================================
|
||||
`enum gcc_jit_types` value Meaning
|
||||
========================================= ================================
|
||||
:c:data:`GCC_JIT_TYPE_VOID` C's ``void`` type.
|
||||
:c:data:`GCC_JIT_TYPE_VOID_PTR` C's ``void *``.
|
||||
:c:data:`GCC_JIT_TYPE_BOOL` C++'s ``bool`` type; also C99's
|
||||
``_Bool`` type, aka ``bool`` if
|
||||
using stdbool.h.
|
||||
:c:data:`GCC_JIT_TYPE_CHAR` C's ``char`` (of some signedness)
|
||||
:c:data:`GCC_JIT_TYPE_SIGNED_CHAR` C's ``signed char``
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_CHAR` C's ``unsigned char``
|
||||
:c:data:`GCC_JIT_TYPE_SHORT` C's ``short`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_SHORT` C's ``unsigned short``
|
||||
:c:data:`GCC_JIT_TYPE_INT` C's ``int`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_INT` C's ``unsigned int``
|
||||
:c:data:`GCC_JIT_TYPE_LONG` C's ``long`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_LONG` C's ``unsigned long``
|
||||
:c:data:`GCC_JIT_TYPE_LONG_LONG` C99's ``long long`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_LONG_LONG` C99's ``unsigned long long``
|
||||
========================================== ================================
|
||||
`enum gcc_jit_types` value Meaning
|
||||
========================================== ================================
|
||||
:c:data:`GCC_JIT_TYPE_VOID` C's ``void`` type.
|
||||
:c:data:`GCC_JIT_TYPE_VOID_PTR` C's ``void *``.
|
||||
:c:data:`GCC_JIT_TYPE_BOOL` C++'s ``bool`` type; also C99's
|
||||
``_Bool`` type, aka ``bool`` if
|
||||
using stdbool.h.
|
||||
:c:data:`GCC_JIT_TYPE_CHAR` C's ``char`` (of some signedness)
|
||||
:c:data:`GCC_JIT_TYPE_SIGNED_CHAR` C's ``signed char``
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_CHAR` C's ``unsigned char``
|
||||
:c:data:`GCC_JIT_TYPE_SHORT` C's ``short`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_SHORT` C's ``unsigned short``
|
||||
:c:data:`GCC_JIT_TYPE_INT` C's ``int`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_INT` C's ``unsigned int``
|
||||
:c:data:`GCC_JIT_TYPE_LONG` C's ``long`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_LONG` C's ``unsigned long``
|
||||
:c:data:`GCC_JIT_TYPE_LONG_LONG` C99's ``long long`` (signed)
|
||||
:c:data:`GCC_JIT_TYPE_UNSIGNED_LONG_LONG` C99's ``unsigned long long``
|
||||
:c:data:`GCC_JIT_TYPE_FLOAT`
|
||||
:c:data:`GCC_JIT_TYPE_DOUBLE`
|
||||
:c:data:`GCC_JIT_TYPE_LONG_DOUBLE`
|
||||
:c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR` C type: ``(const char *)``
|
||||
:c:data:`GCC_JIT_TYPE_SIZE_T` C's ``size_t`` type
|
||||
:c:data:`GCC_JIT_TYPE_FILE_PTR` C type: ``(FILE *)``
|
||||
========================================= ================================
|
||||
:c:data:`GCC_JIT_TYPE_CONST_CHAR_PTR` C type: ``(const char *)``
|
||||
:c:data:`GCC_JIT_TYPE_SIZE_T` C's ``size_t`` type
|
||||
:c:data:`GCC_JIT_TYPE_FILE_PTR` C type: ``(FILE *)``
|
||||
:c:data:`GCC_JIT_TYPE_COMPLEX_FLOAT` C99's ``_Complex float``
|
||||
:c:data:`GCC_JIT_TYPE_COMPLEX_DOUBLE` C99's ``_Complex double``
|
||||
:c:data:`GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE` C99's ``_Complex long double``
|
||||
========================================== ================================
|
||||
|
||||
.. function:: gcc_jit_type *\
|
||||
gcc_jit_context_get_int_type (gcc_jit_context *ctxt, \
|
||||
|
@ -23,17 +23,17 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "opts.h"
|
||||
#include "tree.h"
|
||||
#include "target.h"
|
||||
#include "stringpool.h"
|
||||
|
||||
#include "jit-common.h"
|
||||
#include "jit-builtins.h"
|
||||
#include "jit-recording.h"
|
||||
#include "jit-playback.h"
|
||||
|
||||
namespace gcc {
|
||||
|
||||
namespace jit {
|
||||
|
||||
namespace recording {
|
||||
|
||||
const char *const prefix = "__builtin_";
|
||||
const size_t prefix_len = strlen (prefix);
|
||||
|
||||
@ -41,9 +41,12 @@ const size_t prefix_len = strlen (prefix);
|
||||
struct builtin_data
|
||||
{
|
||||
const char *name;
|
||||
enum built_in_class fnclass;
|
||||
enum jit_builtin_type type;
|
||||
bool both_p;
|
||||
bool fallback_p;
|
||||
enum built_in_attribute attr;
|
||||
bool implicit_p;
|
||||
|
||||
const char *get_asm_name () const
|
||||
{
|
||||
@ -54,8 +57,9 @@ struct builtin_data
|
||||
}
|
||||
};
|
||||
|
||||
#define DEF_BUILTIN(X, NAME, C, TYPE, LT, BOTH_P, FALLBACK_P, NA, AT, IM, COND)\
|
||||
{NAME, TYPE, BOTH_P, FALLBACK_P},
|
||||
#define DEF_BUILTIN(X, NAME, CLASS, TYPE, LT, BOTH_P, FALLBACK_P, \
|
||||
NONANSI_P, ATTRS, IMPLICIT, COND) \
|
||||
{NAME, CLASS, TYPE, BOTH_P, FALLBACK_P, ATTRS, IMPLICIT},
|
||||
static const struct builtin_data builtin_data[] =
|
||||
{
|
||||
#include "builtins.def"
|
||||
@ -130,20 +134,21 @@ find_builtin_by_name (const char *in_name,
|
||||
|
||||
// class builtins_manager
|
||||
|
||||
/* Constructor for gcc::jit::recording::builtins_manager. */
|
||||
/* Constructor for gcc::jit::builtins_manager. */
|
||||
|
||||
builtins_manager::builtins_manager (context *ctxt)
|
||||
builtins_manager::builtins_manager (recording::context *ctxt)
|
||||
: m_ctxt (ctxt)
|
||||
{
|
||||
memset (m_types, 0, sizeof (m_types));
|
||||
memset (m_builtin_functions, 0, sizeof (m_builtin_functions));
|
||||
memset (m_attributes, 0, sizeof (m_attributes));
|
||||
}
|
||||
|
||||
/* Locate a builtin function by name.
|
||||
Create a recording::function of the appropriate type, reusing them
|
||||
if they've already been seen. */
|
||||
|
||||
function *
|
||||
recording::function *
|
||||
builtins_manager::get_builtin_function (const char *name)
|
||||
{
|
||||
enum built_in_function builtin_id;
|
||||
@ -153,6 +158,16 @@ builtins_manager::get_builtin_function (const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return get_builtin_function_by_id (builtin_id);
|
||||
}
|
||||
|
||||
/* Locate a builtin function by id.
|
||||
Create a recording::function of the appropriate type, reusing them
|
||||
if they've already been seen. */
|
||||
|
||||
recording::function *
|
||||
builtins_manager::get_builtin_function_by_id (enum built_in_function builtin_id)
|
||||
{
|
||||
gcc_assert (builtin_id >= 0);
|
||||
gcc_assert (builtin_id < END_BUILTINS);
|
||||
|
||||
@ -160,7 +175,7 @@ builtins_manager::get_builtin_function (const char *name)
|
||||
the same id on a context give back the same object. */
|
||||
if (!m_builtin_functions[builtin_id])
|
||||
{
|
||||
function *fn = make_builtin_function (builtin_id);
|
||||
recording::function *fn = make_builtin_function (builtin_id);
|
||||
if (fn)
|
||||
{
|
||||
m_builtin_functions[builtin_id] = fn;
|
||||
@ -173,23 +188,23 @@ builtins_manager::get_builtin_function (const char *name)
|
||||
|
||||
/* Create the recording::function for a given builtin function, by ID. */
|
||||
|
||||
function *
|
||||
recording::function *
|
||||
builtins_manager::make_builtin_function (enum built_in_function builtin_id)
|
||||
{
|
||||
const struct builtin_data& bd = builtin_data[builtin_id];
|
||||
enum jit_builtin_type type_id = bd.type;
|
||||
type *t = get_type (type_id);
|
||||
recording::type *t = get_type (type_id);
|
||||
if (!t)
|
||||
return NULL;
|
||||
function_type *func_type = t->as_a_function_type ();
|
||||
recording::function_type *func_type = t->as_a_function_type ();
|
||||
if (!func_type)
|
||||
return NULL;
|
||||
|
||||
vec<type *> param_types = func_type->get_param_types ();
|
||||
vec<recording::type *> param_types = func_type->get_param_types ();
|
||||
recording::param **params = new recording::param *[param_types.length ()];
|
||||
|
||||
int i;
|
||||
type *param_type;
|
||||
recording::type *param_type;
|
||||
FOR_EACH_VEC_ELT (param_types, i, param_type)
|
||||
{
|
||||
char buf[16];
|
||||
@ -199,24 +214,47 @@ builtins_manager::make_builtin_function (enum built_in_function builtin_id)
|
||||
buf);
|
||||
}
|
||||
const char *asm_name = bd.get_asm_name ();
|
||||
function *result =
|
||||
new function (m_ctxt,
|
||||
NULL,
|
||||
GCC_JIT_FUNCTION_IMPORTED, // FIXME
|
||||
func_type->get_return_type (),
|
||||
m_ctxt->new_string (asm_name),
|
||||
param_types.length (),
|
||||
params,
|
||||
func_type->is_variadic (),
|
||||
builtin_id);
|
||||
recording::function *result =
|
||||
new recording::function (m_ctxt,
|
||||
NULL,
|
||||
GCC_JIT_FUNCTION_IMPORTED, // FIXME
|
||||
func_type->get_return_type (),
|
||||
m_ctxt->new_string (asm_name),
|
||||
param_types.length (),
|
||||
params,
|
||||
func_type->is_variadic (),
|
||||
builtin_id);
|
||||
delete[] params;
|
||||
|
||||
/* PR/64020 - If the client code is using builtin cos or sin,
|
||||
tree-ssa-math-opt.c's execute_cse_sincos_1 may attempt
|
||||
to optimize them to use __builtin_cexpi; for this,
|
||||
BUILT_IN_CEXPI needs to exist.
|
||||
|
||||
Hence query the cache for BUILT_IN_CEXPI to ensure it gets
|
||||
built. */
|
||||
if (builtin_id == BUILT_IN_COS || builtin_id == BUILT_IN_SIN)
|
||||
(void)get_builtin_function_by_id (BUILT_IN_CEXPI);
|
||||
|
||||
/* builtins.c:expand_builtin_cexpi can optimize the various
|
||||
CEXP builtins to SINCOS builtins, and hence we may require
|
||||
SINCOS builtins latter.
|
||||
|
||||
Ensure the appropriate SINCOS builtin exists. */
|
||||
if (builtin_id == BUILT_IN_CEXPIF)
|
||||
(void)get_builtin_function_by_id (BUILT_IN_SINCOSF);
|
||||
else if (builtin_id == BUILT_IN_CEXPI)
|
||||
(void)get_builtin_function_by_id (BUILT_IN_SINCOS);
|
||||
else if (builtin_id == BUILT_IN_CEXPIL)
|
||||
(void)get_builtin_function_by_id (BUILT_IN_SINCOSL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Get the recording::type for a given type of builtin function,
|
||||
by ID, creating it if it doesn't already exist. */
|
||||
|
||||
type *
|
||||
recording::type *
|
||||
builtins_manager::get_type (enum jit_builtin_type type_id)
|
||||
{
|
||||
if (!m_types[type_id])
|
||||
@ -226,7 +264,7 @@ builtins_manager::get_type (enum jit_builtin_type type_id)
|
||||
|
||||
/* Create the recording::type for a given type of builtin function. */
|
||||
|
||||
type *
|
||||
recording::type *
|
||||
builtins_manager::make_type (enum jit_builtin_type type_id)
|
||||
{
|
||||
/* Use builtin-types.def to construct a switch statement, with each
|
||||
@ -283,12 +321,15 @@ builtins_manager::make_type (enum jit_builtin_type type_id)
|
||||
#include "builtin-types.def"
|
||||
|
||||
#undef DEF_PRIMITIVE_TYPE
|
||||
#undef DEF_FUNCTION_TYPE_0
|
||||
#undef DEF_FUNCTION_TYPE_1
|
||||
#undef DEF_FUNCTION_TYPE_2
|
||||
#undef DEF_FUNCTION_TYPE_3
|
||||
#undef DEF_FUNCTION_TYPE_4
|
||||
#undef DEF_FUNCTION_TYPE_5
|
||||
#undef DEF_FUNCTION_TYPE_6
|
||||
#undef DEF_FUNCTION_TYPE_7
|
||||
#undef DEF_FUNCTION_TYPE_8
|
||||
#undef DEF_FUNCTION_TYPE_VAR_0
|
||||
#undef DEF_FUNCTION_TYPE_VAR_1
|
||||
#undef DEF_FUNCTION_TYPE_VAR_2
|
||||
@ -307,7 +348,7 @@ builtins_manager::make_type (enum jit_builtin_type type_id)
|
||||
|
||||
Only some types are currently supported. */
|
||||
|
||||
type*
|
||||
recording::type*
|
||||
builtins_manager::make_primitive_type (enum jit_builtin_type type_id)
|
||||
{
|
||||
switch (type_id)
|
||||
@ -339,9 +380,12 @@ builtins_manager::make_primitive_type (enum jit_builtin_type type_id)
|
||||
case BT_FLOAT: return m_ctxt->get_type (GCC_JIT_TYPE_FLOAT);
|
||||
case BT_DOUBLE: return m_ctxt->get_type (GCC_JIT_TYPE_DOUBLE);
|
||||
case BT_LONGDOUBLE: return m_ctxt->get_type (GCC_JIT_TYPE_LONG_DOUBLE);
|
||||
// case BT_COMPLEX_FLOAT:
|
||||
// case BT_COMPLEX_DOUBLE:
|
||||
// case BT_COMPLEX_LONGDOUBLE:
|
||||
case BT_COMPLEX_FLOAT:
|
||||
return m_ctxt->get_type (GCC_JIT_TYPE_COMPLEX_FLOAT);
|
||||
case BT_COMPLEX_DOUBLE:
|
||||
return m_ctxt->get_type (GCC_JIT_TYPE_COMPLEX_DOUBLE);
|
||||
case BT_COMPLEX_LONGDOUBLE:
|
||||
return m_ctxt->get_type (GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE);
|
||||
case BT_PTR: return m_ctxt->get_type (GCC_JIT_TYPE_VOID_PTR);
|
||||
case BT_FILEPTR: return m_ctxt->get_type (GCC_JIT_TYPE_FILE_PTR);
|
||||
// case BT_CONST:
|
||||
@ -350,7 +394,8 @@ builtins_manager::make_primitive_type (enum jit_builtin_type type_id)
|
||||
// case BT_PTRMODE:
|
||||
// case BT_INT_PTR:
|
||||
// case BT_FLOAT_PTR:
|
||||
// case BT_DOUBLE_PTR:
|
||||
case BT_DOUBLE_PTR:
|
||||
return m_ctxt->get_type (GCC_JIT_TYPE_DOUBLE)->get_pointer ();
|
||||
// case BT_CONST_DOUBLE_PTR:
|
||||
// case BT_LONGDOUBLE_PTR:
|
||||
// case BT_PID:
|
||||
@ -378,7 +423,7 @@ builtins_manager::make_primitive_type (enum jit_builtin_type type_id)
|
||||
/* Create the recording::function_type for a given function type
|
||||
signature. */
|
||||
|
||||
function_type *
|
||||
recording::function_type *
|
||||
builtins_manager::make_fn_type (enum jit_builtin_type,
|
||||
enum jit_builtin_type return_type_id,
|
||||
bool is_variadic,
|
||||
@ -386,9 +431,9 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
|
||||
{
|
||||
va_list list;
|
||||
int i;
|
||||
type **param_types = new type *[num_args];
|
||||
type *return_type = NULL;
|
||||
function_type *result = NULL;
|
||||
recording::type **param_types = new recording::type *[num_args];
|
||||
recording::type *return_type = NULL;
|
||||
recording::function_type *result = NULL;
|
||||
|
||||
va_start (list, num_args);
|
||||
for (i = 0; i < num_args; ++i)
|
||||
@ -417,14 +462,104 @@ builtins_manager::make_fn_type (enum jit_builtin_type,
|
||||
|
||||
/* Handler for DEF_POINTER_TYPE within builtins_manager::make_type. */
|
||||
|
||||
type *
|
||||
recording::type *
|
||||
builtins_manager::make_ptr_type (enum jit_builtin_type,
|
||||
enum jit_builtin_type other_type_id)
|
||||
{
|
||||
type *base_type = get_type (other_type_id);
|
||||
recording::type *base_type = get_type (other_type_id);
|
||||
return base_type->get_pointer ();
|
||||
}
|
||||
|
||||
} // namespace recording
|
||||
/* Playback support. */
|
||||
|
||||
/* A builtins_manager is associated with a recording::context
|
||||
and might be reused for multiple compiles on various
|
||||
playback::contexts, perhaps with different options.
|
||||
|
||||
Purge any playback state. Currently this is just the table of
|
||||
attributes. */
|
||||
|
||||
void
|
||||
builtins_manager::finish_playback (void)
|
||||
{
|
||||
memset (m_attributes, 0, sizeof (m_attributes));
|
||||
}
|
||||
|
||||
/* Get the enum built_in_class for BUILTIN_ID. */
|
||||
|
||||
enum built_in_class
|
||||
builtins_manager::get_class (enum built_in_function builtin_id)
|
||||
{
|
||||
return builtin_data[builtin_id].fnclass;
|
||||
}
|
||||
|
||||
/* Is BUILTIN_ID implicit? */
|
||||
|
||||
bool
|
||||
builtins_manager::implicit_p (enum built_in_function builtin_id)
|
||||
{
|
||||
return builtin_data[builtin_id].implicit_p;
|
||||
}
|
||||
|
||||
/* Get any attributes (in tree form) for the function declaration
|
||||
for BUILTIN_ID.
|
||||
|
||||
These are created on-demand, and cached within the m_attributes
|
||||
array, until finish_playback. */
|
||||
|
||||
tree
|
||||
builtins_manager::get_attrs_tree (enum built_in_function builtin_id)
|
||||
{
|
||||
enum built_in_attribute attr = builtin_data[builtin_id].attr;
|
||||
return get_attrs_tree (attr);
|
||||
}
|
||||
|
||||
/* As above, but for an enum built_in_attribute. */
|
||||
|
||||
tree
|
||||
builtins_manager::get_attrs_tree (enum built_in_attribute attr)
|
||||
{
|
||||
gcc_assert (attr < ATTR_LAST);
|
||||
if (!m_attributes [attr])
|
||||
m_attributes [attr] = make_attrs_tree (attr);
|
||||
return m_attributes [attr];
|
||||
}
|
||||
|
||||
/* Handle a cache-miss within the m_attributes array by
|
||||
generating the attributes for enum built_in_attribute
|
||||
in tree form. */
|
||||
|
||||
tree
|
||||
builtins_manager::make_attrs_tree (enum built_in_attribute attr)
|
||||
{
|
||||
switch (attr)
|
||||
{
|
||||
/* Generate cases from builtin-attrs.def. */
|
||||
#define DEF_ATTR_NULL_TREE(ENUM) \
|
||||
case ENUM: return NULL_TREE;
|
||||
#define DEF_ATTR_INT(ENUM, VALUE) \
|
||||
case ENUM: return build_int_cst (integer_type_node, VALUE);
|
||||
#define DEF_ATTR_STRING(ENUM, VALUE) \
|
||||
case ENUM: return build_string (strlen (VALUE), VALUE);
|
||||
#define DEF_ATTR_IDENT(ENUM, STRING) \
|
||||
case ENUM: return get_identifier (STRING);
|
||||
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
|
||||
case ENUM: return tree_cons (get_attrs_tree (PURPOSE), \
|
||||
get_attrs_tree (VALUE), \
|
||||
get_attrs_tree (CHAIN));
|
||||
#include "builtin-attrs.def"
|
||||
#undef DEF_ATTR_NULL_TREE
|
||||
#undef DEF_ATTR_INT
|
||||
#undef DEF_ATTR_IDENT
|
||||
#undef DEF_ATTR_TREE_LIST
|
||||
|
||||
default:
|
||||
/* We somehow got a value not covered by the autogenerated
|
||||
cases. */
|
||||
gcc_unreachable ();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace gcc
|
||||
|
@ -26,8 +26,6 @@ namespace gcc {
|
||||
|
||||
namespace jit {
|
||||
|
||||
namespace recording {
|
||||
|
||||
/* Create an enum of the builtin types. */
|
||||
|
||||
enum jit_builtin_type
|
||||
@ -71,43 +69,91 @@ enum jit_builtin_type
|
||||
BT_LAST
|
||||
}; /* enum jit_builtin_type */
|
||||
|
||||
/* Create an enum of the attributes that can be present on builtins. */
|
||||
|
||||
enum built_in_attribute
|
||||
{
|
||||
#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
|
||||
#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
|
||||
#define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
|
||||
#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
|
||||
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
|
||||
#include "builtin-attrs.def"
|
||||
#undef DEF_ATTR_NULL_TREE
|
||||
#undef DEF_ATTR_INT
|
||||
#undef DEF_ATTR_STRING
|
||||
#undef DEF_ATTR_IDENT
|
||||
#undef DEF_ATTR_TREE_LIST
|
||||
ATTR_LAST
|
||||
};
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
class builtins_manager
|
||||
{
|
||||
public:
|
||||
builtins_manager (context *ctxt);
|
||||
builtins_manager (recording::context *ctxt);
|
||||
|
||||
function *
|
||||
recording::function *
|
||||
get_builtin_function (const char *name);
|
||||
|
||||
static enum built_in_class
|
||||
get_class (enum built_in_function builtin_id);
|
||||
|
||||
static bool
|
||||
implicit_p (enum built_in_function builtin_id);
|
||||
|
||||
tree
|
||||
get_attrs_tree (enum built_in_function builtin_id);
|
||||
|
||||
tree
|
||||
get_attrs_tree (enum built_in_attribute attr);
|
||||
|
||||
void
|
||||
finish_playback (void);
|
||||
|
||||
private:
|
||||
function *make_builtin_function (enum built_in_function builtin_id);
|
||||
recording::function *
|
||||
get_builtin_function_by_id (enum built_in_function builtin_id);
|
||||
|
||||
type *get_type (enum jit_builtin_type type_id);
|
||||
recording::function *
|
||||
make_builtin_function (enum built_in_function builtin_id);
|
||||
|
||||
type *make_type (enum jit_builtin_type type_id);
|
||||
recording::type *
|
||||
get_type (enum jit_builtin_type type_id);
|
||||
|
||||
type*
|
||||
recording::type *
|
||||
make_type (enum jit_builtin_type type_id);
|
||||
|
||||
recording::type*
|
||||
make_primitive_type (enum jit_builtin_type type_id);
|
||||
|
||||
function_type*
|
||||
recording::function_type*
|
||||
make_fn_type (enum jit_builtin_type type_id,
|
||||
enum jit_builtin_type return_type_id,
|
||||
bool is_variadic,
|
||||
int num_args, ...);
|
||||
|
||||
type*
|
||||
recording::type*
|
||||
make_ptr_type (enum jit_builtin_type type_id,
|
||||
enum jit_builtin_type other_type_id);
|
||||
|
||||
tree
|
||||
make_attrs_tree (enum built_in_attribute attr);
|
||||
|
||||
private:
|
||||
context *m_ctxt;
|
||||
type *m_types[BT_LAST];
|
||||
function *m_builtin_functions[END_BUILTINS];
|
||||
/* Recording fields. */
|
||||
recording::context *m_ctxt;
|
||||
recording::type *m_types[BT_LAST];
|
||||
recording::function *m_builtin_functions[END_BUILTINS];
|
||||
|
||||
/* Playback fields. */
|
||||
/* m_attributes is not GTY-marked, but is only ever used from within
|
||||
the region of playback::context::replay () in which a GC can't
|
||||
happen. */
|
||||
tree m_attributes[ATTR_LAST];
|
||||
};
|
||||
|
||||
} // namespace recording
|
||||
} // namespace jit
|
||||
} // namespace gcc
|
||||
|
||||
|
@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_FILE_PTR + 1;
|
||||
const int NUM_GCC_JIT_TYPES = GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE + 1;
|
||||
|
||||
/* This comment is included by the docs.
|
||||
|
||||
@ -97,6 +97,7 @@ namespace jit {
|
||||
|
||||
class result;
|
||||
class dump;
|
||||
class builtins_manager; // declared within jit-builtins.h
|
||||
|
||||
namespace recording {
|
||||
|
||||
@ -104,7 +105,6 @@ namespace recording {
|
||||
|
||||
/* Indentation indicates inheritance: */
|
||||
class context;
|
||||
class builtins_manager; // declared within jit-builtins.h
|
||||
class memento;
|
||||
class string;
|
||||
class location;
|
||||
|
@ -46,10 +46,12 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "print-tree.h"
|
||||
#include "gimplify.h"
|
||||
#include "gcc-driver-name.h"
|
||||
#include "attribs.h"
|
||||
|
||||
#include "jit-common.h"
|
||||
#include "jit-playback.h"
|
||||
#include "jit-result.h"
|
||||
#include "jit-builtins.h"
|
||||
|
||||
|
||||
/* gcc::jit::playback::context::build_cast uses the convert.h API,
|
||||
@ -198,6 +200,13 @@ get_tree_node_for_type (enum gcc_jit_types type_)
|
||||
|
||||
case GCC_JIT_TYPE_FILE_PTR:
|
||||
return fileptr_type_node;
|
||||
|
||||
case GCC_JIT_TYPE_COMPLEX_FLOAT:
|
||||
return complex_float_type_node;
|
||||
case GCC_JIT_TYPE_COMPLEX_DOUBLE:
|
||||
return complex_double_type_node;
|
||||
case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
|
||||
return complex_long_double_type_node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -399,10 +408,21 @@ new_function (location *loc,
|
||||
|
||||
if (builtin_id)
|
||||
{
|
||||
DECL_BUILT_IN_CLASS (fndecl) = BUILT_IN_NORMAL;
|
||||
DECL_FUNCTION_CODE (fndecl) = builtin_id;
|
||||
gcc_assert (loc == NULL);
|
||||
DECL_SOURCE_LOCATION (fndecl) = BUILTINS_LOCATION;
|
||||
|
||||
DECL_BUILT_IN_CLASS (fndecl) =
|
||||
builtins_manager::get_class (builtin_id);
|
||||
set_builtin_decl (builtin_id, fndecl,
|
||||
builtins_manager::implicit_p (builtin_id));
|
||||
|
||||
builtins_manager *bm = get_builtins_manager ();
|
||||
tree attrs = bm->get_attrs_tree (builtin_id);
|
||||
if (attrs)
|
||||
decl_attributes (&fndecl, attrs, ATTR_FLAG_BUILT_IN);
|
||||
else
|
||||
decl_attributes (&fndecl, NULL_TREE, 0);
|
||||
}
|
||||
|
||||
if (kind != GCC_JIT_FUNCTION_IMPORTED)
|
||||
@ -1795,6 +1815,14 @@ replay ()
|
||||
refs. Hence we must stop using them before the GC can run. */
|
||||
m_recording_ctxt->disassociate_from_playback ();
|
||||
|
||||
/* The builtins_manager, if any, is associated with the recording::context
|
||||
and might be reused for future compiles on other playback::contexts,
|
||||
but its m_attributes array is not GTY-labeled and hence will become
|
||||
nonsense if the GC runs. Purge this state. */
|
||||
builtins_manager *bm = get_builtins_manager ();
|
||||
if (bm)
|
||||
bm->finish_playback ();
|
||||
|
||||
timevar_pop (TV_JIT_REPLAY);
|
||||
|
||||
if (!errors_occurred ())
|
||||
|
@ -175,6 +175,11 @@ public:
|
||||
return m_recording_ctxt->get_bool_option (opt);
|
||||
}
|
||||
|
||||
builtins_manager *get_builtins_manager () const
|
||||
{
|
||||
return m_recording_ctxt->get_builtins_manager ();
|
||||
}
|
||||
|
||||
result *
|
||||
compile ();
|
||||
|
||||
|
@ -580,6 +580,25 @@ recording::context::new_function (recording::location *loc,
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Locate the builtins_manager (if any) for this family of contexts,
|
||||
creating it if it doesn't exist already.
|
||||
|
||||
All of the recording contexts in a family share one builtins_manager:
|
||||
if we have a child context, follow the parent links to get the
|
||||
ultimate ancestor context, and look for it/store it there. */
|
||||
|
||||
builtins_manager *
|
||||
recording::context::get_builtins_manager ()
|
||||
{
|
||||
if (m_parent_ctxt)
|
||||
return m_parent_ctxt->get_builtins_manager ();
|
||||
|
||||
if (!m_builtins_manager)
|
||||
m_builtins_manager = new builtins_manager (this);
|
||||
|
||||
return m_builtins_manager;
|
||||
}
|
||||
|
||||
/* Get a recording::function instance, which is lazily-created and added
|
||||
to the context's lists of mementos.
|
||||
|
||||
@ -589,9 +608,8 @@ recording::context::new_function (recording::location *loc,
|
||||
recording::function *
|
||||
recording::context::get_builtin_function (const char *name)
|
||||
{
|
||||
if (!m_builtins_manager)
|
||||
m_builtins_manager = new builtins_manager (this);
|
||||
return m_builtins_manager->get_builtin_function (name);
|
||||
builtins_manager *bm = get_builtins_manager ();
|
||||
return bm->get_builtin_function (name);
|
||||
}
|
||||
|
||||
/* Create a recording::global instance and add it to this context's list
|
||||
@ -1248,6 +1266,9 @@ recording::memento_of_get_type::dereference ()
|
||||
case GCC_JIT_TYPE_FLOAT:
|
||||
case GCC_JIT_TYPE_DOUBLE:
|
||||
case GCC_JIT_TYPE_LONG_DOUBLE:
|
||||
case GCC_JIT_TYPE_COMPLEX_FLOAT:
|
||||
case GCC_JIT_TYPE_COMPLEX_DOUBLE:
|
||||
case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
|
||||
/* Not a pointer: */
|
||||
return NULL;
|
||||
|
||||
@ -1309,6 +1330,11 @@ recording::memento_of_get_type::is_int () const
|
||||
|
||||
case GCC_JIT_TYPE_FILE_PTR:
|
||||
return false;
|
||||
|
||||
case GCC_JIT_TYPE_COMPLEX_FLOAT:
|
||||
case GCC_JIT_TYPE_COMPLEX_DOUBLE:
|
||||
case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1357,6 +1383,11 @@ recording::memento_of_get_type::is_float () const
|
||||
|
||||
case GCC_JIT_TYPE_FILE_PTR:
|
||||
return false;
|
||||
|
||||
case GCC_JIT_TYPE_COMPLEX_FLOAT:
|
||||
case GCC_JIT_TYPE_COMPLEX_DOUBLE:
|
||||
case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1405,6 +1436,11 @@ recording::memento_of_get_type::is_bool () const
|
||||
|
||||
case GCC_JIT_TYPE_FILE_PTR:
|
||||
return false;
|
||||
|
||||
case GCC_JIT_TYPE_COMPLEX_FLOAT:
|
||||
case GCC_JIT_TYPE_COMPLEX_DOUBLE:
|
||||
case GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1451,7 +1487,11 @@ static const char * const get_type_strings[] = {
|
||||
|
||||
"size_t", /* GCC_JIT_TYPE_SIZE_T */
|
||||
|
||||
"FILE *" /* GCC_JIT_TYPE_FILE_PTR */
|
||||
"FILE *", /* GCC_JIT_TYPE_FILE_PTR */
|
||||
|
||||
"complex float", /* GCC_JIT_TYPE_COMPLEX_FLOAT */
|
||||
"complex double", /* GCC_JIT_TYPE_COMPLEX_DOUBLE */
|
||||
"complex long double" /* GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE */
|
||||
|
||||
};
|
||||
|
||||
|
@ -52,6 +52,9 @@ public:
|
||||
context (context *parent_ctxt);
|
||||
~context ();
|
||||
|
||||
builtins_manager *
|
||||
get_builtins_manager ();
|
||||
|
||||
void record (memento *m);
|
||||
void replay_into (replayer *r);
|
||||
void disassociate_from_playback ();
|
||||
|
@ -382,7 +382,13 @@ enum gcc_jit_types
|
||||
GCC_JIT_TYPE_SIZE_T,
|
||||
|
||||
/* C type: (FILE *) */
|
||||
GCC_JIT_TYPE_FILE_PTR
|
||||
GCC_JIT_TYPE_FILE_PTR,
|
||||
|
||||
/* Complex numbers. */
|
||||
GCC_JIT_TYPE_COMPLEX_FLOAT,
|
||||
GCC_JIT_TYPE_COMPLEX_DOUBLE,
|
||||
GCC_JIT_TYPE_COMPLEX_LONG_DOUBLE
|
||||
|
||||
};
|
||||
|
||||
extern gcc_jit_type *
|
||||
|
Loading…
Reference in New Issue
Block a user