aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/gimple.c33
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/lto/20101125-1_0.c24
-rw-r--r--gcc/testsuite/gcc.dg/lto/20101125-1_1.c17
5 files changed, 72 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2687d4e..810590c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2010-11-26 Richard Guenther <rguenther@suse.de>
+ PR lto/46648
+ * gimple.c (gtc_visit): Do not return true for members of an
+ SCC still being processed but the current lattice value of
+ the member. Treat SCC members comparison state as lattice,
+ starting at equal, eventually dropping to unequal.
+ (gimple_types_compatible_p_1): Likewise.
+
+2010-11-26 Richard Guenther <rguenther@suse.de>
+
PR middle-end/46559
* dwarf2out.c (dwarf2out_finish): Use comp_unit_die as root
for location list processing.
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 851e30f..67c80e3 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -3515,27 +3515,23 @@ gtc_visit (tree t1, tree t2, enum gtc_mode mode,
if ((slot = pointer_map_contains (sccstate, p)) != NULL)
cstate = (struct sccs *)*slot;
+ /* Not yet visited. DFS recurse. */
if (!cstate)
{
- bool res;
- /* Not yet visited. DFS recurse. */
- res = gimple_types_compatible_p_1 (t1, t2, mode, p,
- sccstack, sccstate, sccstate_obstack);
- if (!cstate)
- cstate = (struct sccs *)* pointer_map_contains (sccstate, p);
+ gimple_types_compatible_p_1 (t1, t2, mode, p,
+ sccstack, sccstate, sccstate_obstack);
+ cstate = (struct sccs *)* pointer_map_contains (sccstate, p);
state->low = MIN (state->low, cstate->low);
- /* If the type is no longer on the SCC stack and thus is not part
- of the parents SCC, return its state. Otherwise we will
- ignore this pair and assume equality. */
- if (!cstate->on_sccstack)
- return res;
}
+ /* If the type is still on the SCC stack adjust the parents low. */
if (cstate->dfsnum < state->dfsnum
&& cstate->on_sccstack)
state->low = MIN (cstate->dfsnum, state->low);
- /* We are part of our parents SCC, skip this entry and return true. */
- return true;
+ /* Return the current lattice value. We start with an equality
+ assumption so types part of a SCC will be optimistically
+ treated equal unless proven otherwise. */
+ return cstate->u.same_p;
}
/* Worker for gimple_types_compatible.
@@ -3559,6 +3555,9 @@ gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode,
state->dfsnum = gtc_next_dfs_num++;
state->low = state->dfsnum;
state->on_sccstack = true;
+ /* Start with an equality assumption. As we DFS recurse into child
+ SCCs this assumption may get revisited. */
+ state->u.same_p = 1;
/* If their attributes are not the same they can't be the same type. */
if (!attribute_list_equal (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2)))
@@ -3822,22 +3821,22 @@ different_types:
/* Common exit path for types that are compatible. */
same_types:
- state->u.same_p = 1;
- goto pop;
+ gcc_assert (state->u.same_p == 1);
pop:
if (state->low == state->dfsnum)
{
type_pair_t x;
- /* Pop off the SCC and set its cache values. */
+ /* Pop off the SCC and set its cache values to the final
+ comparison result. */
do
{
struct sccs *cstate;
x = VEC_pop (type_pair_t, *sccstack);
cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
cstate->on_sccstack = false;
- x->same_p[mode] = cstate->u.same_p;
+ x->same_p[mode] = state->u.same_p;
}
while (x != p);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 57a7b42..80706c0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-11-26 Richard Guenther <rguenther@suse.de>
+
+ PR lto/46648
+ * gcc.dg/lto/20101125-1_0.c: New testcase.
+ * gcc.dg/lto/20101125-1_1.c: Likewise.
+
2010-11-22 Bud Davis <jmdavis@link.com>
* arith_divide_no_check.f
diff --git a/gcc/testsuite/gcc.dg/lto/20101125-1_0.c b/gcc/testsuite/gcc.dg/lto/20101125-1_0.c
new file mode 100644
index 0000000..662dd24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20101125-1_0.c
@@ -0,0 +1,24 @@
+/* { dg-lto-do link } */
+
+struct X {
+ int i;
+};
+
+struct W {
+ struct U *p;
+ struct X *q;
+};
+
+struct U {
+ struct W a[1];
+};
+
+void foo(struct U *ptr)
+{
+ ptr->a[0].p = 0;
+}
+
+int main(void)
+{
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/20101125-1_1.c b/gcc/testsuite/gcc.dg/lto/20101125-1_1.c
new file mode 100644
index 0000000..2924e3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/20101125-1_1.c
@@ -0,0 +1,17 @@
+struct X {
+ char i;
+};
+
+struct W {
+ struct U *p;
+ struct X *q;
+};
+
+struct U {
+ struct W a[1];
+};
+
+void bar(struct U *ptr)
+{
+ ptr->a[0].p = 0;
+}