diff options
author | Martin Jambor <mjambor@suse.cz> | 2017-09-26 19:15:29 +0200 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2017-09-26 19:15:29 +0200 |
commit | 973c150c2d564fbe077f14cb80c17da175c89323 (patch) | |
tree | 8608b6c9baa1858a00c6b1d4c38c4a409a782802 /gcc/tree-sra.c | |
parent | 5714abfff8a8b04cdd294bd9968bcc72924213ec (diff) |
Make SRA qsort comparator transitive
2017-09-26 Martin Jambor <mjambor@suse.cz>
* tree-sra.c (compare_access_positions): Put integral types first,
stabilize sorting of integral types, remove conditions putting
non-full-precision integers last.
(sort_and_splice_var_accesses): Disable scalarization if a
non-integert would be represented by a non-full-precision integer.
From-SVN: r253207
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 163b7a2d03b..f5675edc7f1 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1542,19 +1542,20 @@ compare_access_positions (const void *a, const void *b) && TREE_CODE (f2->type) != COMPLEX_TYPE && TREE_CODE (f2->type) != VECTOR_TYPE) return -1; - /* Put the integral type with the bigger precision first. */ + /* Put any integral type before any non-integral type. When splicing, we + make sure that those with insufficient precision and occupying the + same space are not scalarized. */ else if (INTEGRAL_TYPE_P (f1->type) + && !INTEGRAL_TYPE_P (f2->type)) + return -1; + else if (!INTEGRAL_TYPE_P (f1->type) && INTEGRAL_TYPE_P (f2->type)) - return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type); - /* Put any integral type with non-full precision last. */ - else if (INTEGRAL_TYPE_P (f1->type) - && (TREE_INT_CST_LOW (TYPE_SIZE (f1->type)) - != TYPE_PRECISION (f1->type))) return 1; - else if (INTEGRAL_TYPE_P (f2->type) - && (TREE_INT_CST_LOW (TYPE_SIZE (f2->type)) - != TYPE_PRECISION (f2->type))) - return -1; + /* Put the integral type with the bigger precision first. */ + else if (INTEGRAL_TYPE_P (f1->type) + && INTEGRAL_TYPE_P (f2->type) + && (TYPE_PRECISION (f2->type) != TYPE_PRECISION (f1->type))) + return TYPE_PRECISION (f2->type) - TYPE_PRECISION (f1->type); /* Stabilize the sort. */ return TYPE_UID (f1->type) - TYPE_UID (f2->type); } @@ -2055,6 +2056,11 @@ sort_and_splice_var_accesses (tree var) bool grp_partial_lhs = access->grp_partial_lhs; bool first_scalar = is_gimple_reg_type (access->type); bool unscalarizable_region = access->grp_unscalarizable_region; + bool bf_non_full_precision + = (INTEGRAL_TYPE_P (access->type) + && TYPE_PRECISION (access->type) != access->size + && TREE_CODE (access->expr) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (access->expr, 1))); if (first || access->offset >= high) { @@ -2102,6 +2108,22 @@ sort_and_splice_var_accesses (tree var) this combination of size and offset, the comparison function should have put the scalars first. */ gcc_assert (first_scalar || !is_gimple_reg_type (ac2->type)); + /* It also prefers integral types to non-integral. However, when the + precision of the selected type does not span the entire area and + should also be used for a non-integer (i.e. float), we must not + let that happen. Normally analyze_access_subtree expands the type + to cover the entire area but for bit-fields it doesn't. */ + if (bf_non_full_precision && !INTEGRAL_TYPE_P (ac2->type)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Cannot scalarize the following access " + "because insufficient precision integer type was " + "selected.\n "); + dump_access (dump_file, access, false); + } + unscalarizable_region = true; + } ac2->group_representative = access; j++; } |