re PR tree-optimization/82434 (-fstore-merging does not work reliably.)
authorJakub Jelinek <jakub@redhat.com>
Fri, 6 Oct 2017 09:39:07 +0000 (11:39 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 6 Oct 2017 09:39:07 +0000 (11:39 +0200)
PR tree-optimization/82434
* fold-const.h (can_native_encode_type_p,
can_native_encode_string_p): Remove.
* fold-const.c (native_encode_int): Formatting fixes.  If ptr is NULL,
don't encode anything, just return what would be otherwise returned.
(native_encode_fixed, native_encode_complex, native_encode_vector):
Likewise.
(native_encode_string): Likewise.  Inline by hand
can_native_encode_string_p.
(can_native_encode_type_p): Remove.
(can_native_encode_string_p): Remove.
* tree-vect-stmts.c (vectorizable_store): Instead of testing just
STRING_CSTs using can_native_encode_string_p, test all
CONSTANT_CLASS_P values using native_encode_expr with NULL ptr.
* gimple-ssa-store-merging.c (encode_tree_to_bitpos): Remove last
argument from native_encode_expr.
(rhs_valid_for_store_merging_p): Use native_encode_expr with NULL ptr.
(pass_store_merging::execute): Don't unnecessarily look for 3 stmts,
but just 2.

* gcc.dg/store_merging_9.c: New test.

From-SVN: r253483

gcc/ChangeLog
gcc/fold-const.c
gcc/fold-const.h
gcc/gimple-ssa-store-merging.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/store_merging_9.c [new file with mode: 0644]
gcc/tree-vect-stmts.c

index a5666868b74b966c00f8eeafb147bf24d51b468c..1aec8d306800a58c27bb81297976a43a9c7e3ba4 100644 (file)
@@ -1,3 +1,25 @@
+2017-10-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/82434
+       * fold-const.h (can_native_encode_type_p,
+       can_native_encode_string_p): Remove.
+       * fold-const.c (native_encode_int): Formatting fixes.  If ptr is NULL,
+       don't encode anything, just return what would be otherwise returned.
+       (native_encode_fixed, native_encode_complex, native_encode_vector):
+       Likewise.
+       (native_encode_string): Likewise.  Inline by hand
+       can_native_encode_string_p.
+       (can_native_encode_type_p): Remove.
+       (can_native_encode_string_p): Remove.
+       * tree-vect-stmts.c (vectorizable_store): Instead of testing just
+       STRING_CSTs using can_native_encode_string_p, test all
+       CONSTANT_CLASS_P values using native_encode_expr with NULL ptr.
+       * gimple-ssa-store-merging.c (encode_tree_to_bitpos): Remove last
+       argument from native_encode_expr.
+       (rhs_valid_for_store_merging_p): Use native_encode_expr with NULL ptr.
+       (pass_store_merging::execute): Don't unnecessarily look for 3 stmts,
+       but just 2.
+
 2017-10-06  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/82397
index ae037ce14fbfd2c01bc474b6770186d90f3bec39..d8dc56cea6b7dbb601d7e3605da03c123e9285cd 100644 (file)
@@ -6982,11 +6982,15 @@ native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
   int byte, offset, word, words;
   unsigned char value;
 
-  if ((off == -1 && total_bytes > len)
-      || off >= total_bytes)
+  if ((off == -1 && total_bytes > len) || off >= total_bytes)
     return 0;
   if (off == -1)
     off = 0;
+
+  if (ptr == NULL)
+    /* Dry run.  */
+    return MIN (len, total_bytes - off);
+
   words = total_bytes / UNITS_PER_WORD;
 
   for (byte = 0; byte < total_bytes; byte++)
@@ -7009,8 +7013,7 @@ native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
        }
       else
        offset = BYTES_BIG_ENDIAN ? (total_bytes - 1) - byte : byte;
-      if (offset >= off
-         && offset - off < len)
+      if (offset >= off && offset - off < len)
        ptr[offset - off] = value;
     }
   return MIN (len, total_bytes - off);
@@ -7036,8 +7039,7 @@ native_encode_fixed (const_tree expr, unsigned char *ptr, int len, int off)
 
   i_type = lang_hooks.types.type_for_size (GET_MODE_BITSIZE (mode), 1);
 
-  if (NULL_TREE == i_type
-      || TYPE_PRECISION (i_type) != total_bytes)
+  if (NULL_TREE == i_type || TYPE_PRECISION (i_type) != total_bytes)
     return 0;
   
   value = TREE_FIXED_CST (expr);
@@ -7065,11 +7067,15 @@ native_encode_real (const_tree expr, unsigned char *ptr, int len, int off)
      up to 192 bits.  */
   long tmp[6];
 
-  if ((off == -1 && total_bytes > len)
-      || off >= total_bytes)
+  if ((off == -1 && total_bytes > len) || off >= total_bytes)
     return 0;
   if (off == -1)
     off = 0;
