This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Cleanup do_per_function, require less push/pop_cfun
- From: Richard Biener <rguenther at suse dot de>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Tue, 29 Apr 2014 11:02:26 +0200 (CEST)
- Subject: Re: [PATCH] Cleanup do_per_function, require less push/pop_cfun
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LSU dot 2 dot 11 dot 1404231636150 dot 18709 at zhemvz dot fhfr dot qr> <alpine dot LSU dot 2 dot 11 dot 1404281325330 dot 18709 at zhemvz dot fhfr dot qr> <20140428150850 dot GB16757 at kam dot mff dot cuni dot cz>
On Mon, 28 Apr 2014, Jan Hubicka wrote:
> > On Wed, 23 Apr 2014, Richard Biener wrote:
> >
> > >
> > > This avoids all the complex work on simple things like
> > > clear_last_verified. It also makes eventually inlining all
> > > calls (for example the one with the small IPA pass hack)
> > > less code-duplicating.
> > >
> > > I had to remove the asserts in favor of frees of DOM info in
> > > release_function_body as the old code released DOM info in
> > > various odd places.
> > >
> > > Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> > >
> > > Honza, does this look ok to you?
> >
> > I've heard nothing back so I assume it's ok and committed it.
>
> The purpose of the assert was to make sure that the dominance trees
> are not maintained for whole program at once. release_function_body is
> never called for a function that is "current" and thus the dominators should
> be always freed.
>
> At beggining the datastructure was global and thus it was not possible
> to hold two. I think that is long fixed, but it seems bit wasteful to
> keep all the dominance trees around. Do you know how dominators leak
> there?
As I didn't really remove sensible calls to free_dominance_info
(but from execute_function_dump, execute_function_todo,
clear_last_verified, verify_curr_properties and
update_properties_after_pass) I concluded one of those must
be responsible for spuriously freeing dominance info, likely
of functions determined unreachable.
I suspect IPA passes TODO_* to be responsible eventually, or their
transform stage.
I am testing the following.
Richard.
Index: gcc/dominance.c
===================================================================
*** gcc/dominance.c (revision 209890)
--- gcc/dominance.c (working copy)
*************** calculate_dominance_info (enum cdi_direc
*** 681,704 ****
/* Free dominance information for direction DIR. */
void
! free_dominance_info (enum cdi_direction dir)
{
basic_block bb;
unsigned int dir_index = dom_convert_dir_to_idx (dir);
! if (!dom_info_available_p (dir))
return;
! FOR_ALL_BB_FN (bb, cfun)
{
et_free_tree_force (bb->dom[dir_index]);
bb->dom[dir_index] = NULL;
}
et_free_pools ();
! n_bbs_in_dom_tree[dir_index] = 0;
! dom_computed[dir_index] = DOM_NONE;
}
/* Return the immediate dominator of basic block BB. */
--- 681,710 ----
/* Free dominance information for direction DIR. */
void
! free_dominance_info (function *fn, enum cdi_direction dir)
{
basic_block bb;
unsigned int dir_index = dom_convert_dir_to_idx (dir);
! if (!dom_info_available_p (fn, dir))
return;
! FOR_ALL_BB_FN (bb, fn)
{
et_free_tree_force (bb->dom[dir_index]);
bb->dom[dir_index] = NULL;
}
et_free_pools ();
! fn->cfg->x_n_bbs_in_dom_tree[dir_index] = 0;
! fn->cfg->x_dom_computed[dir_index] = DOM_NONE;
! }
!
! void
! free_dominance_info (enum cdi_direction dir)
! {
! free_dominance_info (cfun, dir);
}
/* Return the immediate dominator of basic block BB. */
*************** next_dom_son (enum cdi_direction dir, ba
*** 1461,1471 ****
/* Return dominance availability for dominance info DIR. */
enum dom_state
! dom_info_state (enum cdi_direction dir)
{
unsigned int dir_index = dom_convert_dir_to_idx (dir);
! return dom_computed[dir_index];
}
/* Set the dominance availability for dominance info DIR to NEW_STATE. */
--- 1467,1485 ----
/* Return dominance availability for dominance info DIR. */
enum dom_state
! dom_info_state (function *fn, enum cdi_direction dir)
{
+ if (!fn->cfg)
+ return DOM_NONE;
+
unsigned int dir_index = dom_convert_dir_to_idx (dir);
+ return fn->cfg->x_dom_computed[dir_index];
+ }
! enum dom_state
! dom_info_state (enum cdi_direction dir)
! {
! return dom_info_state (cfun, dir);
}
/* Set the dominance availability for dominance info DIR to NEW_STATE. */
*************** set_dom_info_availability (enum cdi_dire
*** 1481,1491 ****
/* Returns true if dominance information for direction DIR is available. */
bool
! dom_info_available_p (enum cdi_direction dir)
{
! unsigned int dir_index = dom_convert_dir_to_idx (dir);
! return dom_computed[dir_index] != DOM_NONE;
}
DEBUG_FUNCTION void
--- 1495,1509 ----
/* Returns true if dominance information for direction DIR is available. */
bool
! dom_info_available_p (function *fn, enum cdi_direction dir)
{
! return dom_info_state (fn, dir) != DOM_NONE;
! }
! bool
! dom_info_available_p (enum cdi_direction dir)
! {
! return dom_info_available_p (cfun, dir);
}
DEBUG_FUNCTION void
Index: gcc/basic-block.h
===================================================================
*** gcc/basic-block.h (revision 209890)
--- gcc/basic-block.h (working copy)
*************** enum cdi_direction
*** 826,835 ****
--- 826,838 ----
CDI_POST_DOMINATORS = 2
};
+ extern enum dom_state dom_info_state (function *, enum cdi_direction);
extern enum dom_state dom_info_state (enum cdi_direction);
extern void set_dom_info_availability (enum cdi_direction, enum dom_state);
+ extern bool dom_info_available_p (function *, enum cdi_direction);
extern bool dom_info_available_p (enum cdi_direction);
extern void calculate_dominance_info (enum cdi_direction);
+ extern void free_dominance_info (function *, enum cdi_direction);
extern void free_dominance_info (enum cdi_direction);
extern basic_block nearest_common_dominator (enum cdi_direction,
basic_block, basic_block);
Index: gcc/passes.c
===================================================================
*** gcc/passes.c (revision 209890)
--- gcc/passes.c (working copy)
*************** execute_function_todo (function *fn, voi
*** 1761,1801 ****
rebuild_cgraph_edges ();
/* If we've seen errors do not bother running any verifiers. */
! if (seen_error ())
{
- pop_cfun ();
- return;
- }
-
#if defined ENABLE_CHECKING
! if (flags & TODO_verify_ssa)
! {
! verify_gimple_in_cfg (cfun);
! verify_ssa (true);
! }
! else if (flags & TODO_verify_stmts)
! verify_gimple_in_cfg (cfun);
! if (flags & TODO_verify_flow)
! verify_flow_info ();
! if (flags & TODO_verify_il)
! {
! if (current_loops
! && loops_state_satisfies_p (LOOP_CLOSED_SSA))
{
! if (!(flags & (TODO_verify_stmts|TODO_verify_ssa)))
! verify_gimple_in_cfg (cfun);
! if (!(flags & TODO_verify_ssa))
! verify_ssa (true);
! verify_loop_closed_ssa (false);
}
! }
! if (flags & TODO_verify_rtl_sharing)
! verify_rtl_sharing ();
#endif
fn->last_verified = flags & TODO_verify_all;
pop_cfun ();
}
/* Perform all TODO actions. */
--- 1761,1813 ----
rebuild_cgraph_edges ();
/* If we've seen errors do not bother running any verifiers. */
! if (!seen_error ())
{
#if defined ENABLE_CHECKING
! dom_state pre_verify_state = dom_info_state (fn, CDI_DOMINATORS);
! dom_state pre_verify_pstate = dom_info_state (fn, CDI_POST_DOMINATORS);
!
! if (flags & TODO_verify_ssa)
{
! verify_gimple_in_cfg (cfun);
! verify_ssa (true);
}
! else if (flags & TODO_verify_stmts)
! verify_gimple_in_cfg (cfun);
! if (flags & TODO_verify_flow)
! verify_flow_info ();
! if (flags & TODO_verify_il)
! {
! if (current_loops
! && loops_state_satisfies_p (LOOP_CLOSED_SSA))
! {
! if (!(flags & (TODO_verify_stmts|TODO_verify_ssa)))
! verify_gimple_in_cfg (cfun);
! if (!(flags & TODO_verify_ssa))
! verify_ssa (true);
! verify_loop_closed_ssa (false);
! }
! }
! if (flags & TODO_verify_rtl_sharing)
! verify_rtl_sharing ();
!
! /* Make sure verifiers don't change dominator state. */
! gcc_assert (dom_info_state (fn, CDI_DOMINATORS) == pre_verify_state);
! gcc_assert (dom_info_state (fn, CDI_POST_DOMINATORS) == pre_verify_pstate);
#endif
+ }
fn->last_verified = flags & TODO_verify_all;
pop_cfun ();
+
+ /* For IPA passes make sure to release dominator info, it can be
+ computed by non-verifying TODOs. */
+ if (!cfun)
+ {
+ free_dominance_info (fn, CDI_DOMINATORS);
+ free_dominance_info (fn, CDI_POST_DOMINATORS);
+ }
}
/* Perform all TODO actions. */
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c (revision 209890)
--- gcc/cgraph.c (working copy)
*************** release_function_body (tree decl)
*** 1696,1703 ****
}
if (cfun->cfg)
{
! free_dominance_info (CDI_DOMINATORS);
! free_dominance_info (CDI_POST_DOMINATORS);
clear_edges ();
cfun->cfg = NULL;
}
--- 1696,1703 ----
}
if (cfun->cfg)
{
! gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
! gcc_assert (!dom_info_available_p (CDI_POST_DOMINATORS));
clear_edges ();
cfun->cfg = NULL;
}