summaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c86
1 files changed, 58 insertions, 28 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 558a708c5f9..32a6396bd70 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3801,7 +3801,7 @@ struct no_conflict_data
static void
no_conflict_move_test (rtx dest, const_rtx set, void *p0)
{
- struct no_conflict_data *p= p0;
+ struct no_conflict_data *p= (struct no_conflict_data *) p0;
/* If this inns directly contributes to setting the target, it must stay. */
if (reg_overlap_mentioned_p (p->target, dest))
@@ -5463,7 +5463,7 @@ gen_libfunc (optab optable, const char *opname, int suffix, enum machine_mode mo
unsigned opname_len = strlen (opname);
const char *mname = GET_MODE_NAME (mode);
unsigned mname_len = strlen (mname);
- char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
+ char *libfunc_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
char *p;
const char *q;
@@ -5511,7 +5511,7 @@ gen_fp_libfunc (optab optable, const char *opname, char suffix,
gen_libfunc (optable, opname, suffix, mode);
if (DECIMAL_FLOAT_MODE_P (mode))
{
- dec_opname = alloca (sizeof (DECIMAL_PREFIX) + strlen (opname));
+ dec_opname = XALLOCAVEC (char, sizeof (DECIMAL_PREFIX) + strlen (opname));
/* For BID support, change the name to have either a bid_ or dpd_ prefix
depending on the low level floating format used. */
memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
@@ -5579,7 +5579,7 @@ gen_intv_fp_libfunc (optab optable, const char *name, char suffix,
if (GET_MODE_CLASS (mode) == MODE_INT)
{
int len = strlen (name);
- char *v_name = alloca (len + 2);
+ char *v_name = XALLOCAVEC (char, len + 2);
strcpy (v_name, name);
v_name[len] = 'v';
v_name[len + 1] = 0;
@@ -5683,13 +5683,13 @@ gen_interclass_conv_libfunc (convert_optab tab,
mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
- nondec_name = alloca (2 + opname_len + mname_len + 1 + 1);
+ nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
nondec_name[0] = '_';
nondec_name[1] = '_';
memcpy (&nondec_name[2], opname, opname_len);
nondec_suffix = nondec_name + opname_len + 2;
- dec_name = alloca (2 + dec_len + opname_len + mname_len + 1 + 1);
+ dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
dec_name[0] = '_';
dec_name[1] = '_';
memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
@@ -5808,13 +5808,13 @@ gen_intraclass_conv_libfunc (convert_optab tab, const char *opname,
mname_len = strlen (GET_MODE_NAME (tmode)) + strlen (GET_MODE_NAME (fmode));
- nondec_name = alloca (2 + opname_len + mname_len + 1 + 1);
+ nondec_name = XALLOCAVEC (char, 2 + opname_len + mname_len + 1 + 1);
nondec_name[0] = '_';
nondec_name[1] = '_';
memcpy (&nondec_name[2], opname, opname_len);
nondec_suffix = nondec_name + opname_len + 2;
- dec_name = alloca (2 + dec_len + opname_len + mname_len + 1 + 1);
+ dec_name = XALLOCAVEC (char, 2 + dec_len + opname_len + mname_len + 1 + 1);
dec_name[0] = '_';
dec_name[1] = '_';
memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
@@ -5984,28 +5984,58 @@ gen_satfractuns_conv_libfunc (convert_optab tab,
gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
}
-rtx
-init_one_libfunc (const char *name)
-{
- rtx symbol;
+/* A table of previously-created libfuncs, hashed by name. */
+static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
- /* Create a FUNCTION_DECL that can be passed to
- targetm.encode_section_info. */
- /* ??? We don't have any type information except for this is
- a function. Pretend this is "int foo()". */
- tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
- build_function_type (integer_type_node, NULL_TREE));
- DECL_ARTIFICIAL (decl) = 1;
- DECL_EXTERNAL (decl) = 1;
- TREE_PUBLIC (decl) = 1;
+/* Hashtable callbacks for libfunc_decls. */
- symbol = XEXP (DECL_RTL (decl), 0);
+static hashval_t
+libfunc_decl_hash (const void *entry)
+{
+ return htab_hash_string (IDENTIFIER_POINTER (DECL_NAME ((const_tree) entry)));
+}
- /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
- are the flags assigned by targetm.encode_section_info. */
- SET_SYMBOL_REF_DECL (symbol, 0);
+static int
+libfunc_decl_eq (const void *entry1, const void *entry2)
+{
+ return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
+}
- return symbol;
+rtx
+init_one_libfunc (const char *name)
+{
+ tree id, decl;
+ void **slot;
+ hashval_t hash;
+
+ if (libfunc_decls == NULL)
+ libfunc_decls = htab_create_ggc (37, libfunc_decl_hash,
+ libfunc_decl_eq, NULL);
+
+ /* See if we have already created a libfunc decl for this function. */
+ id = get_identifier (name);
+ hash = htab_hash_string (name);
+ slot = htab_find_slot_with_hash (libfunc_decls, id, hash, INSERT);
+ decl = (tree) *slot;
+ if (decl == NULL)
+ {
+ /* Create a new decl, so that it can be passed to
+ targetm.encode_section_info. */
+ /* ??? We don't have any type information except for this is
+ a function. Pretend this is "int foo()". */
+ decl = build_decl (FUNCTION_DECL, get_identifier (name),
+ build_function_type (integer_type_node, NULL_TREE));
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_EXTERNAL (decl) = 1;
+ TREE_PUBLIC (decl) = 1;
+
+ /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
+ are the flags assigned by targetm.encode_section_info. */
+ SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
+
+ *slot = decl;
+ }
+ return XEXP (DECL_RTL (decl), 0);
}
/* Call this to reset the function entry for one optab (OPTABLE) in mode
@@ -6026,7 +6056,7 @@ set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
val = 0;
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
if (*slot == NULL)
- *slot = ggc_alloc (sizeof (struct libfunc_entry));
+ *slot = GGC_NEW (struct libfunc_entry);
(*slot)->optab = (size_t) (optable - &optab_table[0]);
(*slot)->mode1 = mode;
(*slot)->mode2 = VOIDmode;
@@ -6053,7 +6083,7 @@ set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
val = 0;
slot = (struct libfunc_entry **) htab_find_slot (libfunc_hash, &e, INSERT);
if (*slot == NULL)
- *slot = ggc_alloc (sizeof (struct libfunc_entry));
+ *slot = GGC_NEW (struct libfunc_entry);
(*slot)->optab = (size_t) (optable - &convert_optab_table[0]);
(*slot)->mode1 = tmode;
(*slot)->mode2 = fmode;