public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR67783, quadraticness in IPA inline analysis
@ 2015-10-01 11:39 Richard Biener
  2015-10-01 12:24 ` Richard Biener
  2015-10-05 11:15 ` Richard Biener
  0 siblings, 2 replies; 7+ messages in thread
From: Richard Biener @ 2015-10-01 11:39 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jan Hubicka


The following avoids quadraticness in the loop depth by only considering
loop header defs as IVs for the analysis of the loop_stride predicate.
This will miss cases like

foo (int inv)
{
 for (i = inv; i < n; ++i)
  {
    int derived_iv = i + i * inv;
    ...
  }
}

but I doubt that's important in practice.  Another way would be to
just consider the containing loop when analyzing the IV, thus iterate
over outermost loop bodies only, replacing the

  simple_iv (loop, loop_containing_stmt (stmt), use, &iv, true)

check with

  simple_iv (loop_containing_stmt (stmt), loop_containing_stmt (stmt), 
use, &iv, true);

but doing all this analysis for each stmt is already quite expensive,
esp. as we are doing it for all uses instead of all defs ...

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Honza, is this ok or did you do the current way on purpose (rather
than for completeness as it was easy to do?)

Thanks,
Richard.

2015-10-01  Richard Biener  <rguenther@suse.de>

	PR ipa/67783
	* ipa-inline-analysis.c (estimate_function_body_sizes): Only
	consider loop header PHI defs as IVs.

Index: gcc/ipa-inline-analysis.c
===================================================================
*** gcc/ipa-inline-analysis.c	(revision 228319)
--- gcc/ipa-inline-analysis.c	(working copy)
*************** estimate_function_body_sizes (struct cgr
*** 2760,2768 ****
  	{
  	  vec<edge> exits;
  	  edge ex;
! 	  unsigned int j, i;
  	  struct tree_niter_desc niter_desc;
- 	  basic_block *body = get_loop_body (loop);
  	  bb_predicate = *(struct predicate *) loop->header->aux;
  
  	  exits = get_loop_exit_edges (loop);
--- 2760,2767 ----
  	{
  	  vec<edge> exits;
  	  edge ex;
! 	  unsigned int j;
  	  struct tree_niter_desc niter_desc;
  	  bb_predicate = *(struct predicate *) loop->header->aux;
  
  	  exits = get_loop_exit_edges (loop);
*************** estimate_function_body_sizes (struct cgr
*** 2788,2833 ****
  	    }
  	  exits.release ();
  
! 	  for (i = 0; i < loop->num_nodes; i++)
  	    {
! 	      gimple_stmt_iterator gsi;
! 	      bb_predicate = *(struct predicate *) body[i]->aux;
! 	      for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
! 		   gsi_next (&gsi))
! 		{
! 		  gimple *stmt = gsi_stmt (gsi);
! 		  affine_iv iv;
! 		  ssa_op_iter iter;
! 		  tree use;
! 
! 		  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
! 		  {
! 		    predicate will_be_nonconstant;
! 
! 		    if (!simple_iv
! 			(loop, loop_containing_stmt (stmt), use, &iv, true)
! 			|| is_gimple_min_invariant (iv.step))
! 		      continue;
! 		    will_be_nonconstant
! 		      = will_be_nonconstant_expr_predicate (fbi.info, info,
! 							    iv.step,
! 							    nonconstant_names);
! 		    if (!true_predicate_p (&will_be_nonconstant))
! 		      will_be_nonconstant
! 			 = and_predicates (info->conds,
! 					   &bb_predicate,
! 					   &will_be_nonconstant);
! 		    if (!true_predicate_p (&will_be_nonconstant)
! 			&& !false_predicate_p (&will_be_nonconstant))
! 		      /* This is slightly inprecise.  We may want to represent
! 			 each loop with independent predicate.  */
! 		      loop_stride =
! 			and_predicates (info->conds, &loop_stride,
! 					&will_be_nonconstant);
! 		  }
! 		}
  	    }
- 	  free (body);
  	}
        set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
  			  loop_iterations);
--- 2787,2818 ----
  	    }
  	  exits.release ();
  
