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]

Inliner summary cleanups


Hi,
this patch breaks inliner summaries into separate structure, as I hope every
pass will have.  THere are some challenges about what to embedd into cgraph
nodes and what to point to since cgraph nodes are actually quite memory
critical for whopr plan.  For this reason I added an accestor function for now.

It is clear we need some infrastructure to maintain the summaries: To dump
them, remove, duplicate at least.  This does not really fit into PM structure,
but it seems to me that probably it is best to place this as extra hooks to
ipa_opt_pass and collect them as optimization is running.

Bootstrapped/regtested i686-linux.  Will commit it shortly.

	* cgraph.c (dump_cgraph_node): Update.
	* cgraph.h (cgraph_local_info): Break out inline summary.
	* cgraphunit.c (cgraph_process_new_functions): Use inliner analysis
	hook.
	* ipa-inline (inline_summary): New accestor function.
	(cgraph_clone_inlined_nodes, cgraph_check_inline_limits,
	cgraph_decide_inlining, compute_inline_parameters): Update.
	* ipa.c (cgraph_remove_unreachable_nodes): Remove statistics.
Index: cgraph.c
===================================================================
*** cgraph.c	(revision 134945)
--- cgraph.c	(working copy)
*************** dump_cgraph_node (FILE *f, struct cgraph
*** 723,735 ****
    if (node->count)
      fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
  	     (HOST_WIDEST_INT)node->count);
!   if (node->local.self_insns)
!     fprintf (f, " %i insns", node->local.self_insns);
!   if (node->global.insns && node->global.insns != node->local.self_insns)
      fprintf (f, " (%i after inlining)", node->global.insns);
!   if (node->local.estimated_self_stack_size)
!     fprintf (f, " %i bytes stack usage", (int)node->local.estimated_self_stack_size);
!   if (node->global.estimated_stack_size != node->local.estimated_self_stack_size)
      fprintf (f, " %i bytes after inlining", (int)node->global.estimated_stack_size);
    if (node->origin)
      fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
--- 723,736 ----
    if (node->count)
      fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
  	     (HOST_WIDEST_INT)node->count);
!   if (node->local.inline_summary.self_insns)
!     fprintf (f, " %i insns", node->local.inline_summary.self_insns);
!   if (node->global.insns && node->global.insns
!       != node->local.inline_summary.self_insns)
      fprintf (f, " (%i after inlining)", node->global.insns);
!   if (node->local.inline_summary.estimated_self_stack_size)
!     fprintf (f, " %i bytes stack usage", (int)node->local.inline_summary.estimated_self_stack_size);
!   if (node->global.estimated_stack_size != node->local.inline_summary.estimated_self_stack_size)
      fprintf (f, " %i bytes after inlining", (int)node->global.estimated_stack_size);
    if (node->origin)
      fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
