diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad2aecf62227..20e23f8cd123 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2010-11-15 Martin Jambor + + 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. + 2010-11-15 Richard Guenther PR tree-optimization/46467 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f10da57971c8..f1ff56954889 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2010-11-15 Martin Jambor + + PR tree-optimization/46349 + * gnat.dg/opt9.adb: New file. + * gnat.dg/opt9_pkg.ads: Likewise + 2010-11-15 Richard Guenther PR lto/44989 diff --git a/gcc/testsuite/gnat.dg/opt9.adb b/gcc/testsuite/gnat.dg/opt9.adb new file mode 100644 index 000000000000..a0f1ac5c6896 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt9.adb @@ -0,0 +1,26 @@ +-- { dg-do compile } +-- { dg-options "-gnatws -O" } + +with Opt9_Pkg; use Opt9_Pkg; + +procedure Opt9 is + + type Array_T is array (1 .. N) of Integer; + + type Clock_T is record + N_Ticks : Integer := 0; + end record; + + type Rec is record + Values : Array_T; + Valid : Boolean; + Tstamp : Clock_T; + end record; + + pragma Pack (Rec); + + Data : Rec; + +begin + null; +end; diff --git a/gcc/testsuite/gnat.dg/opt9_pkg.ads b/gcc/testsuite/gnat.dg/opt9_pkg.ads new file mode 100644 index 000000000000..beffac26f38f --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt9_pkg.ads @@ -0,0 +1,5 @@ +package Opt9_Pkg is + + N : integer := 15; + +end Opt9_Pkg; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 88199f131aee..252fa0628e28 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,