! 	  for (gphi_iterator gsi = gsi_start_phis (loop->header);
! 	       !gsi_end_p (gsi); gsi_next (&gsi))
  	    {
! 	      gphi *phi = gsi.phi ();
! 	      tree use = gimple_phi_result (phi);
! 	      affine_iv iv;
! 	      predicate will_be_nonconstant;
! 	      if (!virtual_operand_p (use)
! 		  || !simple_iv (loop, loop, use, &iv, true)
! 		  || is_gimple_min_invariant (iv.step))
! 		continue;
! 	      will_be_nonconstant
! 		= will_be_nonconstant_expr_predicate (fbi.info, info,
! 						      iv.step,
! 						      nonconstant_names);
! 	      if (!true_predicate_p (&will_be_nonconstant))
! 		will_be_nonconstant = and_predicates (info->conds,
! 						      &bb_predicate,
! 						      &will_be_nonconstant);
! 	      if (!true_predicate_p (&will_be_nonconstant)
! 		  && !false_predicate_p (&will_be_nonconstant))
! 		/* This is slightly inprecise.  We may want to represent
! 		   each loop with independent predicate.  */
! 		loop_stride = and_predicates (info->conds, &loop_stride,
! 					      &will_be_nonconstant);
  	    }
  	}
        set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
  			  loop_iterations);

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR67783, quadraticness in IPA inline analysis
  2015-10-01 11:39 [PATCH] Fix PR67783, quadraticness in IPA inline analysis Richard Biener
@ 2015-10-01 12:24 ` Richard Biener
  2015-10-05 11:15 ` Richard Biener
  1 sibling, 0 replies; 7+ messages in thread
From: Richard Biener @ 2015-10-01 12:24 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jan Hubicka

On Thu, 1 Oct 2015, Richard Biener wrote:

