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]

[tree-ssa] Cleanups to cgraph inlining heuristics


Hi,
this patch should make (I hope) cgraph inlining heuristics more readable
and easier to maintain.  The idea is that all the bookkeeping can be
hidden in little bit of abstraction.
I hope it will make it easier to make infrastructure more flexible for
non-transitive inlining (like recursive inlining or inline_once idea is)

The patch has passed i686-pc-gnu-linux and x86_64-linux testing.  I plan
to commit it tomorrow.
Honza

2003-11-30  Jan Hubicka  <jh@suse.cz>
	* cgraphunit.c (cgraph_inline_context): New structure.
	(cgrpah_mark_inline, cgraph_check_inline_limits): Use context
	instead of passing all arguments by hand.
	(cgraph_create_inline_context, cgraph_free_inline_context,
	cgraph_inline_context_set_caller, cgraph_inline_context_clear_caller,
	cgraph_inline_context_set_callee, cgrpah_inline_context_clear_callee,
	cgraph_recursive_inlining_p): New static function.
	(cgrpah_decide_inline*):  Reorganize to use context.
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.1.4.14
diff -c -3 -p -r1.1.4.14 cgraphunit.c
*** cgraphunit.c	25 Nov 2003 02:09:34 -0000	1.1.4.14
--- cgraphunit.c	29 Nov 2003 19:14:20 -0000
*************** cgraph_estimate_growth (struct cgraph_no
*** 802,815 ****
    return growth;
  }
  
! /* Update insn sizes after inlining WHAT into TO that is already inlined into
!    all nodes in INLINED array.  */
  
  static void
! cgraph_mark_inline (struct cgraph_node *to, struct cgraph_node *what,
! 		    struct cgraph_node **inlined, int ninlined,
! 		    struct cgraph_node **inlined_callees,
! 		    int ninlined_callees)
  {
    int i;
    int times = 0;
--- 802,863 ----
    return growth;
  }
  
! /* In order to avoid re-computing of function caller is inlined into
!    and functions inilned by callee needed on several places, we keep
!    these in the context.  */
! struct cgraph_inline_context
! {
!   struct cgraph_node *caller, *callee;
!   struct cgraph_node **inlined;
!   int ninlined;
!   struct cgraph_node **inlined_callees;
!   int ninlined_callees;
! };
! 
! /* Initialize cgraph_inline_context.  */
! 
! static struct cgraph_inline_context *
! cgraph_create_inline_context (void)
! {
!   static struct cgraph_inline_context *context;
! #ifdef ENABLE_CHECKING
!   struct cgraph_node *n;
! 
!   for (n = cgraph_nodes; n; n = n->next)
!     if (n->aux || n->output)
!       abort ();
! #endif
! 
!   context = xcalloc (sizeof (struct cgraph_inline_context), 1);
!   context->inlined = xmalloc (cgraph_n_nodes * sizeof (struct cgraph_node *));
!   context->inlined_callees =
!     xmalloc (cgraph_n_nodes * sizeof (struct cgraph_node *));
!   return context;
! }
! 
! /* Free cgraph_inline_context.  */
  
  static void
