diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/gimple.c | 33 |
2 files changed, 41 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4a81df2..c557f73 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2010-07-09 Richard Guenther <rguenther@suse.de> + + * gimple.c (struct type_fixup_s): New struct and VEC type. + (gimple_register_type_fixups): New static global. + (gimple_queue_type_fixup): New function. + (gimple_types_compatible_p): Queue type fixups instead of + applying them here. + (gimple_register_type): Apply queued fixups for the + canonical type. Empty the type fixup queue. + 2010-07-09 Uros Bizjak <ubizjak@gmail.com> * configure.ac (gcc_cv_as_ix86_rep_lock_prefix): Fix test. diff --git a/gcc/gimple.c b/gcc/gimple.c index 707d4e4..318b6d8 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -3323,6 +3323,26 @@ gimple_compare_field_offset (tree f1, tree f2) return false; } +typedef struct type_fixup_s { + tree context; + tree *incomplete; + tree complete; +} type_fixup; +DEF_VEC_O(type_fixup); +DEF_VEC_ALLOC_O(type_fixup,heap); + +static VEC(type_fixup, heap) *gimple_register_type_fixups = NULL; + +static void +gimple_queue_type_fixup (tree context, tree *incomplete, tree complete) +{ + type_fixup f; + f.context = context; + f.incomplete = incomplete; + f.complete = complete; + VEC_safe_push (type_fixup, heap, gimple_register_type_fixups, &f); +} + /* Return 1 iff T1 and T2 are structurally identical. Otherwise, return 0. */ @@ -3555,9 +3575,9 @@ gimple_types_compatible_p (tree t1, tree t2) in one unit and to complete ones in another. So we probably should merge these types only with more context. */ if (COMPLETE_TYPE_P (TREE_TYPE (t2))) - TREE_TYPE (t1) = TREE_TYPE (t2); + gimple_queue_type_fixup (t1, &TREE_TYPE (t1), TREE_TYPE (t2)); else - TREE_TYPE (t2) = TREE_TYPE (t1); + gimple_queue_type_fixup (t2, &TREE_TYPE (t2), TREE_TYPE (t1)); goto same_types; } @@ -4014,11 +4034,14 @@ gimple_register_type (tree t) if (gimple_types == NULL) gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0); + gcc_assert (VEC_empty (type_fixup, gimple_register_type_fixups)); slot = htab_find_slot (gimple_types, t, INSERT); if (*slot && *(tree *)slot != t) { tree new_type = (tree) *((tree *) slot); + unsigned i; + type_fixup *f; /* Do not merge types with different addressability. */ gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type)); @@ -4070,6 +4093,11 @@ gimple_register_type (tree t) TYPE_CANONICAL (t) = new_type; t = new_type; + + for (i = 0; + VEC_iterate (type_fixup, gimple_register_type_fixups, i, f); ++i) + if (f->context == t) + *(f->incomplete) = f->complete; } else { @@ -4077,6 +4105,7 @@ gimple_register_type (tree t) *slot = (void *) t; } + VEC_truncate (type_fixup, gimple_register_type_fixups, 0); return t; } |