aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2010-11-15 17:32:18 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2010-11-15 17:32:18 +0100
commit4cc13d9d7aae52ba0b6841a2b82fe81d54615aa1 (patch)
tree1a851a57d2fd7b8515a90ca295050abb6e82fb5e /gcc/tree-sra.c
parent9965e3cddf54cfb4c45d5004345e490c6ac45124 (diff)
downloadgcc-4cc13d9d7aae52ba0b6841a2b82fe81d54615aa1.zip
gcc-4cc13d9d7aae52ba0b6841a2b82fe81d54615aa1.tar.gz
gcc-4cc13d9d7aae52ba0b6841a2b82fe81d54615aa1.tar.bz2
re PR tree-optimization/46349 (incorrect scalarization)
2010-11-15 Martin Jambor <mjambor@suse.cz> PR tree-optimization/46349 * tree-sra.c (contains_bitfld_comp_ref_p): New function. (contains_vce_or_bfcref_p): Likewise. (sra_modify_assign): Use them. * testsuite/gnat.dg/opt9.adb: New file. * testsuite/gnat.dg/opt9_pkg.ads: Likewise From-SVN: r166759
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 88199f1..252fa06 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2626,6 +2626,41 @@ get_repl_default_def_ssa_name (struct access *racc)
return repl;
}
+/* Return true if REF has a COMPONENT_REF with a bit-field field declaration
+ somewhere in it. */
+
+static inline bool
+contains_bitfld_comp_ref_p (const_tree ref)
+{
+ while (handled_component_p (ref))
+ {
+ if (TREE_CODE (ref) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ return false;
+}
+
+/* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
+ bit-field field declaration somewhere in it. */
+
+static inline bool
+contains_vce_or_bfcref_p (const_tree ref)
+{
+ while (handled_component_p (ref))
+ {
+ if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
+ || (TREE_CODE (ref) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ return false;
+}
+
/* Examine both sides of the assignment statement pointed to by STMT, replace
them with a scalare replacement if there is one and generate copying of
replacements if scalarized aggregates have been used in the assignment. GSI
@@ -2694,6 +2729,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
??? This should move to fold_stmt which we simply should
call after building a VIEW_CONVERT_EXPR here. */
if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
+ && !contains_bitfld_comp_ref_p (lhs)
&& !access_has_children_p (lacc))
{
lhs = build_ref_for_offset (loc, lhs, 0, TREE_TYPE (rhs),
@@ -2701,7 +2737,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
gimple_assign_set_lhs (*stmt, lhs);
}
else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
- && !contains_view_convert_expr_p (rhs)
+ && !contains_vce_or_bfcref_p (rhs)
&& !access_has_children_p (racc))
rhs = build_ref_for_offset (loc, rhs, 0, TREE_TYPE (lhs),
gsi, false);
@@ -2751,8 +2787,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
This is what the first branch does. */
if (gimple_has_volatile_ops (*stmt)
- || contains_view_convert_expr_p (rhs)
- || contains_view_convert_expr_p (lhs))
+ || contains_vce_or_bfcref_p (rhs)
+ || contains_vce_or_bfcref_p (lhs))
{
if (access_has_children_p (racc))
generate_subtree_copies (racc->first_child, racc->base, 0, 0, 0,