expr.c (store_expr_with_bounds): Handle aggregate moves from BLKmode.
authorJan Hubicka <hubicka@ucw.cz>
Wed, 7 Oct 2015 22:54:35 +0000 (00:54 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 7 Oct 2015 22:54:35 +0000 (22:54 +0000)
* expr.c (store_expr_with_bounds): Handle aggregate moves from
BLKmode.
* gimple-expr.c (useless_type_conversion_p): Do not use TYPE_CANONICAL
to define gimple type system; compare aggregates only by size.

From-SVN: r228586

gcc/ChangeLog
gcc/expr.c
gcc/gimple-expr.c

index 86be03e54770bd54eea2a160b7f7406ba1231aaf..bc6fbc6446f9c82c474d7764aaed49b97a682924 100644 (file)
@@ -1,3 +1,10 @@
+2015-10-07  Jan Hubicka  <hubicka@ucw.cz>
+
+       * expr.c (store_expr_with_bounds): Handle aggregate moves from
+       BLKmode.
+       * gimple-expr.c (useless_type_conversion_p): Do not use TYPE_CANONICAL
+       to define gimple type system; compare aggregates only by size.
+
 2015-10-07  Jeff Law  <law@redhat.com>
 
        * tree-ssa-dom.c (optimize_stmt): Don't set LOOPS_NEED_FIXUP here.
@@ -5,7 +12,6 @@
        here instead.  Tighten test to avoid setting LOOPS_NEED_FIXUP 
        unnecessarily.
 
-@@ -1848,12 +1848,6 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si,
 2015-10-07  Aditya Kumar  <aditya.k7@samsung.com>
            Sebastian Pop  <s.pop@samsung.com>
 
index 6498a63bc90e84fb20bd1c77a45aa6a5526daf4b..6f6554d25c0088149c652e68c61f79682ba444a3 100644 (file)
@@ -5425,6 +5425,14 @@ store_expr_with_bounds (tree exp, rtx target, int call_param_p,
     temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
                          temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
 
+  /* We allow move between structures of same size but different mode.
+     If source is in memory and the mode differs, simply change the memory.  */
+  if (GET_MODE (temp) == BLKmode && GET_MODE (target) != BLKmode)
+    {
+      gcc_assert (MEM_P (temp));
+      temp = adjust_address_nv (temp, GET_MODE (target), 0);
+    }
+
   /* If value was not generated in the target, store it there.
      Convert the value to TARGET's type first if necessary and emit the
      pending incrementations that have been queued when expanding EXP.
index baed63011fa1b136f69e37070bbc870c647d3a3c..2a6ba1aadb919be62589d8eee67f980f814755c5 100644 (file)
@@ -87,11 +87,6 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
   if (inner_type == outer_type)
     return true;
 
-  /* If we know the canonical types, compare them.  */
-  if (TYPE_CANONICAL (inner_type)
-      && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type))
-    return true;
-
   /* Changes in machine mode are never useless conversions unless we
      deal with aggregate types in which case we defer to later checks.  */
   if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)
@@ -270,12 +265,23 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
       return true;
     }
 
-  /* For aggregates we rely on TYPE_CANONICAL exclusively and require
-     explicit conversions for types involving to be structurally
-     compared types.  */
+  /* For aggregates compare only the size.  Accesses to fields do have
+     a type information by themselves and thus we only care if we can i.e.
+     use the types in move operations.  */
   else if (AGGREGATE_TYPE_P (inner_type)
           && TREE_CODE (inner_type) == TREE_CODE (outer_type))
-    return false;
+    return (!TYPE_SIZE (outer_type)
+           || (TYPE_SIZE (inner_type)
+               && operand_equal_p (TYPE_SIZE (inner_type),
+                                   TYPE_SIZE (outer_type), 0)));
+
+  else if (TREE_CODE (inner_type) == OFFSET_TYPE
+          && TREE_CODE (outer_type) == OFFSET_TYPE)
+    return useless_type_conversion_p (TREE_TYPE (outer_type),
+                                     TREE_TYPE (inner_type))
+          && useless_type_conversion_p
+               (TYPE_OFFSET_BASETYPE (outer_type),
+                TYPE_OFFSET_BASETYPE (inner_type));
 
   return false;
 }