2007-09-20 Richard Guenther 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. Index: tree-ssa-alias.c =================================================================== *** tree-ssa-alias.c (revision 128618) --- tree-ssa-alias.c (working copy) *************** mark_aliases_call_clobbered (tree tag, V *** 366,372 **** VEC (int, heap) **worklist2, bitmap on_worklist) { ! bitmap aliases; bitmap_iterator bi; unsigned int i; tree entry; --- 366,372 ---- VEC (int, heap) **worklist2, bitmap on_worklist) { ! bitmap aliases, queued; bitmap_iterator bi; unsigned int i; tree entry; *************** mark_aliases_call_clobbered (tree tag, V *** 378,383 **** --- 378,384 ---- if (!aliases) return; + queued = BITMAP_ALLOC (&alias_bitmap_obstack); EXECUTE_IF_SET_IN_BITMAP (aliases, 0, i, bi) { entry = referenced_var (i); *************** mark_aliases_call_clobbered (tree tag, V *** 387,399 **** in order to allow C/C++ tricks that involve pointer arithmetic to work. */ if (TREE_CODE (entry) == STRUCT_FIELD_TAG) ! { ! 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)) { add_to_worklist (entry, worklist, worklist2, ta->escape_mask, --- 388,394 ---- in order to allow C/C++ tricks that involve pointer arithmetic to work. */ if (TREE_CODE (entry) == STRUCT_FIELD_TAG) ! bitmap_set_bit (queued, DECL_UID (SFT_PARENT_VAR (entry))); else if (!unmodifiable_var_p (entry)) { add_to_worklist (entry, worklist, worklist2, ta->escape_mask, *************** mark_aliases_call_clobbered (tree tag, V *** 401,406 **** --- 396,410 ---- mark_call_clobbered (entry, ta->escape_mask); } } + 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_FREE (queued); } /* Tags containing global vars need to be marked as global. *************** set_initial_properties (struct alias_inf *** 545,552 **** --- 549,558 ---- if (pi->pt_vars) { + bitmap queued; bitmap_iterator bi; unsigned int j; + queued = BITMAP_ALLOC (&alias_bitmap_obstack); EXECUTE_IF_SET_IN_BITMAP (pi->pt_vars, 0, j, bi) { tree alias = referenced_var (j); *************** set_initial_properties (struct alias_inf *** 557,572 **** in order to allow C/C++ tricks that involve pointer arithmetic to work. */ if (TREE_CODE (alias) == STRUCT_FIELD_TAG) ! { ! subvar_t svars; ! svars = get_subvars_for_var (SFT_PARENT_VAR (alias)); ! for (; svars; svars = svars->next) ! if (!unmodifiable_var_p (alias)) ! mark_call_clobbered (svars->var, pi->escape_mask); ! } else if (!unmodifiable_var_p (alias)) mark_call_clobbered (alias, pi->escape_mask); } } } --- 563,581 ---- in order to allow C/C++ tricks that involve pointer arithmetic to work. */ 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); } + EXECUTE_IF_SET_IN_BITMAP (queued, 0, j, bi) + { + subvar_t svars; + svars = get_subvars_for_var (referenced_var (j)); + for (; svars; svars = svars->next) + if (!unmodifiable_var_p (svars->var)) + mark_call_clobbered (svars->var, pi->escape_mask); + } + BITMAP_FREE (queued); } }