! cgraph_free_inline_context (struct cgraph_inline_context *context)
! {
! #ifdef ENABLE_CHECKING
!   struct cgraph_node *n;
! 
!   for (n = cgraph_nodes; n; n = n->next)
!     if (n->aux || n->output)
!       abort ();
! #endif
!   if (context->caller || context->callee)
!     abort ();
!   free (context->inlined);
!   free (context->inlined_callees);
!   free (context);
! }
! 
! /* Mark CONTEXT->CALLER inlinned into CONTEXT->CALLEE.  */
! 
! static void
! cgraph_mark_inline (struct cgraph_inline_context *context)
  {
    int i;
    int times = 0;
*************** cgraph_mark_inline (struct cgraph_node *
*** 818,827 ****
    bool called = false;
    int new_insns;
  
!   what->global.inlined = 1;
!   for (e = what->callers; e; e = e->next_caller)
      {
!       if (e->caller == to)
  	{
  	  if (e->inline_call)
  	    abort ();
--- 866,875 ----
    bool called = false;
    int new_insns;
  
!   context->callee->global.inlined = 1;
!   for (e = context->callee->callers; e; e = e->next_caller)
      {
!       if (e->caller == context->caller)
  	{
  	  if (e->inline_call)
  	    abort ();
*************** cgraph_mark_inline (struct cgraph_node *
*** 836,880 ****
      abort ();
    ncalls_inlined += times;
  
!   new_insns = cgraph_estimate_size_after_inlining (times, to, what);
!   if (to->global.will_be_output)
!     overall_insns += new_insns - to->global.insns;
!   to->global.insns = new_insns;
  
!   if (!called && !what->needed && !what->origin
        && flag_unit_at_a_time
!       && !DECL_EXTERNAL (what->decl))
      {
!       if (!what->global.will_be_output)
  	abort ();
        clones--;
        nfunctions_inlined++;
!       what->global.will_be_output = 0;
!       overall_insns -= what->global.insns;
      }
!   what->global.cloned_times += clones;
!   for (i = 0; i < ninlined; i++)
      {
        new_insns =
! 	cgraph_estimate_size_after_inlining (INLINED_TIMES (inlined[i]) *
! 					     times, inlined[i], what);
!       if (inlined[i]->global.will_be_output)
! 	overall_insns += new_insns - inlined[i]->global.insns;
!       inlined[i]->global.insns = new_insns;
      }
!   for (i = 0; i < ninlined_callees; i++)
      {
!       inlined_callees[i]->global.cloned_times +=
! 	INLINED_TIMES (inlined_callees[i]) * clones;
      }
  }
  
! /* Return false when inlining WHAT into TO is not good idea as it would cause
!    too large growth of function bodies.  */
  
  static bool
! cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
! 			    struct cgraph_node **inlined, int ninlined)
  {
    int i;
    int times = 0;
--- 884,929 ----
      abort ();
    ncalls_inlined += times;
  
!   new_insns = cgraph_estimate_size_after_inlining (times, context->caller,
! 						   context->callee);
!   if (context->caller->global.will_be_output)
!     overall_insns += new_insns - context->caller->global.insns;
!   context->caller->global.insns = new_insns;
  
!   if (!called && !context->callee->needed && !context->callee->origin
        && flag_unit_at_a_time
!       && !DECL_EXTERNAL (context->callee->decl))
      {
!       if (!context->callee->global.will_be_output)
  	abort ();
        clones--;
        nfunctions_inlined++;
!       context->callee->global.will_be_output = 0;
!       overall_insns -= context->callee->global.insns;
      }
!   context->callee->global.cloned_times += clones;
!   for (i = 0; i < context->ninlined; i++)
      {
        new_insns =
! 	cgraph_estimate_size_after_inlining (INLINED_TIMES (context->inlined[i]) *
! 					     times, context->inlined[i],
! 					     context->callee);
!       if (context->inlined[i]->global.will_be_output)
! 	overall_insns += new_insns - context->inlined[i]->global.insns;
!       context->inlined[i]->global.insns = new_insns;
      }
!   for (i = 0; i < context->ninlined_callees; i++)
      {
!       context->inlined_callees[i]->global.cloned_times +=
! 	INLINED_TIMES (context->inlined_callees[i]) * clones;
      }
  }
  
! /* Return false when inlining CONTEXT->WHAT into CONTEXT->TO is not good idea
!    as it would cause too large growth of function bodies.  */
  
  static bool
! cgraph_check_inline_limits (struct cgraph_inline_context *context)
  {
    int i;
    int times = 0;
*************** cgraph_check_inline_limits (struct cgrap
*** 882,912 ****
    int newsize;
    int limit;
  
!   for (e = to->callees; e; e = e->next_callee)
!     if (e->callee == what)
        times++;
  
    /* 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;
  
!   newsize = cgraph_estimate_size_after_inlining (times, to, what);
    if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
        && newsize > limit)
      return false;
!   for (i = 0; i < ninlined; i++)
      {
        newsize =
! 	cgraph_estimate_size_after_inlining (INLINED_TIMES (inlined[i]) *
! 					     times, inlined[i], what);
        if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
  	  && newsize >
! 	  inlined[i]->local.self_insns *
  	  (100 + PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH)) / 100)
  	return false;
      }
--- 931,961 ----
    int newsize;
    int limit;
  
!   for (e = context->caller->callees; e; e = e->next_callee)
!     if (e->callee == context->callee)
        times++;
  
    /* When inlining large function body called once into small function,
       take the inlined function as base for limiting the growth.  */
!   if (context->caller->local.self_insns > context->callee->local.self_insns)
!     limit = context->caller->local.self_insns;
    else
!     limit = context->callee->local.self_insns;
  
    limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
  
!   newsize = cgraph_estimate_size_after_inlining (times, context->caller, context->callee);
    if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
        && newsize > limit)
      return false;
!   for (i = 0; i < context->ninlined; i++)
      {
        newsize =
! 	cgraph_estimate_size_after_inlining (INLINED_TIMES (context->inlined[i]) *
! 					     times, context->inlined[i], context->callee);
        if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
  	  && newsize >
! 	  context->inlined[i]->local.self_insns *
  	  (100 + PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH)) / 100)
  	return false;
      }
*************** cgraph_default_inline_p (struct cgraph_n
*** 926,931 ****
--- 975,1056 ----
      return n->global.insns < MAX_INLINE_INSNS_AUTO;
  }
  
+ /* Set current caller.  */
+ 
+ static void
+ cgraph_inline_context_set_caller (struct cgraph_inline_context *context,
+ 				  struct cgraph_node *node)
+ {
+   if (context->caller)
+     abort ();
+   context->caller = node;
+   context->ninlined = cgraph_inlined_into (context->caller, context->inlined);
+ }
+ 
+ /* Clear current caller.  */
+ 
+ static void
+ cgraph_inline_context_clear_caller (struct cgraph_inline_context *context)
+ {
+   int i;
+ 
+   if (!context->caller)
+     abort ();
+   context->caller->aux = 0;
+   context->caller->output = 0;
+   context->caller = NULL;
+   for (i = 0; i < context->ninlined; i++)
+     {
+       context->inlined[i]->output = 0;
+       context->inlined[i]->aux = 0;
+     }
+   context->ninlined = 0;
+ }
+ 
+ /* Set current callee.  */
+ 
+ static void
+ cgraph_inline_context_set_callee (struct cgraph_inline_context *context,
+ 				  struct cgraph_node *node)
+ {
+   if (context->callee)
+     abort ();
+   context->callee = node;
+   context->ninlined_callees =
+     cgraph_inlined_callees (context->callee, context->inlined_callees);
+ }
+ 
+ /* Clear current callee.  */
+ 
+ static void
+ cgraph_inline_context_clear_callee (struct cgraph_inline_context *context)
+ {
+   int i;
+ 
+   if (!context->callee)
+     abort ();
+   context->callee->aux = 0;
+   context->callee->output = 0;
+   context->callee = NULL;
+   for (i = 0; i < context->ninlined_callees; i++)
+     {
+       context->inlined_callees[i]->output = 0;
+       context->inlined_callees[i]->aux = 0;
+     }
+   context->ninlined_callees = 0;
+ }
+ 
+ /* Return true when inlining NODE would create recursive inlining.  */
+ 
+ static bool
+ cgraph_recursive_inlining_p (struct cgraph_inline_context *context,
+ 			  struct cgraph_node *node)
+ {
+   if (!context->caller)
+     abort ();
+   return node->output || context->caller == node;
+ }
+ 
  /* We use greedy algorithm for inlining of small functions:
     All inline candidates are put into prioritized heap based on estimated
     growth of the overall number of instructions and then update the estimates.
*************** cgraph_default_inline_p (struct cgraph_n
*** 934,948 ****
     to be passed to cgraph_inlined_into and cgraph_inlined_callees.  */
  
  static void
! cgraph_decide_inlining_of_small_functions (struct cgraph_node **inlined,
! 					   struct cgraph_node **inlined_callees)
  {
    int i;
    struct cgraph_node *node;
    fibheap_t heap = fibheap_new ();
    struct fibnode **heap_node =
      xcalloc (cgraph_max_uid, sizeof (struct fibnode *));
-   int ninlined, ninlined_callees;
    int max_insns = ((HOST_WIDEST_INT) initial_insns
  		   * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
  
--- 1059,1071 ----
     to be passed to cgraph_inlined_into and cgraph_inlined_callees.  */
  
  static void
! cgraph_decide_inlining_of_small_functions (struct cgraph_inline_context *context)
  {
    int i;
    struct cgraph_node *node;
    fibheap_t heap = fibheap_new ();
    struct fibnode **heap_node =
      xcalloc (cgraph_max_uid, sizeof (struct fibnode *));
    int max_insns = ((HOST_WIDEST_INT) initial_insns
  		   * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
  
*************** cgraph_decide_inlining_of_small_function
*** 986,1028 ****
  	    fprintf (cgraph_dump_file, " Function too large.\n");
  	  continue;
  	}
!       ninlined_callees = cgraph_inlined_callees (node, inlined_callees);
        for (e = node->callers; e; e = e->next_caller)
  	if (!e->inline_call && e->caller != node)
  	  {
! 	    ninlined = cgraph_inlined_into (e->caller, inlined);
! 	    if (e->callee->output
! 		|| !cgraph_check_inline_limits (e->caller, node, inlined,
! 						ninlined))
  	      {
! 		for (i = 0; i < ninlined; i++)
! 		  inlined[i]->output = 0, node->aux = 0;
  		if (cgraph_dump_file)
  		  fprintf (cgraph_dump_file, " Not inlining into %s.\n",
  			   cgraph_node_name (e->caller));
  		continue;
  	      }
! 	    cgraph_mark_inline (e->caller, node, inlined, ninlined,
! 				inlined_callees, ninlined_callees);
  	    if (heap_node[e->caller->uid])
  	      fibheap_replace_key (heap, heap_node[e->caller->uid],
  				   cgraph_estimate_growth (e->caller));
  
  	    /* Size of the functions we updated into has changed, so update
  	       the keys.  */
! 	    for (i = 0; i < ninlined; i++)
  	      {
! 		inlined[i]->output = 0, node->aux = 0;
! 		if (heap_node[inlined[i]->uid])
! 		  fibheap_replace_key (heap, heap_node[inlined[i]->uid],
! 				       cgraph_estimate_growth (inlined[i]));
  	      }
! 	if (cgraph_dump_file)
! 	  fprintf (cgraph_dump_file, 
! 		   " Inlined into %s which now has %i insns.\n",
! 		   cgraph_node_name (e->caller),
! 		   e->caller->global.insns);
! 
  	  }
  
        /* Similarly all functions called by the function we just inlined
--- 1109,1147 ----
  	    fprintf (cgraph_dump_file, " Function too large.\n");
  	  continue;
  	}
!       cgraph_inline_context_set_callee (context, node);
        for (e = node->callers; e; e = e->next_caller)
  	if (!e->inline_call && e->caller != node)
  	  {
! 	    cgraph_inline_context_set_caller (context, e->caller);
! 	    if (cgraph_recursive_inlining_p (context, e->callee)
! 		|| !cgraph_check_inline_limits (context))
  	      {
! 	        cgraph_inline_context_clear_caller (context);
  		if (cgraph_dump_file)
  		  fprintf (cgraph_dump_file, " Not inlining into %s.\n",
  			   cgraph_node_name (e->caller));
  		continue;
  	      }
! 	    cgraph_mark_inline (context);
  	    if (heap_node[e->caller->uid])
  	      fibheap_replace_key (heap, heap_node[e->caller->uid],
  				   cgraph_estimate_growth (e->caller));
  
  	    /* Size of the functions we updated into has changed, so update
  	       the keys.  */
! 	    for (i = 0; i < context->ninlined; i++)
  	      {
! 		if (heap_node[context->inlined[i]->uid])
! 		  fibheap_replace_key (heap, heap_node[context->inlined[i]->uid],
! 				       cgraph_estimate_growth (context->inlined[i]));
  	      }
! 	    cgraph_inline_context_clear_caller (context);
! 	    if (cgraph_dump_file)
! 	      fprintf (cgraph_dump_file, 
! 		       " Inlined into %s which now has %i insns.\n",
! 		       cgraph_node_name (e->caller),
! 		       e->caller->global.insns);
  	  }
  
        /* Similarly all functions called by the function we just inlined
*************** cgraph_decide_inlining_of_small_function
*** 1033,1049 ****
  	  fibheap_replace_key (heap, heap_node[e->callee->uid],
  			       cgraph_estimate_growth (e->callee));
  
!       for (i = 0; i < ninlined_callees; i++)
  	{
  	  struct cgraph_edge *e;
  
! 	  for (e = inlined_callees[i]->callees; e; e = e->next_callee)
  	    if (!e->inline_call && heap_node[e->callee->uid])
  	      fibheap_replace_key (heap, heap_node[e->callee->uid],
  				   cgraph_estimate_growth (e->callee));
  
- 	  inlined_callees[i]->output = 0, node->aux = 0;
  	}
        if (cgraph_dump_file)
  	fprintf (cgraph_dump_file, 
  		 " Inlined %i times for a net change of %+i insns.\n",
--- 1152,1168 ----
  	  fibheap_replace_key (heap, heap_node[e->callee->uid],
  			       cgraph_estimate_growth (e->callee));
  
!       for (i = 0; i < context->ninlined_callees; i++)
  	{
  	  struct cgraph_edge *e;
  
! 	  for (e = context->inlined_callees[i]->callees; e; e = e->next_callee)
  	    if (!e->inline_call && heap_node[e->callee->uid])
  	      fibheap_replace_key (heap, heap_node[e->callee->uid],
  				   cgraph_estimate_growth (e->callee));
  
  	}
+       cgraph_inline_context_clear_callee (context);
        if (cgraph_dump_file)
  	fprintf (cgraph_dump_file, 
  		 " Inlined %i times for a net change of %+i insns.\n",
*************** cgraph_decide_inlining (void)
*** 1063,1078 ****
  {
    struct cgraph_node *node;
    int nnodes;
    struct cgraph_node **order =
      xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
-   struct cgraph_node **inlined =
-     xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
-   struct cgraph_node **inlined_callees =
-     xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
-   int ninlined;
-   int ninlined_callees;
    int old_insns = 0;
!   int i, y;
  
    for (node = cgraph_nodes; node; node = node->next)
      initial_insns += node->local.self_insns;
--- 1182,1192 ----
  {
    struct cgraph_node *node;
    int nnodes;
+   struct cgraph_inline_context *context = cgraph_create_inline_context ();
    struct cgraph_node **order =
      xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
    int old_insns = 0;
!   int i;
  
    for (node = cgraph_nodes; node; node = node->next)
      initial_insns += node->local.self_insns;
*************** cgraph_decide_inlining (void)
*** 1108,1127 ****
  	fprintf (cgraph_dump_file,
  		 "\nConsidering %s %i insns (always inline)\n",
  		 cgraph_node_name (e->callee), e->callee->global.insns);
!       ninlined = cgraph_inlined_into (order[i], inlined);
        for (; e; e = e->next_callee)
  	{
  	  old_insns = overall_insns;
  	  if (e->inline_call || !e->callee->local.disregard_inline_limits)
  	    continue;
! 	  if (e->callee->output || e->callee == node)
  	    continue;
! 	  ninlined_callees =
! 	    cgraph_inlined_callees (e->callee, inlined_callees);
! 	  cgraph_mark_inline (node, e->callee, inlined, ninlined,
! 			      inlined_callees, ninlined_callees);
! 	  for (y = 0; y < ninlined_callees; y++)
! 	    inlined_callees[y]->output = 0, node->aux = 0;
  	  if (cgraph_dump_file)
  	    fprintf (cgraph_dump_file, 
  		     " Inlined into %s which now has %i insns.\n",
--- 1222,1238 ----
  	fprintf (cgraph_dump_file,
  		 "\nConsidering %s %i insns (always inline)\n",
  		 cgraph_node_name (e->callee), e->callee->global.insns);
!       cgraph_inline_context_set_caller (context, order[i]);
        for (; e; e = e->next_callee)
  	{
  	  old_insns = overall_insns;
  	  if (e->inline_call || !e->callee->local.disregard_inline_limits)
  	    continue;
! 	  if (cgraph_recursive_inlining_p (context, e->callee))
  	    continue;
! 	  cgraph_inline_context_set_callee (context, e->callee);
! 	  cgraph_mark_inline (context);
! 	  cgraph_inline_context_clear_callee (context);
  	  if (cgraph_dump_file)
  	    fprintf (cgraph_dump_file, 
  		     " Inlined into %s which now has %i insns.\n",
*************** cgraph_decide_inlining (void)
*** 1132,1142 ****
  	  fprintf (cgraph_dump_file, 
  		   " Inlined %i times for a net change of %+i insns.\n",
  		   node->global.cloned_times, overall_insns - old_insns);
!       for (y = 0; y < ninlined; y++)
! 	inlined[y]->output = 0, node->aux = 0;
      }
  
!   cgraph_decide_inlining_of_small_functions (inlined, inlined_callees);
  
    if (cgraph_dump_file)
      fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
--- 1243,1252 ----
  	  fprintf (cgraph_dump_file, 
  		   " Inlined %i times for a net change of %+i insns.\n",
  		   node->global.cloned_times, overall_insns - old_insns);
!       cgraph_inline_context_clear_caller (context);
      }
  
!   cgraph_decide_inlining_of_small_functions (context);
  
    if (cgraph_dump_file)
      fprintf (cgraph_dump_file, "\nDeciding on functions called once:\n");
*************** cgraph_decide_inlining (void)
*** 1169,1186 ****
  			 cgraph_node_name (node), node->global.insns,
  			 cgraph_node_name (node->callers->caller),
  			 node->callers->caller->global.insns);
! 	      ninlined = cgraph_inlined_into (node->callers->caller, inlined);
  	      old_insns = overall_insns;
! 	      if (cgraph_check_inline_limits
! 		  (node->callers->caller, node, inlined, ninlined))
  		{
! 		  ninlined_callees =
! 		    cgraph_inlined_callees (node, inlined_callees);
! 		  cgraph_mark_inline (node->callers->caller, node, inlined,
! 				      ninlined, inlined_callees,
! 				      ninlined_callees);
! 		  for (y = 0; y < ninlined_callees; y++)
! 		    inlined_callees[y]->output = 0, node->aux = 0;
  		  if (cgraph_dump_file)
  		    fprintf (cgraph_dump_file,
  			     " Inlined into %s which now has %i insns"
--- 1279,1293 ----
  			 cgraph_node_name (node), node->global.insns,
  			 cgraph_node_name (node->callers->caller),
  			 node->callers->caller->global.insns);
! 
  	      old_insns = overall_insns;
! 
! 	      cgraph_inline_context_set_caller (context, node->callers->caller);
! 	      cgraph_inline_context_set_callee (context, node);
! 
! 	      if (cgraph_check_inline_limits (context))
  		{
! 		  cgraph_mark_inline (context);
  		  if (cgraph_dump_file)
  		    fprintf (cgraph_dump_file,
  			     " Inlined into %s which now has %i insns"
*************** cgraph_decide_inlining (void)
*** 1195,1202 ****
  		    fprintf (cgraph_dump_file,
  	                     " Inline limit reached, not inlined.\n");
  	        }
! 	      for (y = 0; y < ninlined; y++)
! 		inlined[y]->output = 0, node->aux = 0;
  	    }
  	}
      }
--- 1302,1309 ----
  		    fprintf (cgraph_dump_file,
  	                     " Inline limit reached, not inlined.\n");
  	        }
! 	      cgraph_inline_context_clear_callee (context);
! 	      cgraph_inline_context_clear_caller (context);
  	    }
  	}
      }
*************** cgraph_decide_inlining (void)
*** 1208,1215 ****
  	     ncalls_inlined, nfunctions_inlined, initial_insns,
  	     overall_insns);
    free (order);
!   free (inlined);
!   free (inlined_callees);
  }
  
  /* Decide on the inlining.  We do so in the topological order to avoid
--- 1315,1321 ----
  	     ncalls_inlined, nfunctions_inlined, initial_insns,
  	     overall_insns);
    free (order);
!   cgraph_free_inline_context (context);
  }
  
  /* Decide on the inlining.  We do so in the topological order to avoid
*************** static void
*** 1219,1267 ****
  cgraph_decide_inlining_incrementally (struct cgraph_node *node)
  {
    struct cgraph_edge *e;
!   struct cgraph_node **inlined =
!     xmalloc (sizeof (struct cgraph_node *) * cgraph_n_nodes);
!   struct cgraph_node **inlined_callees =
!     xmalloc (sizeof (struct cgraph_node *) * cgraph_n_nodes);
!   int ninlined;
!   int ninlined_callees;
!   int y;
  
!   ninlined = cgraph_inlined_into (node, inlined);
  
    /* First of all look for always inline functions.  */
    for (e = node->callees; e; e = e->next_callee)
!     if (e->callee->local.disregard_inline_limits && !e->callee->output
! 	&& e->callee != node && !e->inline_call)
        {
! 	ninlined_callees = cgraph_inlined_callees (e->callee, inlined_callees);
! 	cgraph_mark_inline (node, e->callee, inlined, ninlined,
! 			    inlined_callees, ninlined_callees);
! 	for (y = 0; y < ninlined_callees; y++)
! 	  inlined_callees[y]->output = 0, node->aux = 0;
        }
  
    /* Now do the automatic inlining.  */
    for (e = node->callees; e; e = e->next_callee)
!     if (e->callee->local.inlinable && !e->callee->output
! 	&& e->callee != node && !e->inline_call
!         && cgraph_default_inline_p (e->callee)
! 	&& cgraph_check_inline_limits (node, e->callee, inlined,
! 				       ninlined))
        {
! 	ninlined_callees = cgraph_inlined_callees (e->callee, inlined_callees);
! 	cgraph_mark_inline (node, e->callee, inlined, ninlined,
! 			    inlined_callees, ninlined_callees);
! 	for (y = 0; y < ninlined_callees; y++)
! 	  inlined_callees[y]->output = 0, node->aux = 0;
        }
  
!   /* Clear the flags set by cgraph_inlined_into.  */
!   for (y = 0; y < ninlined; y++)
!     inlined[y]->output = 0, node->aux = 0;
! 
!   free (inlined);
!   free (inlined_callees);
  }
  
  
--- 1325,1360 ----
  cgraph_decide_inlining_incrementally (struct cgraph_node *node)
  {
    struct cgraph_edge *e;
!   struct cgraph_inline_context *context = cgraph_create_inline_context ();
  
!   cgraph_inline_context_set_caller (context, node);
  
    /* First of all look for always inline functions.  */
    for (e = node->callees; e; e = e->next_callee)
!     if (e->callee->local.disregard_inline_limits
!         && !cgraph_recursive_inlining_p (context, e->callee)
! 	&& !e->inline_call)
        {
!         cgraph_inline_context_set_callee (context, e->callee);
! 	cgraph_mark_inline (context);
!         cgraph_inline_context_clear_callee (context);
        }
  
    /* Now do the automatic inlining.  */
    for (e = node->callees; e; e = e->next_callee)
!     if (e->callee->local.inlinable
! 	&& !e->inline_call
!         && !cgraph_recursive_inlining_p (context, e->callee)
!         && cgraph_default_inline_p (e->callee))
        {
!         cgraph_inline_context_set_callee (context, e->callee);
! 	if (cgraph_check_inline_limits (context))
! 	  cgraph_mark_inline (context);
!         cgraph_inline_context_clear_callee (context);
        }
  
!   cgraph_inline_context_clear_caller (context);
!   cgraph_free_inline_context (context);
  }
  
  


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