+
+  if (ptr == NULL)
+    /* Dry run.  */
+    return MIN (len, total_bytes - off);
+
   words = (32 / BITS_PER_UNIT) / UNITS_PER_WORD;
 
   real_to_target (tmp, TREE_REAL_CST_PTR (expr), TYPE_MODE (type));
@@ -7123,15 +7129,14 @@ native_encode_complex (const_tree expr, unsigned char *ptr, int len, int off)
 
   part = TREE_REALPART (expr);
   rsize = native_encode_expr (part, ptr, len, off);
-  if (off == -1
-      && rsize == 0)
+  if (off == -1 && rsize == 0)
     return 0;
   part = TREE_IMAGPART (expr);
   if (off != -1)
     off = MAX (0, off - GET_MODE_SIZE (SCALAR_TYPE_MODE (TREE_TYPE (part))));
-  isize = native_encode_expr (part, ptr+rsize, len-rsize, off);
-  if (off == -1
-      && isize != rsize)
+  isize = native_encode_expr (part, ptr ? ptr + rsize : NULL,
+                             len - rsize, off);
+  if (off == -1 && isize != rsize)
     return 0;
   return rsize + isize;
 }
@@ -7161,9 +7166,9 @@ native_encode_vector (const_tree expr, unsigned char *ptr, int len, int off)
          continue;
        }
       elem = VECTOR_CST_ELT (expr, i);
-      int res = native_encode_expr (elem, ptr+offset, len-offset, off);
-      if ((off == -1 && res != size)
-         || res == 0)
+      int res = native_encode_expr (elem, ptr ? ptr + offset : NULL,
+                                   len - offset, off);
+      if ((off == -1 && res != size) || res == 0)
        return 0;
       offset += res;
       if (offset >= len)
@@ -7183,16 +7188,24 @@ native_encode_vector (const_tree expr, unsigned char *ptr, int len, int off)
 static int
 native_encode_string (const_tree expr, unsigned char *ptr, int len, int off)
 {
-  if (! can_native_encode_string_p (expr))
+  tree type = TREE_TYPE (expr);
+
+  /* Wide-char strings are encoded in target byte-order so native
+     encoding them is trivial.  */
+  if (BITS_PER_UNIT != CHAR_BIT
+      || TREE_CODE (type) != ARRAY_TYPE
+      || TREE_CODE (TREE_TYPE (type)) != INTEGER_TYPE
+      || !tree_fits_shwi_p (TYPE_SIZE_UNIT (type)))
     return 0;
 
   HOST_WIDE_INT total_bytes = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
-  if ((off == -1 && total_bytes > len)
-      || off >= total_bytes)
+  if ((off == -1 && total_bytes > len) || off >= total_bytes)
     return 0;
   if (off == -1)
     off = 0;
-  if (TREE_STRING_LENGTH (expr) - off < MIN (total_bytes, len))
+  if (ptr == NULL)
+    /* Dry run.  */;
+  else if (TREE_STRING_LENGTH (expr) - off < MIN (total_bytes, len))
     {
       int written = 0;
       if (off < TREE_STRING_LENGTH (expr))
@@ -7211,7 +7224,8 @@ native_encode_string (const_tree expr, unsigned char *ptr, int len, int off)
 
 /* Subroutine of fold_view_convert_expr.  Encode the INTEGER_CST,
    REAL_CST, COMPLEX_CST or VECTOR_CST specified by EXPR into the
-   buffer PTR of length LEN bytes.  If OFF is not -1 then start
+   buffer PTR of length LEN bytes.  If PTR is NULL, don't actually store
+   anything, just do a dry run.  If OFF is not -1 then start
    the encoding at byte offset OFF and encode at most LEN bytes.
    Return the number of bytes placed in the buffer, or zero upon failure.  */
 
@@ -7459,43 +7473,6 @@ can_native_interpret_type_p (tree type)
     }
 }
 
-/* Return true iff a constant of type TYPE is accepted by
-   native_encode_expr.  */
-
-bool
-can_native_encode_type_p (tree type)
-{
-  switch (TREE_CODE (type))
-    {
-    case INTEGER_TYPE:
-    case REAL_TYPE:
-    case FIXED_POINT_TYPE:
-    case COMPLEX_TYPE:
-    case VECTOR_TYPE:
-    case POINTER_TYPE:
-      return true;
-    default:
-      return false;
-    }
-}
-
-/* Return true iff a STRING_CST S is accepted by
-   native_encode_expr.  */
-
-bool
-can_native_encode_string_p (const_tree expr)
-{
-  tree type = TREE_TYPE (expr);
-
-  /* Wide-char strings are encoded in target byte-order so native
-     encoding them is trivial.  */
-  if (BITS_PER_UNIT != CHAR_BIT
-      || TREE_CODE (type) != ARRAY_TYPE
-      || TREE_CODE (TREE_TYPE (type)) != INTEGER_TYPE
-      || !tree_fits_shwi_p (TYPE_SIZE_UNIT (type)))
-    return false;
-  return true;
-}
 
 /* Fold a VIEW_CONVERT_EXPR of a constant expression EXPR to type
    TYPE at compile-time.  If we're unable to perform the conversion
index 46d563953ce94411ba3fb29258367534ba19c2e2..0684ae762350730eba38f7caed3b961582f284f0 100644 (file)
@@ -27,8 +27,6 @@ extern int folding_initializer;
 /* Convert between trees and native memory representation.  */
 extern int native_encode_expr (const_tree, unsigned char *, int, int off = -1);
 extern tree native_interpret_expr (tree, const unsigned char *, int);
