https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87627

--- Comment #6 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
FWIW the following CSE enhancement cleans this up, but I'm unhappy with this
patch because it's too narrowly targeted; in particular, won't clean up

void g(int a, int *b, int c);
void f(int a, int *b, int c)
{
  if (a) *b = c;
  g(a, b, c);
}

Had to special-case for PARM_DECL because, in general, automatic variables that
are not address-taken on GIMPLE can become addressable on RTL when ABI requires
passing a large argument by reference.

--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2232,6 +2232,15 @@ hash_rtx_string (const char *ps)
   return hash;
 }

+static bool
+mem_escapes_p (const_rtx x)
+{
+  tree decl = MEM_EXPR (x);
+  if (!decl || TREE_CODE (decl) != PARM_DECL)
+    return true;
+  return may_be_aliased (decl);
+}
+
 /* Same as hash_rtx, but call CB on each rtx if it is not NULL.
    When the callback returns true, we continue with the new rtx.  */

@@ -2421,7 +2430,8 @@ hash_rtx_cb (const_rtx x, machine_mode mode,
          return 0;
        }
       if (hash_arg_in_memory_p && !MEM_READONLY_P (x))
-       *hash_arg_in_memory_p = 1;
+       if (*hash_arg_in_memory_p != 1)
+         *hash_arg_in_memory_p = mem_escapes_p (x) ? 1 : 2;

       /* Now that we have already found this special case,
         might as well speed it up as much as possible.  */
@@ -6127,7 +6137,7 @@ invalidate_memory (void)
     for (p = table[i]; p; p = next)
       {
        next = p->next_same_hash;
-       if (p->in_memory)
+       if (p->in_memory == 1)
          remove_from_table (p, i);
       }
 }

Reply via email to