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

--- Comment #6 from Martin Jambor <jamborm at gcc dot gnu.org> ---
The problem is that we now consider MEM_REFs loading a different type
than the one of the underlying DECL as V_C_E and are equally careful
about it.

I this particular case, we have statements like.

MEM[(struct box *)&D.389258].value = pos

Where D.363334 is of type struct adaptor_cursor.  If we follow the
chain of first non-method fields, we get struct adaptor_cursor ->
struct adaptor_value_type_ -> struct adaptor_value_type_2_ -> struct
compressed_pair -> struct tagged -> struct getter -> struct getter ->
struct compressed_tuple_ -> struct box, which is the type of the
MEM_REF itself.

So the MEM_REF is not really a V_C_E but instead represents a bunch of
COMPONENT_REFs.  The following patch makes all of the overhead go away
but I guess the type walking results should be cached somehow and it
also only works for MEM_REFs with zero offset, I'm not sure how likely
it is to get MEM_REFs with equal semantics for fields with non-zero
offset.

diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index eeef31ba496..e94d01e0ffa 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1169,10 +1169,27 @@ contains_vce_or_bfcref_p (const_tree ref)
       || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
     return false;

-  tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
+  tree mem_type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (ref, 0), 0));
   if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
-      != TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
-    return true;
+      != TYPE_MAIN_VARIANT (mem_type))
+    {
+      while (TREE_CODE (mem_type) == RECORD_TYPE)
+       {
+         tree fld;
+         for (fld = TYPE_FIELDS (mem_type); fld; fld = DECL_CHAIN (fld))
+           if (TREE_CODE (fld) == FIELD_DECL)
+             {
+               if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
+                   == TYPE_MAIN_VARIANT (TREE_TYPE (fld)))
+                 return false;
+               mem_type = TREE_TYPE (fld);
+               break;
+             }
+         if (!fld)
+           break;
+       }
+      return true;
+    }

   return false;
 }

Reply via email to