@@ -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);
+
+ recording::function *
+ make_builtin_function (enum built_in_function builtin_id);
- type *get_type (enum jit_builtin_type type_id);
+ recording::type *
+ get_type (enum jit_builtin_type type_id);
- type *make_type (enum jit_builtin_type type_id);
+ recording::type *
+ make_type (enum jit_builtin_type type_id);
- type*
+ 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 *