re PR middle-end/38474 (compile time explosion in dataflow_set_preserve_mem_locs at -O3)

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.

From-SVN: r188667
This commit is contained in:
Michael Matz 2012-06-15 14:56:26 +00:00
parent 4c53d18336
commit f8395d62c1
3 changed files with 26 additions and 75 deletions

View File

@ -1,3 +1,15 @@
2012-06-15 Michael Matz <matz@suse.de>
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 <matz@suse.de>
* gimplify.c (gimplify_compound_literal_expr): Take gimple_test_f
@ -190,9 +202,9 @@
2012-06-14 Richard Earnshaw <rearnsha@arm.com>
* 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 <Sandeep.Singh2@kpitcummins.com>

View File

@ -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. */

View File

@ -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;
}
}