re PR tree-optimization/82434 (-fstore-merging does not work reliably.)
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
This commit is contained in:
parent
d20eac1b41
commit
2f3914287d
7 changed files with 102 additions and 73 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
33
gcc/testsuite/gcc.dg/store_merging_9.c
Normal file
33
gcc/testsuite/gcc.dg/store_merging_9.c
Normal file
|
@ -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" } } */
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue