* RFA: init_one_libfunc vs. target_reinit
@ 2008-06-26 21:24 Richard Sandiford
2008-06-27 22:51 ` Mark Mitchell
0 siblings, 1 reply; 2+ messages in thread
From: Richard Sandiford @ 2008-06-26 21:24 UTC (permalink / raw)
To: gcc-patches
Following on from:
http://gcc.gnu.org/ml/gcc-patches/2008-06/msg01700.html
this is another patch aimed at making:
...switch to a new subtarget...
target_reinit ();
...switch back to the old subtarget...
target_reinit ();
a no-op.
target_reinit calls init_optabs, which in turn uses init_one_libfunc to
set up various library functions. The problem is that init_one_libfunc
creates a new decl each time it is called, causing the sequence above
to change both the DECL_UID and SYMBOL_REF of something like
memcpy_libfunc.
The libfunc decls themselves aren't particularly important; we just
use their SYMBOL_REFs. However, allocating DECL_UIDs affects every
decl created after that, leading to spurious differences in the names
of nested functions.
This patch uses a hashtable to make sure that set_one_libfunc uses
the same decl and symbol for a given name. I realise that this
will in theory add extra set-up overhead to targets that don't
use target_reinit, but the number of libfuncs is actually pretty small.
I wondered about conditionialising the hashtable code on a
"reinitialising?" predicate, but the first init_optabs would then
behave differently from subsequent init_optabs if two libfuncs
happen to share the same external routine.
Also, I believe function-specific-branch makes more use of target_reinit,
so I hope this sort of thing will be of general use than just MIPS.
Tested on mipsisa64-elfoabi and x86_64-linux-gnu. OK to install?
Richard
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.
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c 2008-06-24 21:27:58.000000000 +0100
+++ gcc/optabs.c 2008-06-24 21:30:14.000000000 +0100
@@ -5984,28 +5984,58 @@ gen_satfractuns_conv_libfunc (convert_op
gen_interclass_conv_libfunc (tab, opname, tmode, fmode);
}
+/* A table of previously-created libfuncs, hashed by name. */
+static GTY ((param_is (union tree_node))) htab_t libfunc_decls;
+
+/* Hashtable callbacks for libfunc_decls. */
+
+static hashval_t
+libfunc_decl_hash (const void *entry)
+{
+ return htab_hash_string (IDENTIFIER_POINTER (DECL_NAME ((tree) entry)));
+}
+
+static int
+libfunc_decl_eq (const void *entry1, const void *entry2)
+{
+ return DECL_NAME ((tree) entry1) == (tree) entry2;
+}
+
rtx
init_one_libfunc (const char *name)
{
- rtx symbol;
-
- /* 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;
-
- symbol = XEXP (DECL_RTL (decl), 0);
-
- /* 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);
+ 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);
- return symbol;
+ *slot = decl;
+ }
+ return XEXP (DECL_RTL (decl), 0);
}
/* Call this to reset the function entry for one optab (OPTABLE) in mode
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: RFA: init_one_libfunc vs. target_reinit
2008-06-26 21:24 RFA: init_one_libfunc vs. target_reinit Richard Sandiford
@ 2008-06-27 22:51 ` Mark Mitchell
0 siblings, 0 replies; 2+ messages in thread
From: Mark Mitchell @ 2008-06-27 22:51 UTC (permalink / raw)
To: gcc-patches, rdsandiford
Richard Sandiford wrote:
>
> 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.
OK.
--
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-06-27 22:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-26 21:24 RFA: init_one_libfunc vs. target_reinit Richard Sandiford
2008-06-27 22:51 ` Mark Mitchell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).