> 
> The following avoids quadraticness in the loop depth by only considering
> loop header defs as IVs for the analysis of the loop_stride predicate.
> This will miss cases like
> 
> foo (int inv)
> {
>  for (i = inv; i < n; ++i)
>   {
>     int derived_iv = i + i * inv;
>     ...
>   }
> }
> 
> but I doubt that's important in practice.  Another way would be to
> just consider the containing loop when analyzing the IV, thus iterate
> over outermost loop bodies only, replacing the
> 
>   simple_iv (loop, loop_containing_stmt (stmt), use, &iv, true)
> 
> check with
> 
>   simple_iv (loop_containing_stmt (stmt), loop_containing_stmt (stmt), 
> use, &iv, true);
> 
> but doing all this analysis for each stmt is already quite expensive,
> esp. as we are doing it for all uses instead of all defs ...
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> 
> Honza, is this ok or did you do the current way on purpose (rather
> than for completeness as it was easy to do?)
> 
> Thanks,
> Richard.
> 
> 2015-10-01  Richard Biener  <rguenther@suse.de>
> 
> 	PR ipa/67783
> 	* ipa-inline-analysis.c (estimate_function_body_sizes): Only
> 	consider loop header PHI defs as IVs.
> 
> Index: gcc/ipa-inline-analysis.c
> ===================================================================
> *** gcc/ipa-inline-analysis.c	(revision 228319)
> --- gcc/ipa-inline-analysis.c	(working copy)
> *************** estimate_function_body_sizes (struct cgr
> *** 2760,2768 ****
>   	{
>   	  vec<edge> exits;
>   	  edge ex;
> ! 	  unsigned int j, i;
>   	  struct tree_niter_desc niter_desc;
> - 	  basic_block *body = get_loop_body (loop);
>   	  bb_predicate = *(struct predicate *) loop->header->aux;
>   
>   	  exits = get_loop_exit_edges (loop);
> --- 2760,2767 ----
>   	{
>   	  vec<edge> exits;
>   	  edge ex;
> ! 	  unsigned int j;
>   	  struct tree_niter_desc niter_desc;
>   	  bb_predicate = *(struct predicate *) loop->header->aux;
>   
>   	  exits = get_loop_exit_edges (loop);
> *************** estimate_function_body_sizes (struct cgr
> *** 2788,2833 ****
>   	    }
>   	  exits.release ();
>   
> ! 	  for (i = 0; i < loop->num_nodes; i++)
>   	    {
> ! 	      gimple_stmt_iterator gsi;
> ! 	      bb_predicate = *(struct predicate *) body[i]->aux;
> ! 	      for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
> ! 		   gsi_next (&gsi))
> ! 		{
> ! 		  gimple *stmt = gsi_stmt (gsi);
> ! 		  affine_iv iv;
> ! 		  ssa_op_iter iter;
> ! 		  tree use;
> ! 
> ! 		  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
> ! 		  {
> ! 		    predicate will_be_nonconstant;
> ! 
> ! 		    if (!simple_iv
> ! 			(loop, loop_containing_stmt (stmt), use, &iv, true)
> ! 			|| is_gimple_min_invariant (iv.step))
> ! 		      continue;
> ! 		    will_be_nonconstant
> ! 		      = will_be_nonconstant_expr_predicate (fbi.info, info,
> ! 							    iv.step,
> ! 							    nonconstant_names);
> ! 		    if (!true_predicate_p (&will_be_nonconstant))
> ! 		      will_be_nonconstant
> ! 			 = and_predicates (info->conds,
> ! 					   &bb_predicate,
> ! 					   &will_be_nonconstant);
> ! 		    if (!true_predicate_p (&will_be_nonconstant)
> ! 			&& !false_predicate_p (&will_be_nonconstant))
> ! 		      /* This is slightly inprecise.  We may want to represent
> ! 			 each loop with independent predicate.  */
> ! 		      loop_stride =
> ! 			and_predicates (info->conds, &loop_stride,
> ! 					&will_be_nonconstant);
> ! 		  }
> ! 		}
>   	    }
> - 	  free (body);
>   	}
>         set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
>   			  loop_iterations);
> --- 2787,2818 ----
>   	    }
>   	  exits.release ();
>   
> ! 	  for (gphi_iterator gsi = gsi_start_phis (loop->header);
> ! 	       !gsi_end_p (gsi); gsi_next (&gsi))
>   	    {
> ! 	      gphi *phi = gsi.phi ();
> ! 	      tree use = gimple_phi_result (phi);
> ! 	      affine_iv iv;
> ! 	      predicate will_be_nonconstant;
> ! 	      if (!virtual_operand_p (use)

Just noticed the inverted predicate during testing.  Re-testing with
that fixed now.

Richard.

> ! 		  || !simple_iv (loop, loop, use, &iv, true)
> ! 		  || is_gimple_min_invariant (iv.step))
> ! 		continue;
> ! 	      will_be_nonconstant
> ! 		= will_be_nonconstant_expr_predicate (fbi.info, info,
> ! 						      iv.step,
> ! 						      nonconstant_names);
> ! 	      if (!true_predicate_p (&will_be_nonconstant))
> ! 		will_be_nonconstant = and_predicates (info->conds,
> ! 						      &bb_predicate,
> ! 						      &will_be_nonconstant);
> ! 	      if (!true_predicate_p (&will_be_nonconstant)
> ! 		  && !false_predicate_p (&will_be_nonconstant))
> ! 		/* This is slightly inprecise.  We may want to represent
> ! 		   each loop with independent predicate.  */
> ! 		loop_stride = and_predicates (info->conds, &loop_stride,
> ! 					      &will_be_nonconstant);
>   	    }
>   	}
>         set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
>   			  loop_iterations);
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR67783, quadraticness in IPA inline analysis
  2015-10-01 11:39 [PATCH] Fix PR67783, quadraticness in IPA inline analysis Richard Biener
  2015-10-01 12:24 ` Richard Biener
@ 2015-10-05 11:15 ` Richard Biener
  2015-10-05 15:34   ` Jan Hubicka
  1 sibling, 1 reply; 7+ messages in thread
From: Richard Biener @ 2015-10-05 11:15 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jan Hubicka

On Thu, 1 Oct 2015, Richard Biener wrote:

> 
> The following avoids quadraticness in the loop depth by only considering
> loop header defs as IVs for the analysis of the loop_stride predicate.
> This will miss cases like
> 
> foo (int inv)
> {
>  for (i = inv; i < n; ++i)
>   {
>     int derived_iv = i + i * inv;
>     ...
>   }
> }
> 
> but I doubt that's important in practice.  Another way would be to
> just consider the containing loop when analyzing the IV, thus iterate
> over outermost loop bodies only, replacing the
> 
>   simple_iv (loop, loop_containing_stmt (stmt), use, &iv, true)
> 
> check with
> 
>   simple_iv (loop_containing_stmt (stmt), loop_containing_stmt (stmt), 
> use, &iv, true);
> 
> but doing all this analysis for each stmt is already quite expensive,
> esp. as we are doing it for all uses instead of all defs ...
> 
> Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> 
> Honza, is this ok or did you do the current way on purpose (rather
> than for completeness as it was easy to do?)

Applied as r228472.

Richard.

> Thanks,
> Richard.
> 
> 2015-10-01  Richard Biener  <rguenther@suse.de>
> 
> 	PR ipa/67783
> 	* ipa-inline-analysis.c (estimate_function_body_sizes): Only
> 	consider loop header PHI defs as IVs.
> 
> Index: gcc/ipa-inline-analysis.c
> ===================================================================
> *** gcc/ipa-inline-analysis.c	(revision 228319)
> --- gcc/ipa-inline-analysis.c	(working copy)
> *************** estimate_function_body_sizes (struct cgr
> *** 2760,2768 ****
>   	{
>   	  vec<edge> exits;
>   	  edge ex;
> ! 	  unsigned int j, i;
>   	  struct tree_niter_desc niter_desc;
> - 	  basic_block *body = get_loop_body (loop);
>   	  bb_predicate = *(struct predicate *) loop->header->aux;
>   
>   	  exits = get_loop_exit_edges (loop);
> --- 2760,2767 ----
>   	{
>   	  vec<edge> exits;
>   	  edge ex;
> ! 	  unsigned int j;
>   	  struct tree_niter_desc niter_desc;
>   	  bb_predicate = *(struct predicate *) loop->header->aux;
>   
>   	  exits = get_loop_exit_edges (loop);
> *************** estimate_function_body_sizes (struct cgr
> *** 2788,2833 ****
>   	    }
>   	  exits.release ();
>   
> ! 	  for (i = 0; i < loop->num_nodes; i++)
>   	    {
> ! 	      gimple_stmt_iterator gsi;
> ! 	      bb_predicate = *(struct predicate *) body[i]->aux;
> ! 	      for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
> ! 		   gsi_next (&gsi))
> ! 		{
> ! 		  gimple *stmt = gsi_stmt (gsi);
> ! 		  affine_iv iv;
> ! 		  ssa_op_iter iter;
> ! 		  tree use;
> ! 
> ! 		  FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
> ! 		  {
> ! 		    predicate will_be_nonconstant;
> ! 
> ! 		    if (!simple_iv
> ! 			(loop, loop_containing_stmt (stmt), use, &iv, true)
> ! 			|| is_gimple_min_invariant (iv.step))
> ! 		      continue;
> ! 		    will_be_nonconstant
> ! 		      = will_be_nonconstant_expr_predicate (fbi.info, info,
> ! 							    iv.step,
> ! 							    nonconstant_names);
> ! 		    if (!true_predicate_p (&will_be_nonconstant))
> ! 		      will_be_nonconstant
> ! 			 = and_predicates (info->conds,
> ! 					   &bb_predicate,
> ! 					   &will_be_nonconstant);
> ! 		    if (!true_predicate_p (&will_be_nonconstant)
> ! 			&& !false_predicate_p (&will_be_nonconstant))
> ! 		      /* This is slightly inprecise.  We may want to represent
> ! 			 each loop with independent predicate.  */
> ! 		      loop_stride =
> ! 			and_predicates (info->conds, &loop_stride,
> ! 					&will_be_nonconstant);
> ! 		  }
> ! 		}
>   	    }
> - 	  free (body);
>   	}
>         set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
>   			  loop_iterations);
> --- 2787,2818 ----
>   	    }
>   	  exits.release ();
>   
> ! 	  for (gphi_iterator gsi = gsi_start_phis (loop->header);
> ! 	       !gsi_end_p (gsi); gsi_next (&gsi))
>   	    {
> ! 	      gphi *phi = gsi.phi ();
> ! 	      tree use = gimple_phi_result (phi);
> ! 	      affine_iv iv;
> ! 	      predicate will_be_nonconstant;
> ! 	      if (!virtual_operand_p (use)
> ! 		  || !simple_iv (loop, loop, use, &iv, true)
> ! 		  || is_gimple_min_invariant (iv.step))
> ! 		continue;
> ! 	      will_be_nonconstant
> ! 		= will_be_nonconstant_expr_predicate (fbi.info, info,
> ! 						      iv.step,
> ! 						      nonconstant_names);
> ! 	      if (!true_predicate_p (&will_be_nonconstant))
> ! 		will_be_nonconstant = and_predicates (info->conds,
> ! 						      &bb_predicate,
> ! 						      &will_be_nonconstant);
> ! 	      if (!true_predicate_p (&will_be_nonconstant)
> ! 		  && !false_predicate_p (&will_be_nonconstant))
> ! 		/* This is slightly inprecise.  We may want to represent
> ! 		   each loop with independent predicate.  */
> ! 		loop_stride = and_predicates (info->conds, &loop_stride,
> ! 					      &will_be_nonconstant);
>   	    }
>   	}
>         set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
>   			  loop_iterations);
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR67783, quadraticness in IPA inline analysis
  2015-10-05 11:15 ` Richard Biener
