[Bug middle-end/56888] memcpy implementation optimized as a call to memcpy

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Tue Apr 29 14:16:00 GMT 2014


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56888

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hubicka at gcc dot gnu.org

--- Comment #27 from Richard Biener <rguenth at gcc dot gnu.org> ---
Ok, so looking at this again.

We don't have a cgraph node for builtin_decl_(implicit|explicit)
(BUILT_IN_MEMSET).

But it seems that decl has DECL_ASSEMBLER_NAME_SET_P (not sure if set
"correctly" though).

So we can use symtab_node_for_asm (DECL_ASSEMBLER_NAME ()) and
eventually get to symtab_alias_target of that and check if it
is equal to the current function.

Index: gcc/tree-loop-distribution.c
===================================================================
--- gcc/tree-loop-distribution.c        (revision 209892)
+++ gcc/tree-loop-distribution.c        (working copy)
@@ -71,6 +71,7 @@ along with GCC; see the file COPYING3.
 #include "tree-pass.h"
 #include "gimple-pretty-print.h"
 #include "tree-vectorizer.h"
+#include "cgraph.h"


 /* A Reduced Dependence Graph (RDG) vertex representing a statement.  */
@@ -1084,6 +1085,15 @@ classify_partition (loop_p loop, struct
          || !dominated_by_p (CDI_DOMINATORS,
                              loop->latch, gimple_bb (stmt)))
        return;
+      tree fn = builtin_decl_implicit (BUILT_IN_MEMSET);
+      if (DECL_ASSEMBLER_NAME_SET_P (fn))
+       {
+         symtab_node *n1 = symtab_node_for_asm (DECL_ASSEMBLER_NAME (fn));
+         symtab_node *n2 = symtab_get_node (cfun->decl);
+         if (n1 == n2
+             || (n1->alias && symtab_alias_target (n1) == n2))
+           return;
+       }
       partition->kind = PKIND_MEMSET;
       partition->main_dr = single_store;
       partition->niter = nb_iter;


fixes the following testcase:

typedef __SIZE_TYPE__ size_t;
extern void *
memset (void *s, int c, size_t n) __attribute__ ((weak, alias("_memset")));

void *
_memset(void *s, int c, size_t n)
{
  char *q = (char *)s;
  while (n != 0)
    {
      *(q++) = c;
      n--;
    }
}

it won't fix glibc as that uses

asm(".alias ....");

for the aliases which we don't parse.

It of course also fixes the very direct recursion.  At least if
the assembler name of the builtin agrees with that of the function.

Honza, is there a more "fancy" way of doing this?



More information about the Gcc-bugs mailing list