diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ebb64a7e7f3..8db7b6c5a18 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2012-06-15 Michael Matz + + PR middle-end/38474 + * cfgexpand.c (add_alias_set_conflicts): Remove. + (expand_used_vars): Don't call it. + (aggregate_contains_union_type): Remove. + * function.c (n_temp_slots_in_use): New static data. + (make_slot_available, assign_stack_temp_for_type): Update it. + (init_temp_slots): Zero it. + (remove_unused_temp_slot_addresses): Use it for quicker removal. + (remove_unused_temp_slot_addresses_1): Use htab_clear_slot. + 2012-06-15 Michael Matz * gimplify.c (gimplify_compound_literal_expr): Take gimple_test_f @@ -190,9 +202,9 @@ 2012-06-14 Richard Earnshaw * arm.opt (mfp=2, mfp=3, mfpe, mfpe=2, mfpe=3): Delete options. - * arm-fpus.def (fpa, fpe2, fpe3, maverick): Delete FPU types. + * arm-fpus.def (fpa, fpe2, fpe3, maverick): Delete FPU types. * arm-tables.opt: Regenerated. - * doc/invoke.texi: Remove references to deleted options. + * doc/invoke.texi: Remove references to deleted options. 2012-06-14 Sandeep Kumar Singh diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 8a31a9f5835..a8397c69b03 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -329,70 +329,6 @@ stack_var_conflict_p (size_t x, size_t y) return bitmap_bit_p (a->conflicts, y); } -/* Returns true if TYPE is or contains a union type. */ - -static bool -aggregate_contains_union_type (tree type) -{ - tree field; - - if (TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE) - return true; - if (TREE_CODE (type) == ARRAY_TYPE) - return aggregate_contains_union_type (TREE_TYPE (type)); - if (TREE_CODE (type) != RECORD_TYPE) - return false; - - for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL) - if (aggregate_contains_union_type (TREE_TYPE (field))) - return true; - - return false; -} - -/* A subroutine of expand_used_vars. If two variables X and Y have alias - sets that do not conflict, then do add a conflict for these variables - in the interference graph. We also need to make sure to add conflicts - for union containing structures. Else RTL alias analysis comes along - and due to type based aliasing rules decides that for two overlapping - union temporaries { short s; int i; } accesses to the same mem through - different types may not alias and happily reorders stores across - life-time boundaries of the temporaries (See PR25654). */ - -static void -add_alias_set_conflicts (void) -{ - size_t i, j, n = stack_vars_num; - - for (i = 0; i < n; ++i) - { - tree type_i = TREE_TYPE (stack_vars[i].decl); - bool aggr_i = AGGREGATE_TYPE_P (type_i); - bool contains_union; - - contains_union = aggregate_contains_union_type (type_i); - for (j = 0; j < i; ++j) - { - tree type_j = TREE_TYPE (stack_vars[j].decl); - bool aggr_j = AGGREGATE_TYPE_P (type_j); - if (aggr_i != aggr_j - /* Either the objects conflict by means of type based - aliasing rules, or we need to add a conflict. */ - || !objects_must_conflict_p (type_i, type_j) - /* In case the types do not conflict ensure that access - to elements will conflict. In case of unions we have - to be careful as type based aliasing rules may say - access to the same memory does not conflict. So play - safe and add a conflict in this case when - -fstrict-aliasing is used. */ - || (contains_union && flag_strict_aliasing)) - add_stack_var_conflict (i, j); - } - } -} - /* Callback for walk_stmt_ops. If OP is a decl touched by add_stack_var enter its partition number into bitmap DATA. */ @@ -1625,10 +1561,6 @@ expand_used_vars (void) if (stack_vars_num > 0) { add_scope_conflicts (); - /* Due to the way alias sets work, no variables with non-conflicting - alias sets may be assigned the same address. Add conflicts to - reflect this. */ - add_alias_set_conflicts (); /* If stack protection is enabled, we don't share space between vulnerable data and non-vulnerable data. */ diff --git a/gcc/function.c b/gcc/function.c index 9e79bcd8333..5f510f0bfed 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -571,6 +571,7 @@ struct GTY(()) temp_slot { /* A table of addresses that represent a stack slot. The table is a mapping from address RTXen to a temp slot. */ static GTY((param_is(struct temp_slot_address_entry))) htab_t temp_slot_address_table; +static size_t n_temp_slots_in_use; /* Entry for the above hash table. */ struct GTY(()) temp_slot_address_entry { @@ -647,6 +648,7 @@ make_slot_available (struct temp_slot *temp) insert_slot_to_list (temp, &avail_temp_slots); temp->in_use = 0; temp->level = -1; + n_temp_slots_in_use--; } /* Compute the hash value for an address -> temp slot mapping. @@ -699,7 +701,7 @@ remove_unused_temp_slot_addresses_1 (void **slot, void *data ATTRIBUTE_UNUSED) const struct temp_slot_address_entry *t; t = (const struct temp_slot_address_entry *) *slot; if (! t->temp_slot->in_use) - *slot = NULL; + htab_clear_slot (temp_slot_address_table, slot); return 1; } @@ -707,9 +709,13 @@ remove_unused_temp_slot_addresses_1 (void **slot, void *data ATTRIBUTE_UNUSED) static void remove_unused_temp_slot_addresses (void) { - htab_traverse (temp_slot_address_table, - remove_unused_temp_slot_addresses_1, - NULL); + /* Use quicker clearing if there aren't any active temp slots. */ + if (n_temp_slots_in_use) + htab_traverse (temp_slot_address_table, + remove_unused_temp_slot_addresses_1, + NULL); + else + htab_empty (temp_slot_address_table); } /* Find the temp slot corresponding to the object at address X. */ @@ -901,6 +907,7 @@ assign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size, p->in_use = 1; p->type = type; p->level = temp_slot_level; + n_temp_slots_in_use++; pp = temp_slots_at_level (p->level); insert_slot_to_list (p, pp); @@ -1212,6 +1219,7 @@ init_temp_slots (void) avail_temp_slots = 0; used_temp_slots = 0; temp_slot_level = 0; + n_temp_slots_in_use = 0; /* Set up the table to map addresses to temp slots. */ if (! temp_slot_address_table) @@ -4496,7 +4504,6 @@ allocate_struct_function (tree fndecl, bool abstract_p) /* ??? This could be set on a per-function basis by the front-end but is this worth the hassle? */ cfun->can_throw_non_call_exceptions = flag_non_call_exceptions; - cfun->can_delete_dead_exceptions = flag_delete_dead_exceptions; } }