@ 2015-10-05 15:34   ` Jan Hubicka
  2015-10-10 19:02     ` Jan Hubicka
  0 siblings, 1 reply; 7+ messages in thread
From: Jan Hubicka @ 2015-10-05 15:34 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, Jan Hubicka

> On Thu, 1 Oct 2015, Richard Biener wrote:
> 
> > 
> > The following avoids quadraticness in the loop depth by only considering
> > loop header defs as IVs for the analysis of the loop_stride predicate.
> > This will miss cases like
> > 
> > foo (int inv)
> > {
> >  for (i = inv; i < n; ++i)
> >   {
> >     int derived_iv = i + i * inv;
> >     ...
> >   }
> > }
> > 
> > but I doubt that's important in practice.  Another way would be to
> > just consider the containing loop when analyzing the IV, thus iterate
> > over outermost loop bodies only, replacing the
> > 
> >   simple_iv (loop, loop_containing_stmt (stmt), use, &iv, true)
> > 
> > check with
> > 
> >   simple_iv (loop_containing_stmt (stmt), loop_containing_stmt (stmt), 
> > use, &iv, true);
> > 
> > but doing all this analysis for each stmt is already quite expensive,
> > esp. as we are doing it for all uses instead of all defs ...
> > 
> > Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
> > 
> > Honza, is this ok or did you do the current way on purpose (rather
> > than for completeness as it was easy to do?)
> 
> Applied as r228472.