-extern bool can_native_encode_type_p (tree);
-extern bool can_native_encode_string_p (const_tree);
 
 /* Fold constants as much as possible in an expression.
    Returns the simplified expression.
index cb764032205a8233f826178e799a26ee3ae41083..bc50bab3bae76165a9d4e4b886b17a3e1b9bcf53 100644 (file)
@@ -357,8 +357,7 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
                        || !int_mode_for_size (bitlen, 0).exists ());
 
   if (!sub_byte_op_p)
-    return (native_encode_expr (tmp_int, ptr + first_byte, total_bytes, 0)
-           != 0);
+    return native_encode_expr (tmp_int, ptr + first_byte, total_bytes) != 0;
 
   /* LITTLE-ENDIAN
      We are writing a non byte-sized quantity or at a position that is not
@@ -408,7 +407,7 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
   memset (tmpbuf, '\0', byte_size);
   /* The store detection code should only have allowed constants that are
      accepted by native_encode_expr.  */
-  if (native_encode_expr (expr, tmpbuf, byte_size - 1, 0) == 0)
+  if (native_encode_expr (expr, tmpbuf, byte_size - 1) == 0)
     gcc_unreachable ();
 
   /* The native_encode_expr machinery uses TYPE_MODE to determine how many
@@ -1326,12 +1325,8 @@ lhs_valid_for_store_merging_p (tree lhs)
 static bool
 rhs_valid_for_store_merging_p (tree rhs)
 {
-  tree type = TREE_TYPE (rhs);
-  if (TREE_CODE_CLASS (TREE_CODE (rhs)) != tcc_constant
-      || !can_native_encode_type_p (type))
-    return false;
-
-  return true;
+  return native_encode_expr (rhs, NULL,
+                            GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (rhs)))) != 0;
 }
 
 /* Entry point for the pass.  Go over each basic block recording chains of
@@ -1357,7 +1352,7 @@ pass_store_merging::execute (function *fun)
          if (is_gimple_debug (gsi_stmt (gsi)))
            continue;
 
-         if (++num_statements > 2)
+         if (++num_statements >= 2)
            break;
        }
 
index cf7f2c82a37bb785f4b113f06d70b3991c7981b0..266bedc792ae01acccbb3748a8feb15b99d3f6cb 100644 (file)
@@ -1,3 +1,8 @@
+2017-10-06  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/82434
+       * gcc.dg/store_merging_9.c: New test.
+
 2017-10-06  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/82397
diff --git a/gcc/testsuite/gcc.dg/store_merging_9.c b/gcc/testsuite/gcc.dg/store_merging_9.c
new file mode 100644 (file)
index 0000000..4c9f21e
--- /dev/null
@@ -0,0 +1,33 @@
+/* PR tree-optimization/82434 */
+/* { dg-do compile } */
+/* { dg-require-effective-target store_merge } */
+/* { dg-options "-O2 -fdump-tree-store-merging" } */
+
+enum E { E0, E1, E2 = __INT_MAX__, E3 = -__INT_MAX__ - 1 };
+
+struct bar {
+  enum E a;
+  char b;
+  _Bool c;
+  short d;
+};
+
+void
+foo1 (struct bar *p)
+{
+  p->b = 0;
+  p->a = E0;
+  p->c = (_Bool) 0;
+  p->d = 0;
+}
+
+void
+foo2 (struct bar *p)
+{
+  p->b = 0;
+  p->a = E0;
+  p->c = (_Bool) 1;
+  p->d = 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Merging successful" 2 "store-merging" } } */
index 29b733324d751cb9c98546327f7d808e9f217285..f986b753c83b3bfe1ff36be7a70e8c0017bbbc9c 100644 (file)
@@ -5728,10 +5728,9 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
 
   op = gimple_assign_rhs1 (stmt);
 
-  /* In the case this is a store from a STRING_CST make sure
+  /* In the case this is a store from a constant make sure
      native_encode_expr can handle it.  */
-  if (TREE_CODE (op) == STRING_CST
-      && ! can_native_encode_string_p (op))
+  if (CONSTANT_CLASS_P (op) && native_encode_expr (op, NULL, 64) == 0)
     return false;
 
   if (!vect_is_simple_use (op, vinfo, &def_stmt, &dt, &rhs_vectype))