aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2017-04-24 17:13:39 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2017-04-24 17:13:39 +0200
commita753df11b8bc86cf0e991fe2843ebb30b7992a16 (patch)
tree6d3ec20ad48bcca2e3018827c134c624e86f5c74 /gcc/tree-sra.c
parent957221f5511cf97447f52ba274eb0e0be7eff151 (diff)
downloadgcc-a753df11b8bc86cf0e991fe2843ebb30b7992a16.zip
gcc-a753df11b8bc86cf0e991fe2843ebb30b7992a16.tar.gz
gcc-a753df11b8bc86cf0e991fe2843ebb30b7992a16.tar.bz2
[PR 80293] Dont totally-scalarize char arrays
2017-04-24 Martin Jambor <mjambor@suse.cz> PR tree-optimization/80293 * tree-sra.c (scalarizable_type_p): New parameter const_decl, make char arrays not totally scalarizable if it is false. (analyze_all_variable_accesses): Pass correct value in the new parameter. Add a statistics counter. testsuite/ * g++.dg/tree-ssa/pr80293.C: New test. From-SVN: r247104
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 31834ed..0334d06 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -949,10 +949,12 @@ create_access (tree expr, gimple *stmt, bool write)
/* Return true iff TYPE is scalarizable - i.e. a RECORD_TYPE or fixed-length
ARRAY_TYPE with fields that are either of gimple register types (excluding
- bit-fields) or (recursively) scalarizable types. */
+ bit-fields) or (recursively) scalarizable types. CONST_DECL must be true if
+ we are considering a decl from constant pool. If it is false, char arrays
+ will be refused. */
static bool
-scalarizable_type_p (tree type)
+scalarizable_type_p (tree type, bool const_decl)
{
gcc_assert (!is_gimple_reg_type (type));
if (type_contains_placeholder_p (type))
@@ -970,7 +972,7 @@ scalarizable_type_p (tree type)
return false;
if (!is_gimple_reg_type (ft)
- && !scalarizable_type_p (ft))
+ && !scalarizable_type_p (ft, const_decl))
return false;
}
@@ -978,10 +980,16 @@ scalarizable_type_p (tree type)
case ARRAY_TYPE:
{
+ HOST_WIDE_INT min_elem_size;
+ if (const_decl)
+ min_elem_size = 0;
+ else
+ min_elem_size = BITS_PER_UNIT;
+
if (TYPE_DOMAIN (type) == NULL_TREE
|| !tree_fits_shwi_p (TYPE_SIZE (type))
|| !tree_fits_shwi_p (TYPE_SIZE (TREE_TYPE (type)))
- || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= 0)
+ || (tree_to_shwi (TYPE_SIZE (TREE_TYPE (type))) <= min_elem_size)
|| !tree_fits_shwi_p (TYPE_MIN_VALUE (TYPE_DOMAIN (type))))
return false;
if (tree_to_shwi (TYPE_SIZE (type)) == 0
@@ -995,7 +1003,7 @@ scalarizable_type_p (tree type)
tree elem = TREE_TYPE (type);
if (!is_gimple_reg_type (elem)
- && !scalarizable_type_p (elem))
+ && !scalarizable_type_p (elem, const_decl))
return false;
return true;
}
@@ -2660,13 +2668,16 @@ analyze_all_variable_accesses (void)
{
tree var = candidate (i);
- if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var)))
+ if (VAR_P (var) && scalarizable_type_p (TREE_TYPE (var),
+ constant_decl_p (var)))
{
if (tree_to_uhwi (TYPE_SIZE (TREE_TYPE (var)))
<= max_scalarization_size)
{
create_total_scalarization_access (var);
completely_scalarize (var, TREE_TYPE (var), 0, var);
+ statistics_counter_event (cfun,
+ "Totally-scalarized aggregates", 1);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Will attempt to totally scalarize ");