tree-sra.c (instantiate_missing_elements): Canonicalize bit-field types.

gcc/ChangeLog:
* tree-sra.c (instantiate_missing_elements): Canonicalize
bit-field types.
(sra_build_assignment): New.
(generate_copy_inout, generate_element_copy,
generate_element_zero, generate_one_element_init): Use it.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/sra-1.C: New.

From-SVN: r121980
This commit is contained in:
Alexandre Oliva 2007-02-15 04:24:50 +00:00 committed by Alexandre Oliva
parent db9e0d2af6
commit 45f94ec730
4 changed files with 86 additions and 9 deletions

View File

@ -1,3 +1,19 @@
2007-02-15 Alexandre Oliva <aoliva@redhat.com>
* tree-sra.c (instantiate_missing_elements): Canonicalize
bit-field types.
(sra_build_assignment): New.
(generate_copy_inout, generate_element_copy,
generate_element_zero, generate_one_element_init): Use it.
2007-02-15 Alexandre Oliva <aoliva@redhat.com>
* tree-sra.c (instantiate_missing_elements): Canonicalize
bit-field types.
(sra_build_assignment): New.
(generate_copy_inout, generate_element_copy,
generate_element_zero, generate_one_element_init): Use it.
2007-02-15 Alexandre Oliva <aoliva@redhat.com>
* dwarf2out.c (dwarf2out_finish): Accept namespaces as context of

View File

@ -1,3 +1,11 @@
2007-02-15 Alexandre Oliva <aoliva@redhat.com>
* g++.dg/tree-ssa/sra-1.C: New.
2007-02-15 Alexandre Oliva <aoliva@redhat.com>
* g++.dg/tree-ssa/sra-1.C: New.
2007-02-15 Alexandre Oliva <aoliva@redhat.com>
* g++.dg/ext/interface4.C, g++.dg/ext/interface4.h: New.

View File

@ -0,0 +1,29 @@
/* https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=223576 */
/* SRA failed to canonicalize bit-field types, introducing type
mismatches. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
struct A
{
int a:16;
/* These dummy bit-fields are here to prevent GCC 4.2+ from merging
the bit-field compares into a single word compare, which disables
SRA. */
int a2:16;
int a3:16;
int a4:16;
int b:8;
bool operator==(A const x) const
{
return (this->a == x.a && this->b == x.b);
}
};
bool
foo (A const x, A const y)
{
return x == y;
}

View File

@ -1,7 +1,8 @@
/* Scalar Replacement of Aggregates (SRA) converts some structure
references into scalar references, exposing them to the scalar
optimizers.
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com>
This file is part of GCC.
@ -1355,7 +1356,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;
}
@ -1706,6 +1723,14 @@ generate_element_ref (struct sra_elt *elt)
return elt->element;
}
static tree
sra_build_assignment (tree dst, tree src)
{
gcc_assert (TYPE_CANONICAL (TYPE_MAIN_VARIANT (TREE_TYPE (dst)))
== TYPE_CANONICAL (TYPE_MAIN_VARIANT (TREE_TYPE (src))));
return build2 (GIMPLE_MODIFY_STMT, 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
@ -1729,16 +1754,16 @@ generate_copy_inout (struct sra_elt *elt, bool copy_out, tree expr,
i = c->replacement;
t = build2 (COMPLEX_EXPR, elt->type, r, i);
t = build2 (GIMPLE_MODIFY_STMT, 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 = build2 (GIMPLE_MODIFY_STMT, void_type_node, elt->replacement, expr);
t = sra_build_assignment (elt->replacement, expr);
else
t = build2 (GIMPLE_MODIFY_STMT, void_type_node, expr, elt->replacement);
t = sra_build_assignment (expr, elt->replacement);
append_to_statement_list (t, list_p);
}
else
@ -1773,8 +1798,7 @@ generate_element_copy (struct sra_elt *dst, struct sra_elt *src, tree *list_p)
gcc_assert (src->replacement);
t = build2 (GIMPLE_MODIFY_STMT, void_type_node, dst->replacement,
src->replacement);
t = sra_build_assignment (dst->replacement, src->replacement);
append_to_statement_list (t, list_p);
}
}
@ -1805,7 +1829,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 = build2 (GIMPLE_MODIFY_STMT, void_type_node, elt->replacement, t);
t = sra_build_assignment (elt->replacement, t);
append_to_statement_list (t, list_p);
}
}
@ -1817,7 +1841,7 @@ static void
generate_one_element_init (tree var, tree init, tree *list_p)
{
/* The replacement can be almost arbitrarily complex. Gimplify. */
tree stmt = build2 (GIMPLE_MODIFY_STMT, void_type_node, var, init);
tree stmt = sra_build_assignment (var, init);
gimplify_and_add (stmt, list_p);
}