optabs.c (libfunc_decls): New variable.
authorRichard Sandiford <rdsandiford@googlemail.com>
Sat, 28 Jun 2008 09:24:35 +0000 (09:24 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 28 Jun 2008 09:24:35 +0000 (09:24 +0000)
gcc/
* optabs.c (libfunc_decls): New variable.
(libfunc_decl_hash, libfunc_decl_eq): New functions.
(init_one_libfunc): Reuse decls and SYMBOL_REFs when asked
for the same function twice.

From-SVN: r137215

gcc/ChangeLog
gcc/optabs.c

index de6e75b..87b85c0 100644 (file)
@@ -1,3 +1,10 @@
+2008-06-28  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * optabs.c (libfunc_decls): New variable.
+       (libfunc_decl_hash, libfunc_decl_eq): New functions.
+       (init_one_libfunc): Reuse decls and SYMBOL_REFs when asked
+       for the same function twice.
+
 2008-06-27 Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.md (ashlti3, ashrti3, lshrti3): Expand using
index 61c810e..c3377c8 100644 (file)
@@ -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 ((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 ((tree) entry1) == (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