Commit 91fe0424 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/33508 (tree struct aliasing goes into a loop marking call clobbers.)

2007-09-21  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/33508
	* tree-ssa-alias.c (mark_aliases_call_clobbered): Avoid
	quadratic loop by keeping a bitmap of variables we have
	to clobber all subvariables for.
	(set_initial_properties): Likewise.

From-SVN: r128645
parent 6eed4bbf
2007-09-21 Richard Guenther <rguenther@suse.de>
PR tree-optimization/33508
* tree-ssa-alias.c (mark_aliases_call_clobbered): Avoid
quadratic loop by keeping a bitmap of variables we have
to clobber all subvariables for.
(set_initial_properties): Likewise.
2007-09-21 Richard Sandiford <rsandifo@nildram.co.uk> 2007-09-21 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/t-sde (TARGET_LIBGCC2_CFLAGS): Delete. * config/mips/t-sde (TARGET_LIBGCC2_CFLAGS): Delete.
...@@ -364,7 +364,7 @@ add_to_worklist (tree alias, VEC (tree, heap) **worklist, ...@@ -364,7 +364,7 @@ add_to_worklist (tree alias, VEC (tree, heap) **worklist,
static void static void
mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist, mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist,
VEC (int, heap) **worklist2, VEC (int, heap) **worklist2,
bitmap on_worklist) bitmap on_worklist, bitmap queued)
{ {
bitmap aliases; bitmap aliases;
bitmap_iterator bi; bitmap_iterator bi;
...@@ -387,13 +387,7 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist, ...@@ -387,13 +387,7 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist,
in order to allow C/C++ tricks that involve in order to allow C/C++ tricks that involve
pointer arithmetic to work. */ pointer arithmetic to work. */
if (TREE_CODE (entry) == STRUCT_FIELD_TAG) if (TREE_CODE (entry) == STRUCT_FIELD_TAG)
{ bitmap_set_bit (queued, DECL_UID (SFT_PARENT_VAR (entry)));
subvar_t svars;
svars = get_subvars_for_var (SFT_PARENT_VAR (entry));
for (; svars; svars = svars->next)
if (!unmodifiable_var_p (entry))
mark_call_clobbered (svars->var, ta->escape_mask);
}
else if (!unmodifiable_var_p (entry)) else if (!unmodifiable_var_p (entry))
{ {
add_to_worklist (entry, worklist, worklist2, ta->escape_mask, add_to_worklist (entry, worklist, worklist2, ta->escape_mask,
...@@ -401,6 +395,18 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist, ...@@ -401,6 +395,18 @@ mark_aliases_call_clobbered (tree tag, VEC (tree, heap) **worklist,
mark_call_clobbered (entry, ta->escape_mask); mark_call_clobbered (entry, ta->escape_mask);
} }
} }
if (!bitmap_empty_p (queued))
{
EXECUTE_IF_SET_IN_BITMAP (queued, 0, i, bi)
{
subvar_t svars;
svars = get_subvars_for_var (referenced_var (i));
for (; svars; svars = svars->next)
if (!unmodifiable_var_p (svars->var))
mark_call_clobbered (svars->var, ta->escape_mask);
}
bitmap_clear (queued);
}
} }
/* Tags containing global vars need to be marked as global. /* Tags containing global vars need to be marked as global.
...@@ -508,6 +514,11 @@ set_initial_properties (struct alias_info *ai) ...@@ -508,6 +514,11 @@ set_initial_properties (struct alias_info *ai)
referenced_var_iterator rvi; referenced_var_iterator rvi;
tree var; tree var;
tree ptr; tree ptr;
bitmap queued;
/* Temporary bitmap to avoid quadratic behavior in marking
call clobbers. */
queued = BITMAP_ALLOC (&alias_bitmap_obstack);
FOR_EACH_REFERENCED_VAR (var, rvi) FOR_EACH_REFERENCED_VAR (var, rvi)
{ {
...@@ -557,15 +568,22 @@ set_initial_properties (struct alias_info *ai) ...@@ -557,15 +568,22 @@ set_initial_properties (struct alias_info *ai)
in order to allow C/C++ tricks that involve in order to allow C/C++ tricks that involve
pointer arithmetic to work. */ pointer arithmetic to work. */
if (TREE_CODE (alias) == STRUCT_FIELD_TAG) if (TREE_CODE (alias) == STRUCT_FIELD_TAG)
bitmap_set_bit (queued, DECL_UID (SFT_PARENT_VAR (alias)));
else if (!unmodifiable_var_p (alias))
mark_call_clobbered (alias, pi->escape_mask);
}
/* Process variables we need to clobber all parts of. */
if (!bitmap_empty_p (queued))
{
EXECUTE_IF_SET_IN_BITMAP (queued, 0, j, bi)
{ {
subvar_t svars; subvar_t svars;
svars = get_subvars_for_var (SFT_PARENT_VAR (alias)); svars = get_subvars_for_var (referenced_var (j));
for (; svars; svars = svars->next) for (; svars; svars = svars->next)
if (!unmodifiable_var_p (alias)) if (!unmodifiable_var_p (svars->var))
mark_call_clobbered (svars->var, pi->escape_mask); mark_call_clobbered (svars->var, pi->escape_mask);
} }
else if (!unmodifiable_var_p (alias)) bitmap_clear (queued);
mark_call_clobbered (alias, pi->escape_mask);
} }
} }
} }
...@@ -600,6 +618,8 @@ set_initial_properties (struct alias_info *ai) ...@@ -600,6 +618,8 @@ set_initial_properties (struct alias_info *ai)
MTAG_GLOBAL (tag) = true; MTAG_GLOBAL (tag) = true;
} }
} }
BITMAP_FREE (queued);
} }
/* Compute which variables need to be marked call clobbered because /* Compute which variables need to be marked call clobbered because
...@@ -611,10 +631,11 @@ compute_call_clobbered (struct alias_info *ai) ...@@ -611,10 +631,11 @@ compute_call_clobbered (struct alias_info *ai)
{ {
VEC (tree, heap) *worklist = NULL; VEC (tree, heap) *worklist = NULL;
VEC (int,heap) *worklist2 = NULL; VEC (int,heap) *worklist2 = NULL;
bitmap on_worklist; bitmap on_worklist, queued;
timevar_push (TV_CALL_CLOBBER); timevar_push (TV_CALL_CLOBBER);
on_worklist = BITMAP_ALLOC (NULL); on_worklist = BITMAP_ALLOC (NULL);
queued = BITMAP_ALLOC (NULL);
set_initial_properties (ai); set_initial_properties (ai);
init_transitive_clobber_worklist (&worklist, &worklist2, on_worklist); init_transitive_clobber_worklist (&worklist, &worklist2, on_worklist);
...@@ -626,11 +647,12 @@ compute_call_clobbered (struct alias_info *ai) ...@@ -626,11 +647,12 @@ compute_call_clobbered (struct alias_info *ai)
bitmap_clear_bit (on_worklist, DECL_UID (curr)); bitmap_clear_bit (on_worklist, DECL_UID (curr));
mark_call_clobbered (curr, reason); mark_call_clobbered (curr, reason);
mark_aliases_call_clobbered (curr, &worklist, &worklist2, mark_aliases_call_clobbered (curr, &worklist, &worklist2,
on_worklist); on_worklist, queued);
} }
VEC_free (tree, heap, worklist); VEC_free (tree, heap, worklist);
VEC_free (int, heap, worklist2); VEC_free (int, heap, worklist2);
BITMAP_FREE (on_worklist); BITMAP_FREE (on_worklist);
BITMAP_FREE (queued);
compute_tag_properties (); compute_tag_properties ();
timevar_pop (TV_CALL_CLOBBER); timevar_pop (TV_CALL_CLOBBER);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment