diff options
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index a4773b75e94..9e61723b2d2 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1,7 +1,7 @@ /* Scalar Replacement of Aggregates (SRA) converts some structure references into scalar references, exposing them to the scalar optimizers. - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Contributed by Diego Novillo <dnovillo@redhat.com> This file is part of GCC. @@ -1246,7 +1246,23 @@ instantiate_missing_elements (struct sra_elt *elt) tree f; for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f)) if (TREE_CODE (f) == FIELD_DECL) - instantiate_missing_elements_1 (elt, f, TREE_TYPE (f)); + { + tree field_type = TREE_TYPE (f); + + /* canonicalize_component_ref() unwidens some bit-field + types (not marked as DECL_BIT_FIELD in C++), so we + must do the same, lest we may introduce type + mismatches. */ + if (INTEGRAL_TYPE_P (field_type) + && DECL_MODE (f) != TYPE_MODE (field_type)) + field_type = TREE_TYPE (get_unwidened (build3 (COMPONENT_REF, + field_type, + elt->element, + f, NULL_TREE), + NULL_TREE)); + + instantiate_missing_elements_1 (elt, f, field_type); + } break; } @@ -1539,6 +1555,14 @@ generate_element_ref (struct sra_elt *elt) return elt->element; } +static tree +sra_build_assignment (tree dst, tree src) +{ + /* We need TYPE_CANONICAL to compare the types of dst and src + efficiently, but that's only introduced in GCC 4.3. */ + return build (MODIFY_EXPR, void_type_node, dst, src); +} + /* Generate a set of assignment statements in *LIST_P to copy all instantiated elements under ELT to or from the equivalent structure rooted at EXPR. COPY_OUT controls the direction of the copy, with @@ -1562,16 +1586,16 @@ generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr, i = c->replacement; t = build (COMPLEX_EXPR, elt->type, r, i); - t = build (MODIFY_EXPR, void_type_node, expr, t); + t = sra_build_assignment (expr, t); SSA_NAME_DEF_STMT (expr) = t; append_to_statement_list (t, list_p); } else if (elt->replacement) { if (copy_out) - t = build (MODIFY_EXPR, void_type_node, elt->replacement, expr); + t = sra_build_assignment (elt->replacement, expr); else - t = build (MODIFY_EXPR, void_type_node, expr, elt->replacement); + t = sra_build_assignment (expr, elt->replacement); append_to_statement_list (t, list_p); } else @@ -1606,8 +1630,7 @@ generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p) gcc_assert (src->replacement); - t = build (MODIFY_EXPR, void_type_node, dst->replacement, - src->replacement); + t = sra_build_assignment (dst->replacement, src->replacement); append_to_statement_list (t, list_p); } } @@ -1638,7 +1661,7 @@ generate_element_zero (struct sra_elt *elt, tree *list_p) gcc_assert (elt->is_scalar); t = fold_convert (elt->type, integer_zero_node); - t = build (MODIFY_EXPR, void_type_node, elt->replacement, t); + t = sra_build_assignment (elt->replacement, t); append_to_statement_list (t, list_p); } } @@ -1650,7 +1673,9 @@ static void generate_one_element_init (tree var, tree init, tree *list_p) { /* The replacement can be almost arbitrarily complex. Gimplify. */ - tree stmt = build (MODIFY_EXPR, void_type_node, var, init); + tree stmt; + + stmt = sra_build_assignment (var, init); gimplify_and_add (stmt, list_p); } |