Index: cgraph.h
===================================================================
*** cgraph.h	(revision 134945)
--- cgraph.h	(working copy)
*************** extern const char * const cgraph_availab
*** 53,63 ****
  
  struct cgraph_local_info GTY(())
  {
!   /* Estimated stack frame consumption by the function.  */
!   HOST_WIDE_INT estimated_self_stack_size;
! 
!   /* Size of the function before inlining.  */
!   int self_insns;
  
    /* Set when function function is visible in current compilation unit only
       and its address is never taken.  */
--- 53,65 ----
  
  struct cgraph_local_info GTY(())
  {
!   struct inline_summary {
!     /* Estimated stack frame consumption by the function.  */
!     HOST_WIDE_INT estimated_self_stack_size;
! 
!     /* Size of the function before inlining.  */
!     int self_insns;
!   } inline_summary;
  
    /* Set when function function is visible in current compilation unit only
       and its address is never taken.  */
Index: cgraphunit.c
===================================================================
*** cgraphunit.c	(revision 134945)
--- cgraphunit.c	(working copy)
*************** cgraph_process_new_functions (void)
*** 460,475 ****
  	    cgraph_analyze_function (node);
  	  push_cfun (DECL_STRUCT_FUNCTION (fndecl));
  	  current_function_decl = fndecl;
! 	  node->local.inlinable = tree_inlinable_function_p (fndecl);
! 	  node->local.self_insns = estimate_num_insns (fndecl,
! 						       &eni_inlining_weights);
! 	  node->local.disregard_inline_limits
! 	    |= DECL_DISREGARD_INLINE_LIMITS (fndecl);
! 	  /* Inlining characteristics are maintained by the
! 	     cgraph_mark_inline.  */
! 	  node->global.insns = node->local.self_insns;
! 	  if (flag_really_no_inline && !node->local.disregard_inline_limits)
! 	     node->local.inlinable = 0;
  	  if ((cgraph_state == CGRAPH_STATE_IPA_SSA
  	      && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
  	      /* When not optimizing, be sure we run early local passes anyway
--- 460,466 ----
  	    cgraph_analyze_function (node);
  	  push_cfun (DECL_STRUCT_FUNCTION (fndecl));
  	  current_function_decl = fndecl;
! 	  pass_ipa_inline.function_generate_summary (node);
  	  if ((cgraph_state == CGRAPH_STATE_IPA_SSA
  	      && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
  	      /* When not optimizing, be sure we run early local passes anyway
Index: ipa-inline.c
===================================================================
*** ipa-inline.c	(revision 134945)
--- ipa-inline.c	(working copy)
*************** static int nfunctions_inlined;
*** 172,177 ****
--- 172,183 ----
  static int overall_insns;
  static gcov_type max_count;
  
+ static inline struct inline_summary *
+ inline_summary (struct cgraph_node *node)
+ {
+   return &node->local.inline_summary;
+ }
+ 
  /* Estimate size of the function after inlining WHAT into TO.  */
  
  static int
*************** cgraph_clone_inlined_nodes (struct cgrap
*** 226,233 ****
    else
      e->callee->global.inlined_to = e->caller;
    e->callee->global.stack_frame_offset
!     = e->caller->global.stack_frame_offset + e->caller->local.estimated_self_stack_size;
!   peak = e->callee->global.stack_frame_offset + e->callee->local.estimated_self_stack_size;
    if (e->callee->global.inlined_to->global.estimated_stack_size < peak)
      e->callee->global.inlined_to->global.estimated_stack_size = peak;
  
--- 232,241 ----
    else
      e->callee->global.inlined_to = e->caller;
    e->callee->global.stack_frame_offset
!     = e->caller->global.stack_frame_offset
!       + inline_summary (e->caller)->estimated_self_stack_size;
!   peak = e->callee->global.stack_frame_offset
!       + inline_summary (e->callee)->estimated_self_stack_size;
    if (e->callee->global.inlined_to->global.estimated_stack_size < peak)
      e->callee->global.inlined_to->global.estimated_stack_size = peak;
  
*************** cgraph_check_inline_limits (struct cgrap
*** 359,368 ****
  
    /* When inlining large function body called once into small function,
       take the inlined function as base for limiting the growth.  */
!   if (to->local.self_insns > what->local.self_insns)
!     limit = to->local.self_insns;
    else
!     limit = what->local.self_insns;
  
    limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
  
--- 367,376 ----
  
    /* When inlining large function body called once into small function,
       take the inlined function as base for limiting the growth.  */
!   if (inline_summary (to)->self_insns > inline_summary(what)->self_insns)
!     limit = inline_summary (to)->self_insns;
    else
!     limit = inline_summary (what)->self_insns;
  
    limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
  
*************** cgraph_check_inline_limits (struct cgrap
*** 378,389 ****
        return false;
      }
  
!   stack_size_limit = to->local.estimated_self_stack_size;
  
    stack_size_limit += stack_size_limit * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100;
  
    inlined_stack = (to->global.stack_frame_offset
! 		   + to->local.estimated_self_stack_size
  		   + what->global.estimated_stack_size);
    if (inlined_stack  > stack_size_limit
        && inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))
--- 386,397 ----
        return false;
      }
  
!   stack_size_limit = inline_summary (to)->estimated_self_stack_size;
  
    stack_size_limit += stack_size_limit * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100;
  
    inlined_stack = (to->global.stack_frame_offset
! 		   + inline_summary (to)->estimated_self_stack_size
  		   + what->global.estimated_stack_size);
    if (inlined_stack  > stack_size_limit
        && inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))
*************** cgraph_decide_inlining (void)
*** 1036,1043 ****
        {
  	struct cgraph_edge *e;
  
! 	initial_insns += node->local.self_insns;
! 	gcc_assert (node->local.self_insns == node->global.insns);
  	for (e = node->callees; e; e = e->next_callee)
  	  if (max_count < e->count)
  	    max_count = e->count;
--- 1044,1051 ----
        {
  	struct cgraph_edge *e;
  
! 	initial_insns += inline_summary (node)->self_insns;
! 	gcc_assert (inline_summary (node)->self_insns == node->global.insns);
  	for (e = node->callees; e; e = e->next_callee)
  	  if (max_count < e->count)
  	    max_count = e->count;
*************** compute_inline_parameters (void)
*** 1517,1535 ****
    struct cgraph_node *node = cgraph_node (current_function_decl);
  
    gcc_assert (!node->global.inlined_to);
!   node->local.estimated_self_stack_size = estimated_stack_frame_size ();
!   node->global.estimated_stack_size = node->local.estimated_self_stack_size;
    node->global.stack_frame_offset = 0;
    node->local.inlinable = tree_inlinable_function_p (current_function_decl);
!   node->local.self_insns = estimate_num_insns (current_function_decl,
! 					       &eni_inlining_weights);
    if (node->local.inlinable && !node->local.disregard_inline_limits)
      node->local.disregard_inline_limits
        = DECL_DISREGARD_INLINE_LIMITS (current_function_decl);
    if (flag_really_no_inline && !node->local.disregard_inline_limits)
      node->local.inlinable = 0;
    /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
!   node->global.insns = node->local.self_insns;
    return 0;
  }
  
--- 1525,1545 ----
    struct cgraph_node *node = cgraph_node (current_function_decl);
  
    gcc_assert (!node->global.inlined_to);
!   inline_summary (node)->estimated_self_stack_size
!     = estimated_stack_frame_size ();
!   node->global.estimated_stack_size
!     = inline_summary (node)->estimated_self_stack_size;
    node->global.stack_frame_offset = 0;
    node->local.inlinable = tree_inlinable_function_p (current_function_decl);
!   inline_summary (node)->self_insns = estimate_num_insns (current_function_decl,
! 					                  &eni_inlining_weights);
    if (node->local.inlinable && !node->local.disregard_inline_limits)
      node->local.disregard_inline_limits
        = DECL_DISREGARD_INLINE_LIMITS (current_function_decl);
    if (flag_really_no_inline && !node->local.disregard_inline_limits)
      node->local.inlinable = 0;
    /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
!   node->global.insns = inline_summary (node)->self_insns;
    return 0;
  }
  
Index: ipa.c
===================================================================
*** ipa.c	(revision 134945)
--- ipa.c	(working copy)
*************** cgraph_remove_unreachable_nodes (bool be
*** 100,106 ****
    struct cgraph_node *first = (struct cgraph_node *) (void *) 1;
    struct cgraph_node *node, *next;
    bool changed = false;
-   int insns = 0;
  
  #ifdef ENABLE_CHECKING
    verify_cgraph ();
--- 100,105 ----
*************** cgraph_remove_unreachable_nodes (bool be
*** 157,170 ****
        next = node->next;
        if (!node->aux)
  	{
- 	  int local_insns;
- 	  tree decl = node->decl;
- 
            node->global.inlined_to = NULL;
- 	  if (DECL_STRUCT_FUNCTION (decl))
- 	    local_insns = node->local.self_insns;
- 	  else
- 	    local_insns = 0;
  	  if (file)
  	    fprintf (file, " %s", cgraph_node_name (node));
  	  if (!node->analyzed || !DECL_EXTERNAL (node->decl)
--- 156,162 ----
*************** cgraph_remove_unreachable_nodes (bool be
*** 197,211 ****
  	      else
  		cgraph_remove_node (node);
  	    }
- 	  if (!DECL_SAVED_TREE (decl))
- 	    insns += local_insns;
  	  changed = true;
  	}
      }
    for (node = cgraph_nodes; node; node = node->next)
      node->aux = NULL;
-   if (file)
-     fprintf (file, "\nReclaimed %i insns", insns);
  #ifdef ENABLE_CHECKING
    verify_cgraph ();
  #endif
--- 189,199 ----


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