This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PR tree-optimize/49373 (IPA-PTA regression)


On Sat, 25 Jun 2011, Jan Hubicka wrote:

> Hi,
> just for those who are interested, this is quick&dirty patch adding another
> pass of local optimization passes at WPA time.  I've added early inliner and
> IPA-SRA because I was curious how much of optimization oppurtunities we are
> missing by limiting those to early pass.

At WPA time?  I thought we don't have function bodies around.

Richard.

> With Early inlining it seems to be very little. We inline one extra call when
> building Mozilla in LTO mode.
> 
> IPA SRA is different story.  While we do 579 IPA SRA clones in the early pass,
> the late pass produces 13014 clones (22 times more ;) suggesting that the pass
> might be interesting at IPA level after all.
> 
> There are 78686 functions after inlining in Mozilla, so one out of 7 functions
> is touched.
> 
> Size difference of libxul is not great, about 100Kb reduction. I will try
> benchmarking it eventually, too.
> 
> Honza
> 
> 
> Index: cgraph.c
> ===================================================================
> *** cgraph.c	(revision 175350)
> --- cgraph.c	(working copy)
> *************** cgraph_release_function_body (struct cgr
> *** 1389,1396 ****
>   	}
>         if (cfun->cfg)
>   	{
> ! 	  gcc_assert (dom_computed[0] == DOM_NONE);
> ! 	  gcc_assert (dom_computed[1] == DOM_NONE);
>   	  clear_edges ();
>   	}
>         if (cfun->value_histograms)
> --- 1393,1403 ----
>   	}
>         if (cfun->cfg)
>   	{
> ! 	  /*gcc_assert (dom_computed[0] == DOM_NONE);
> ! 	  gcc_assert (dom_computed[1] == DOM_NONE);*/
> ! free_dominance_info (CDI_DOMINATORS);
> ! free_dominance_info (CDI_POST_DOMINATORS);
> ! 
>   	  clear_edges ();
>   	}
>         if (cfun->value_histograms)
> Index: tree-pass.h
> ===================================================================
> *** tree-pass.h	(revision 175350)
> --- tree-pass.h	(working copy)
> *************** extern struct simple_ipa_opt_pass pass_i
> *** 452,458 ****
>   extern struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility;
>   extern struct simple_ipa_opt_pass pass_ipa_tree_profile;
>   
> ! extern struct simple_ipa_opt_pass pass_early_local_passes;
>   
>   extern struct ipa_opt_pass_d pass_ipa_whole_program_visibility;
>   extern struct ipa_opt_pass_d pass_ipa_lto_gimple_out;
> --- 452,458 ----
>   extern struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility;
>   extern struct simple_ipa_opt_pass pass_ipa_tree_profile;
>   
> ! extern struct simple_ipa_opt_pass pass_early_local_passes, pass_late_local_passes, pass_late_local_passes2;
>   
>   extern struct ipa_opt_pass_d pass_ipa_whole_program_visibility;
>   extern struct ipa_opt_pass_d pass_ipa_lto_gimple_out;
> Index: ipa-inline-analysis.c
> ===================================================================
> *** ipa-inline-analysis.c	(revision 175350)
> --- ipa-inline-analysis.c	(working copy)
> *************** estimate_function_body_sizes (struct cgr
> *** 1535,1542 ****
>   		  edge->call_stmt_cannot_inline_p = true;
>   		  gimple_call_set_cannot_inline (stmt, true);
>   		}
> ! 	      else
> ! 		gcc_assert (!gimple_call_cannot_inline_p (stmt));
>   	    }
>   
>   	  /* TODO: When conditional jump or swithc is known to be constant, but
> --- 1535,1542 ----
>   		  edge->call_stmt_cannot_inline_p = true;
>   		  gimple_call_set_cannot_inline (stmt, true);
>   		}
> ! 	      /*else
> ! 		gcc_assert (!gimple_call_cannot_inline_p (stmt));*/
>   	    }
>   
>   	  /* TODO: When conditional jump or swithc is known to be constant, but
> Index: tree-inline.c
> ===================================================================
> *** tree-inline.c	(revision 175350)
> --- tree-inline.c	(working copy)
> *************** expand_call_inline (basic_block bb, gimp
> *** 3891,3897 ****
>     id->src_cfun = DECL_STRUCT_FUNCTION (fn);
>     id->gimple_call = stmt;
>   
> !   gcc_assert (!id->src_cfun->after_inlining);
>   
>     id->entry_bb = bb;
>     if (lookup_attribute ("cold", DECL_ATTRIBUTES (fn)))
> --- 3891,3897 ----
>     id->src_cfun = DECL_STRUCT_FUNCTION (fn);
>     id->gimple_call = stmt;
>   
> !   /*gcc_assert (!id->src_cfun->after_inlining);*/
>   
>     id->entry_bb = bb;
>     if (lookup_attribute ("cold", DECL_ATTRIBUTES (fn)))
> Index: tree-optimize.c
> ===================================================================
> *** tree-optimize.c	(revision 175350)
> --- tree-optimize.c	(working copy)
> *************** struct simple_ipa_opt_pass pass_early_lo
> *** 123,128 ****
> --- 123,189 ----
>   /* Gate: execute, or not, all of the non-trivial optimizations.  */
>   
>   static bool
> + gate_all_late_local_passes (void)
> + {
> + 	  /* Don't bother doing anything if the program has errors.  */
> +   return (!seen_error () && optimize);
> + }
> + 
> + static unsigned int
> + execute_all_late_local_passes (void)
> + {
> +   /* Once this pass (and its sub-passes) are complete, all functions
> +      will be in SSA form.  Technically this state change is happening
> +      a tad late, since the sub-passes have not yet run, but since
> +      none of the sub-passes are IPA passes and do not create new
> +      functions, this is ok.  We're setting this value for the benefit
> +      of IPA passes that follow.  */
> +   if (cgraph_state < CGRAPH_STATE_IPA_SSA)
> +     cgraph_state = CGRAPH_STATE_IPA_SSA;
> +   return 0;
> + }
> + 
> + struct simple_ipa_opt_pass pass_late_local_passes =
> + {
> +  {
> +   SIMPLE_IPA_PASS,
> +   "late_local_cleanups",		/* name */
> +   gate_all_late_local_passes,		/* gate */
> +   execute_all_late_local_passes,	/* execute */
> +   NULL,					/* sub */
> +   NULL,					/* next */
> +   0,					/* static_pass_number */
> +   TV_EARLY_LOCAL,			/* tv_id */
> +   0,					/* properties_required */
> +   0,					/* properties_provided */
> +   0,					/* properties_destroyed */
> +   0,					/* todo_flags_start */
> +   TODO_remove_functions	 		/* todo_flags_finish */
> +  }
> + };
> + 
> + struct simple_ipa_opt_pass pass_late_local_passes2 =
> + {
> +  {
> +   SIMPLE_IPA_PASS,
> +   "late_local_cleanups2",		/* name */
> +   gate_all_late_local_passes,		/* gate */
> +   execute_all_late_local_passes,	/* execute */
> +   NULL,					/* sub */
> +   NULL,					/* next */
> +   0,					/* static_pass_number */
> +   TV_EARLY_LOCAL,			/* tv_id */
> +   0,					/* properties_required */
> +   0,					/* properties_provided */
> +   0,					/* properties_destroyed */
> +   0,					/* todo_flags_start */
> +   TODO_remove_functions	 		/* todo_flags_finish */
> +  }
> + };
> + 
> + /* Gate: execute, or not, all of the non-trivial optimizations.  */
> + 
> + static bool
>   gate_all_early_optimizations (void)
>   {
>     return (optimize >= 1
> Index: passes.c
> ===================================================================
> *** passes.c	(revision 175350)
> --- passes.c	(working copy)
> *************** init_optimization_passes (void)
> *** 1263,1268 ****
> --- 1263,1288 ----
>        passes are executed after partitioning and thus see just parts of the
>        compiled unit.  */
>     p = &all_late_ipa_passes;
> +   NEXT_PASS (pass_late_local_passes);
> +     {
> +       struct opt_pass **p = &pass_late_local_passes.pass.sub;
> +       NEXT_PASS (pass_inline_parameters);
> +       NEXT_PASS (pass_release_ssa_names);
> +     }
> +   NEXT_PASS (pass_late_local_passes2);
> +     {
> +       struct opt_pass **p = &pass_late_local_passes2.pass.sub;
> +       NEXT_PASS (pass_early_inline);
> +       NEXT_PASS (pass_remove_cgraph_callee_edges);
> +       NEXT_PASS (pass_ccp);
> +       NEXT_PASS (pass_forwprop);
> +       NEXT_PASS (pass_fre);
> +       NEXT_PASS (pass_cd_dce);
> +       NEXT_PASS (pass_early_ipa_sra);
> +       NEXT_PASS (pass_release_ssa_names);
> +       NEXT_PASS (pass_rebuild_cgraph_edges);
> +       NEXT_PASS (pass_inline_parameters);
> +     }
>     NEXT_PASS (pass_ipa_pta);
>     *p = NULL;
>     /* These passes are run after IPA passes on every function that is being
> Index: statistics.c
> ===================================================================
> *** statistics.c	(revision 175350)
> --- statistics.c	(working copy)
> *************** statistics_fini_pass_3 (void **slot, voi
> *** 171,176 ****
> --- 171,178 ----
>   void
>   statistics_fini_pass (void)
>   {
> +   if (!current_pass)
> +     return;
>     if (current_pass->static_pass_number == -1)
>       return;
>   
> 
> 

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]