diff options
author | Martin Jambor <mjambor@suse.cz> | 2010-11-15 17:32:18 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2010-11-15 17:32:18 +0100 |
commit | 4cc13d9d7aae52ba0b6841a2b82fe81d54615aa1 (patch) | |
tree | 1a851a57d2fd7b8515a90ca295050abb6e82fb5e /gcc/tree-sra.c | |
parent | 9965e3cddf54cfb4c45d5004345e490c6ac45124 (diff) | |
download | gcc-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.c | 42 |
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, |