Ah, sorry. I wrote you a reply but apparently did not send.  Yes, the patch looks
resonable - it is a heuristics after all.  Lets watch if the change make any difference
on polyhedron and other benchmarks.

Honza

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR67783, quadraticness in IPA inline analysis
  2015-10-05 15:34   ` Jan Hubicka
@ 2015-10-10 19:02     ` Jan Hubicka
  0 siblings, 0 replies; 7+ messages in thread
From: Jan Hubicka @ 2015-10-10 19:02 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: Richard Biener, gcc-patches

> 
> Ah, sorry. I wrote you a reply but apparently did not send.  Yes, the patch looks
> resonable - it is a heuristics after all.  Lets watch if the change make any difference
> on polyhedron and other benchmarks.

It seems there was regression on fatigue/fatigue2 http://gcc.opensuse.org/c++bench/pb11/
Fatigue was one of reasons to intorduce the heuristics, so it may be related to the patch :(

Honza
> 
> Honza

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR67783, quadraticness in IPA inline analysis
  2015-10-11  7:57 Dominique d'Humières
@ 2015-10-12  9:18 ` Richard Biener
  0 siblings, 0 replies; 7+ messages in thread
From: Richard Biener @ 2015-10-12  9:18 UTC (permalink / raw)
  To: Dominique d'Humières; +Cc: hubicka, GCC Patches

[-- Attachment #1: Type: TEXT/PLAIN, Size: 5444 bytes --]

On Sun, 11 Oct 2015, Dominique d'HumiÚres wrote:

> > It seems there was regression on fatigue/fatigue2 http://gcc.opensuse.org/c++bench/pb11/ Fatigue
> > was one of reasons to intorduce the heuristics, so it may be related to the patch :( 
> 
> The test in pr 64099 comment 14 now requires -fwhole-program to inline the subroutine perdida:
> 
> [Book15] lin/test% /opt/gcc/gcc6p-228566/bin/gfortran fatigue_v1nn2.f90 -Ofast
> [Book15] lin/test% time a.out > /dev/null
> 16.266u 0.003s 0:16.27 99.9%	0+0k 0+0io 36pf+0w
> [Book15] lin/test% /opt/gcc/gcc6p-228566/bin/gfortran fatigue_v1nn2.f90 -Ofast -fwhole-program
> [Book15] lin/test% time a.out > /dev/null
> 6.179u 0.001s 0:06.18 99.8%	0+0k 0+0io 0pf+0w

Ok, so for loops like

<bb 135>:
# S.255_53 = PHI <1(134), S.255_598(136)>
if (S.255_53 > 3)
  goto <bb 137>;
else
  goto <bb 136>;

<bb 136>:
_590 = S.255_53 * iftmp.446_62;
_591 = _587 + _590;
_592 = *back_stress_tensor.0_140[_591];
_593 = S.255_53 + _589;
_594 = back_stress_rate_tensor[_593];
_595 = plastic_time_step_521 * _594;
_596 = _592 + _595;
*back_stress_tensor.0_140[_591] = _596;
S.255_598 = S.255_53 + 1;
goto <bb 135>;

we analyze _591 and see that it is {iftmp.446_62, +, iftmp.446_62}
(missed strength-reduction in early opts).  And that is defined by
a stride load from the array descriptor with the usual
if (stride == 0) stride = 1 added.  With strength reduction
performed we'd see an IV in the loop header, without we have to
do the more expensive work.

I'm testing the following (solves the fatigue regression for me).

Richard.

2015-10-12  Richard Biener  <rguenther@suse.de>

	PR ipa/64099
	* ipa-inline-analysis.c (estimate_function_body_sizes): Re-add
	code that analyzes IVs on each stmt but in a cheaper way avoiding
	quadratic behavior.

Index: gcc/ipa-inline-analysis.c
===================================================================
*** gcc/ipa-inline-analysis.c	(revision 228703)
--- gcc/ipa-inline-analysis.c	(working copy)
*************** estimate_function_body_sizes (struct cgr
*** 2786,2822 ****
  				  &will_be_nonconstant);
  	    }
  	  exits.release ();
  
! 	  for (gphi_iterator gsi = gsi_start_phis (loop->header);
! 	       !gsi_end_p (gsi); gsi_next (&gsi))
  	    {
! 	      gphi *phi = gsi.phi ();
! 	      tree use = gimple_phi_result (phi);
! 	      affine_iv iv;
! 	      predicate will_be_nonconstant;
! 	      if (virtual_operand_p (use)
! 		  || !simple_iv (loop, loop, use, &iv, true)
! 		  || is_gimple_min_invariant (iv.step))
! 		continue;
! 	      will_be_nonconstant
! 		= will_be_nonconstant_expr_predicate (fbi.info, info,
! 						      iv.step,
! 						      nonconstant_names);
! 	      if (!true_predicate_p (&will_be_nonconstant))
! 		will_be_nonconstant = and_predicates (info->conds,
! 						      &bb_predicate,
! 						      &will_be_nonconstant);
! 	      if (!true_predicate_p (&will_be_nonconstant)
! 		  && !false_predicate_p (&will_be_nonconstant))
! 		/* This is slightly inprecise.  We may want to represent
! 		   each loop with independent predicate.  */
! 		loop_stride = and_predicates (info->conds, &loop_stride,
! 					      &will_be_nonconstant);
  	    }
  	}
        set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
  			  loop_iterations);
!       set_hint_predicate (&inline_summaries->get (node)->loop_stride, loop_stride);
        scev_finalize ();
      }
    FOR_ALL_BB_FN (bb, my_function)
--- 2786,2845 ----
  				  &will_be_nonconstant);
  	    }
  	  exits.release ();
+ 	}
  
!       /* To avoid quadratic behavior we analyze stride predicates only
!          with respect to the containing loop.  Thus we simply iterate
! 	 over all defs in the outermost loop body.  */
!       for (loop = loops_for_fn (cfun)->tree_root->inner;
! 	   loop != NULL; loop = loop->next)
! 	{
! 	  basic_block *body = get_loop_body (loop);
! 	  for (unsigned i = 0; i < loop->num_nodes; i++)
  	    {
! 	      gimple_stmt_iterator gsi;
! 	      bb_predicate = *(struct predicate *) body[i]->aux;
! 	      for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
! 		   gsi_next (&gsi))
! 		{
! 		  gimple *stmt = gsi_stmt (gsi);
! 
! 		  if (!is_gimple_assign (stmt))
! 		    continue;
! 
! 		  tree def = gimple_assign_lhs (stmt);
! 		  if (TREE_CODE (def) != SSA_NAME)
! 		    continue;
! 
! 		  affine_iv iv;
! 		  if (!simple_iv (loop_containing_stmt (stmt),
! 				  loop_containing_stmt (stmt),
! 				  def, &iv, true)
! 		      || is_gimple_min_invariant (iv.step))
! 		    continue;
! 
! 		  predicate will_be_nonconstant
! 		    = will_be_nonconstant_expr_predicate (fbi.info, info,
! 							  iv.step,
! 							  nonconstant_names);
! 		  if (!true_predicate_p (&will_be_nonconstant))
! 		    will_be_nonconstant
! 		      = and_predicates (info->conds, &bb_predicate,
! 					&will_be_nonconstant);
! 		  if (!true_predicate_p (&will_be_nonconstant)
! 		      && !false_predicate_p (&will_be_nonconstant))
! 		    /* This is slightly inprecise.  We may want to represent
! 		       each loop with independent predicate.  */
! 		    loop_stride = and_predicates (info->conds, &loop_stride,
! 						  &will_be_nonconstant);
! 		}
  	    }
+ 	  free (body);
  	}
        set_hint_predicate (&inline_summaries->get (node)->loop_iterations,
  			  loop_iterations);
!       set_hint_predicate (&inline_summaries->get (node)->loop_stride,
! 			  loop_stride);
        scev_finalize ();
      }
    FOR_ALL_BB_FN (bb, my_function)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR67783, quadraticness in IPA inline analysis
@ 2015-10-11  7:57 Dominique d'Humières
  2015-10-12  9:18 ` Richard Biener
  0 siblings, 1 reply; 7+ messages in thread
From: Dominique d'Humières @ 2015-10-11  7:57 UTC (permalink / raw)
  To: rguenther; +Cc: hubicka, GCC Patches

> It seems there was regression on fatigue/fatigue2 http://gcc.opensuse.org/c++bench/pb11/ Fatigue
> was one of reasons to intorduce the heuristics, so it may be related to the patch :( 

The test in pr 64099 comment 14 now requires -fwhole-program to inline the subroutine perdida:

[Book15] lin/test% /opt/gcc/gcc6p-228566/bin/gfortran fatigue_v1nn2.f90 -Ofast
[Book15] lin/test% time a.out > /dev/null
16.266u 0.003s 0:16.27 99.9%	0+0k 0+0io 36pf+0w
[Book15] lin/test% /opt/gcc/gcc6p-228566/bin/gfortran fatigue_v1nn2.f90 -Ofast -fwhole-program
[Book15] lin/test% time a.out > /dev/null
6.179u 0.001s 0:06.18 99.8%	0+0k 0+0io 0pf+0w

Dominique

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-10-12  9:18 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-01 11:39 [PATCH] Fix PR67783, quadraticness in IPA inline analysis Richard Biener
2015-10-01 12:24 ` Richard Biener
2015-10-05 11:15 ` Richard Biener
2015-10-05 15:34   ` Jan Hubicka
2015-10-10 19:02     ` Jan Hubicka
2015-10-11  7:57 Dominique d'Humières
2015-10-12  9:18 ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).