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]

Fix inliner's accounting of stack usage


Hi,
this patch fixes thinko I introduced while fixing another thinko
in accounting stack frame sizes.  Due to the bug we did not
take into account stack size of the outermost function in the
inline tree resulting in too many decisions to not inline
because of large-stack-frae-growth limits.

The patch also adds some debugging goodies.

Bootstrapped/regtested x86_64-linux, will commit it later today.

Honza

	* ipa-inline.c (caller_growth_limits): Fix thinko when
	looking for largest stack frame.
	* ipa-inline.h (dump_inline_summary): Declare.
	* ipa-inline-analysis.c (dump_inline_edge_summary): Dump info
	on stack usage.
	(dump_inline_summary): Export.
	(debug_inline_summary): Declare as DEBUG_FUNCTION.
Index: ipa-inline.c
===================================================================
*** ipa-inline.c	(revision 173216)
--- ipa-inline.c	(working copy)
*************** caller_growth_limits (struct cgraph_edge
*** 151,157 ****
       we immediately inline to.  This is the most relaxed
       interpretation of the rule "do not grow large functions
       too much in order to prevent compiler from exploding".  */
!   do
      {
        info = inline_summary (to);
        if (limit < info->self_size)
--- 151,157 ----
       we immediately inline to.  This is the most relaxed
       interpretation of the rule "do not grow large functions
       too much in order to prevent compiler from exploding".  */
!   while (true)
      {
        info = inline_summary (to);
        if (limit < info->self_size)
*************** caller_growth_limits (struct cgraph_edge
*** 160,167 ****
  	stack_size_limit = info->estimated_self_stack_size;
        if (to->global.inlined_to)
          to = to->callers->caller;
      }
-   while (to->global.inlined_to);
  
    what_info = inline_summary (what);
  
--- 160,168 ----
  	stack_size_limit = info->estimated_self_stack_size;
        if (to->global.inlined_to)
          to = to->callers->caller;
+       else
+ 	break;
      }
  
    what_info = inline_summary (what);
  
*************** caller_growth_limits (struct cgraph_edge
*** 181,192 ****
        return false;
      }
  
    /* FIXME: Stack size limit often prevents inlining in Fortran programs
       due to large i/o datastructures used by the Fortran front-end.
       We ought to ignore this limit when we know that the edge is executed
       on every invocation of the caller (i.e. its call statement dominates
       exit block).  We do not track this information, yet.  */
!   stack_size_limit += (stack_size_limit
  		       * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100);
  
    inlined_stack = (outer_info->stack_frame_offset
--- 182,196 ----
        return false;
      }
  
+   if (!what_info->estimated_stack_size)
+     return true;
+ 
    /* FIXME: Stack size limit often prevents inlining in Fortran programs
       due to large i/o datastructures used by the Fortran front-end.
       We ought to ignore this limit when we know that the edge is executed
       on every invocation of the caller (i.e. its call statement dominates
       exit block).  We do not track this information, yet.  */
!   stack_size_limit += ((gcov_type)stack_size_limit
  		       * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100);
  
    inlined_stack = (outer_info->stack_frame_offset
Index: ipa-inline.h
===================================================================
*** ipa-inline.h	(revision 173211)
--- ipa-inline.h	(working copy)
*************** extern VEC(edge_growth_cache_entry,heap)
*** 141,146 ****
--- 141,147 ----
  /* In ipa-inline-analysis.c  */
  void debug_inline_summary (struct cgraph_node *);
  void dump_inline_summaries (FILE *f);
+ void dump_inline_summary (FILE * f, struct cgraph_node *node);
  void inline_generate_summary (void);
  void inline_read_summary (void);
  void inline_write_summary (cgraph_node_set, varpool_node_set);
Index: ipa-inline-analysis.c
===================================================================
*** ipa-inline-analysis.c	(revision 173211)
--- ipa-inline-analysis.c	(working copy)
*************** dump_inline_edge_summary (FILE * f, int 
*** 735,741 ****
    for (edge = node->callees; edge; edge = edge->next_callee)
      {
        struct inline_edge_summary *es = inline_edge_summary (edge);
!       fprintf (f, "%*s%s/%i %s\n%*s  loop depth:%2i freq:%4i size:%2i time: %2i",
  	       indent, "", cgraph_node_name (edge->callee),
  	       edge->callee->uid, 
  	       !edge->inline_failed ? "inlined"
--- 735,741 ----
    for (edge = node->callees; edge; edge = edge->next_callee)
      {
        struct inline_edge_summary *es = inline_edge_summary (edge);
!       fprintf (f, "%*s%s/%i %s\n%*s  loop depth:%2i freq:%4i size:%2i time: %2i callee size:%2i stack:%2i",
  	       indent, "", cgraph_node_name (edge->callee),
  	       edge->callee->uid, 
  	       !edge->inline_failed ? "inlined"
*************** dump_inline_edge_summary (FILE * f, int 
*** 744,750 ****
  	       es->loop_depth,	
                 edge->frequency,
  	       es->call_stmt_size,
! 	       es->call_stmt_time);
        if (es->predicate)
  	{
  	  fprintf (f, " predicate: ");
--- 744,752 ----
  	       es->loop_depth,	
                 edge->frequency,
  	       es->call_stmt_size,
! 	       es->call_stmt_time,
! 	       (int)inline_summary (edge->callee)->size,
! 	       (int)inline_summary (edge->callee)->estimated_stack_size);
        if (es->predicate)
  	{
  	  fprintf (f, " predicate: ");
*************** dump_inline_edge_summary (FILE * f, int 
*** 753,759 ****
        else
  	  fprintf (f, "\n");
        if (!edge->inline_failed)
! 	dump_inline_edge_summary (f, indent+2, edge->callee, info);
      }
    for (edge = node->indirect_calls; edge; edge = edge->next_callee)
      {
--- 755,768 ----
        else
  	  fprintf (f, "\n");
        if (!edge->inline_failed)
! 	{
!           fprintf (f, "%*sStack frame offset %i, callee self size %i, callee size %i\n",
! 		   indent+2, "",
! 		   (int)inline_summary (edge->callee)->stack_frame_offset,
! 		   (int)inline_summary (edge->callee)->estimated_self_stack_size,
! 		   (int)inline_summary (edge->callee)->estimated_stack_size);
! 	  dump_inline_edge_summary (f, indent+2, edge->callee, info);
! 	}
      }
    for (edge = node->indirect_calls; edge; edge = edge->next_callee)
      {
*************** dump_inline_edge_summary (FILE * f, int 
*** 775,781 ****
  }
  
  
! static void
  dump_inline_summary (FILE * f, struct cgraph_node *node)
  {
    if (node->analyzed)
--- 784,790 ----
  }
  
  
! void
  dump_inline_summary (FILE * f, struct cgraph_node *node)
  {
    if (node->analyzed)
*************** dump_inline_summary (FILE * f, struct cg
*** 816,822 ****
      }
  }
  
! void
  debug_inline_summary (struct cgraph_node *node)
  {
    dump_inline_summary (stderr, node);
--- 825,831 ----
      }
  }
  
! DEBUG_FUNCTION void
  debug_inline_summary (struct cgraph_node *node)
  {
    dump_inline_summary (stderr, node);


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