diff options
author | Jakub Jelinek <jakub@redhat.com> | 2013-04-08 10:20:39 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2013-04-08 10:20:39 +0200 |
commit | 401f3a81a6744d27083b8dc65460b5b3e37d3c3a (patch) | |
tree | 77ea0cbf6db3539a8026292020faae8c681fbc6f /gcc | |
parent | 03ed99a89eff22949d9983cb70092127a7a0c190 (diff) | |
download | gcc-401f3a81a6744d27083b8dc65460b5b3e37d3c3a.zip gcc-401f3a81a6744d27083b8dc65460b5b3e37d3c3a.tar.gz gcc-401f3a81a6744d27083b8dc65460b5b3e37d3c3a.tar.bz2 |
tree-loop-distribution.c (const_with_all_bytes_same): New function.
* tree-loop-distribution.c (const_with_all_bytes_same): New function.
(generate_memset_builtin): Only handle integer_all_onesp as -1 val if
TYPE_PRECISION is equal to mode bitsize. Use const_with_all_bytes_same
if possible to compute val.
(classify_partition): Verify CONSTRUCTOR doesn't have any elts.
For QImode integers don't require anything about precision. Use
const_with_all_bytes_same to find out if the constant doesn't have
repeated bytes in it.
* gcc.dg/pr56837.c: New test.
* gcc.dg/tree-ssa/ldist-19.c: Don't check for
"generated memset minus one".
From-SVN: r197568
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr56837.c | 67 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ldist-19.c | 1 | ||||
-rw-r--r-- | gcc/tree-loop-distribution.c | 80 |
5 files changed, 132 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb7076c..31c760a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2013-04-08 Jakub Jelinek <jakub@redhat.com> + + * tree-loop-distribution.c (const_with_all_bytes_same): New function. + (generate_memset_builtin): Only handle integer_all_onesp as -1 val if + TYPE_PRECISION is equal to mode bitsize. Use const_with_all_bytes_same + if possible to compute val. + (classify_partition): Verify CONSTRUCTOR doesn't have any elts. + For QImode integers don't require anything about precision. Use + const_with_all_bytes_same to find out if the constant doesn't have + repeated bytes in it. + 2013-04-08 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * config/s390/s390.c (s390_expand_insv): Only accept insertions diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 15896c3..ad15b18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-04-08 Jakub Jelinek <jakub@redhat.com> + + * gcc.dg/pr56837.c: New test. + * gcc.dg/tree-ssa/ldist-19.c: Don't check for + "generated memset minus one". + 2013-04-07 Tobias Burnus <burnus@net-b.de> PR fortran/56849 diff --git a/gcc/testsuite/gcc.dg/pr56837.c b/gcc/testsuite/gcc.dg/pr56837.c new file mode 100644 index 0000000..d665a6d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr56837.c @@ -0,0 +1,67 @@ +/* Limit this test to selected targets with IEEE double, 8-byte long long, + supported 4x int vectors, 4-byte int. */ +/* { dg-do compile { target { i?86-*-* x86_64-*-* powerpc*-*-* } } } */ +/* { dg-options "-O3 -fdump-tree-optimized" } */ +/* { dg-additional-options "-msse2" { target ia32 } } */ +/* { dg-additional-options "-mvsx -maltivec" { target powerpc*-*-* } } */ + +typedef int V __attribute__((__vector_size__ (16))); +#define N 1024 +double d[N]; +long long int l[N]; +_Bool b[N]; +_Complex double c[N]; +V v[N]; + +void +fd (void) +{ + int i; + for (i = 0; i < N; i++) + d[i] = 747708026454360457216.0; +} + +void +fl (void) +{ + int i; + for (i = 0; i < N; i++) + l[i] = 0x7c7c7c7c7c7c7c7cULL; +} + +void +fb (void) +{ + int i; + for (i = 0; i < N; i++) + b[i] = 1; +} + +void +fc (void) +{ + int i; + for (i = 0; i < N; i++) + c[i] = 747708026454360457216.0 + 747708026454360457216.0i; +} + +void +fv (void) +{ + int i; + for (i = 0; i < N; i++) + v[i] = (V) { 0x12121212, 0x12121212, 0x12121212, 0x12121212 }; +} + +/* Look for + __builtin_memset (&d, 68, 8192); + __builtin_memset (&l, 124, 8192); + __builtin_memset (&b, 1, 1024); + __builtin_memset (&c, 68, 16384); + __builtin_memset (&v, 18, 16384); */ +/* { dg-final { scan-tree-dump-times "memset ..d, 68, 8192.;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "memset ..l, 124, 8192.;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "memset ..b, 1, 1024.;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "memset ..c, 68, 16384.;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "memset ..v, 18, 16384.;" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-19.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-19.c index 332fedf..8ea9cea 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-19.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-19.c @@ -67,6 +67,5 @@ int main() } /* { dg-final { scan-tree-dump-times "generated memset zero" 1 "ldist" } } */ -/* { dg-final { scan-tree-dump-times "generated memset minus one" 1 "ldist" } } */ /* { dg-final { scan-tree-dump-times "generated memset" 5 "ldist" } } */ /* { dg-final { cleanup-tree-dump "ldist" } } */ diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 101efbe..668ceec 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -297,6 +297,36 @@ build_addr_arg_loc (location_t loc, data_reference_p dr, tree nb_bytes) return fold_build_pointer_plus_loc (loc, DR_BASE_ADDRESS (dr), addr_base); } +/* If VAL memory representation contains the same value in all bytes, + return that value, otherwise return -1. + E.g. for 0x24242424 return 0x24, for IEEE double + 747708026454360457216.0 return 0x44, etc. */ + +static int +const_with_all_bytes_same (tree val) +{ + unsigned char buf[64]; + int i, len; + + if (integer_zerop (val) + || real_zerop (val) + || (TREE_CODE (val) == CONSTRUCTOR + && !TREE_CLOBBER_P (val) + && CONSTRUCTOR_NELTS (val) == 0)) + return 0; + + if (CHAR_BIT != 8 || BITS_PER_UNIT != 8) + return -1; + + len = native_encode_expr (val, buf, sizeof (buf)); + if (len == 0) + return -1; + for (i = 1; i < len; i++) + if (buf[i] != buf[0]) + return -1; + return buf[0]; +} + /* Generate a call to memset for PARTITION in LOOP. */ static void @@ -327,24 +357,20 @@ generate_memset_builtin (struct loop *loop, partition_t partition) /* This exactly matches the pattern recognition in classify_partition. */ val = gimple_assign_rhs1 (stmt); - if (integer_zerop (val) - || real_zerop (val) - || TREE_CODE (val) == CONSTRUCTOR) - val = integer_zero_node; - else if (integer_all_onesp (val)) - val = build_int_cst (integer_type_node, -1); - else + /* Handle constants like 0x15151515 and similarly + floating point constants etc. where all bytes are the same. */ + int bytev = const_with_all_bytes_same (val); + if (bytev != -1) + val = build_int_cst (integer_type_node, bytev); + else if (TREE_CODE (val) == INTEGER_CST) + val = fold_convert (integer_type_node, val); + else if (!useless_type_conversion_p (integer_type_node, TREE_TYPE (val))) { - if (TREE_CODE (val) == INTEGER_CST) - val = fold_convert (integer_type_node, val); - else if (!useless_type_conversion_p (integer_type_node, TREE_TYPE (val))) - { - gimple cstmt; - tree tem = make_ssa_name (integer_type_node, NULL); - cstmt = gimple_build_assign_with_ops (NOP_EXPR, tem, val, NULL_TREE); - gsi_insert_after (&gsi, cstmt, GSI_CONTINUE_LINKING); - val = tem; - } + gimple cstmt; + tree tem = make_ssa_name (integer_type_node, NULL); + cstmt = gimple_build_assign_with_ops (NOP_EXPR, tem, val, NULL_TREE); + gsi_insert_after (&gsi, cstmt, GSI_CONTINUE_LINKING); + val = tem; } fn = build_fold_addr_expr (builtin_decl_implicit (BUILT_IN_MEMSET)); @@ -354,10 +380,8 @@ generate_memset_builtin (struct loop *loop, partition_t partition) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "generated memset"); - if (integer_zerop (val)) + if (bytev == 0) fprintf (dump_file, " zero\n"); - else if (integer_all_onesp (val)) - fprintf (dump_file, " minus one\n"); else fprintf (dump_file, "\n"); } @@ -941,18 +965,10 @@ classify_partition (loop_p loop, struct graph *rdg, partition_t partition) { gimple stmt = DR_STMT (single_store); tree rhs = gimple_assign_rhs1 (stmt); - if (!(integer_zerop (rhs) - || real_zerop (rhs) - || (TREE_CODE (rhs) == CONSTRUCTOR - && !TREE_CLOBBER_P (rhs)) - || ((integer_all_onesp (rhs) - || (INTEGRAL_TYPE_P (TREE_TYPE (rhs)) - && (TYPE_MODE (TREE_TYPE (rhs)) - == TYPE_MODE (unsigned_char_type_node)))) - /* For stores of a non-zero value require that the precision - of the value matches its actual size. */ - && (TYPE_PRECISION (TREE_TYPE (rhs)) - == GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (rhs))))))) + if (const_with_all_bytes_same (rhs) == -1 + && (!INTEGRAL_TYPE_P (TREE_TYPE (rhs)) + || (TYPE_MODE (TREE_TYPE (rhs)) + != TYPE_MODE (unsigned_char_type_node)))) return; if (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs) |