[tree-ssa] Updated version of -Winline warnings patch

Jan Hubicka jh@suse.cz
Sat Jan 3 17:16:00 GMT 2004


Hi,
tree-ssa version of the patch.

Honza

Tue Sep  9 18:50:42 CEST 2003  Jan Hubicka  <jh@suse.cz>
	* Makefile.in (cgraph.o, cgraphunit.o): Add intl.h dependency.
	* cgraph.c (create_edge, dump_cgraph): Update to use inline_failed
	* cgraph.h (cgraph_edge): Replace inline_call by inline_failed
	(cgraph_inline_p): Add extra argument reason.
	* cgraphunit.c: Minor formating fixes.
	cgraph_first_inlined_callee): New functions.
	(record_call_1): Record builtins too.
	(cgraph_analyze_function): Update inline_failed messages.
	(cgraph_mark_functions_to_output, cgraph_expand_function, cgraph_inlined_into,
	cgraph_inlined_callees, cgraph_estimate_growth): Update to use inline_failed.
	(cgraph_check_inline_limits): Likewise; Add argument reason.
	(cgraph_set_inline_failed): New static function.
	(cgraph_decide_inlining_of_small_function, cgraph_decide_inlining): Set
	reasons.
	(cgraph_inline_p): Add new argument reason.
	* tree-inline.c (expand_call_inline):  Update warning.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.159
diff -c -3 -p -r1.903.2.159 Makefile.in
*** Makefile.in	28 Dec 2003 00:56:51 -0000	1.903.2.159
--- Makefile.in	2 Jan 2004 23:51:59 -0000
*************** simplify-rtx.o : simplify-rtx.c $(CONFIG
*** 1761,1769 ****
     $(REGS_H) hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
     output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) $(TREE_H) $(TARGET_H)
  cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
!    langhooks.h toplev.h flags.h $(GGC_H)  $(TARGET_H) cgraph.h gt-cgraph.h output.h
  cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
!    langhooks.h tree-inline.h toplev.h flags.h $(GGC_H)  $(TARGET_H) cgraph.h
  coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(RTL_H) $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
     toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) libfuncs.h \
--- 1761,1770 ----
     $(REGS_H) hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
     output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) $(TREE_H) $(TARGET_H)
  cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
!    langhooks.h toplev.h flags.h $(GGC_H)  $(TARGET_H) cgraph.h gt-cgraph.h \
!    output.h intl.h
  cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
!    langhooks.h tree-inline.h toplev.h flags.h $(GGC_H)  $(TARGET_H) cgraph.h intl.h
  coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(RTL_H) $(TREE_H) flags.h output.h $(REGS_H) $(EXPR_H) function.h \
     toplev.h $(GGC_H) $(TARGET_H) langhooks.h $(COVERAGE_H) libfuncs.h \
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.4.4.14
diff -c -3 -p -r1.4.4.14 cgraph.c
*** cgraph.c	15 Dec 2003 23:54:47 -0000	1.4.4.14
--- cgraph.c	2 Jan 2004 23:51:59 -0000
*************** Software Foundation, 59 Temple Place - S
*** 34,40 ****
  #include "cgraph.h"
  #include "varray.h"
  #include "output.h"
! 
  
  /* Hash table used to convert declarations into nodes.  */
  static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
--- 34,40 ----
  #include "cgraph.h"
  #include "varray.h"
  #include "output.h"
! #include "intl.h"
  
  /* Hash table used to convert declarations into nodes.  */
  static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
*************** cgraph_create_edge (struct cgraph_node *
*** 196,202 ****
    if (TREE_CODE (call_expr) != CALL_EXPR)
      abort ();
  
!   edge->inline_call = false;
    edge->aux = NULL;
  
    edge->caller = caller;
--- 196,208 ----
    if (TREE_CODE (call_expr) != CALL_EXPR)
      abort ();
  
!   if (!DECL_SAVED_TREE (callee->decl))
!     edge->inline_failed = N_("function body not available");
!   else if (callee->local.inlinable)
!     edge->inline_failed = N_("function not considered for inlining");
!   else
!     edge->inline_failed = N_("function not inlinable");
! 
    edge->aux = NULL;
  
    edge->caller = caller;
*************** dump_cgraph_node (FILE *f, struct cgraph
*** 455,461 ****
      {
        fprintf (f, "%s/%i ", cgraph_node_name (edge->caller),
  	       edge->caller->uid);
!       if (edge->inline_call)
  	fprintf(f, "(inlined) ");
      }
  
--- 461,467 ----
      {
        fprintf (f, "%s/%i ", cgraph_node_name (edge->caller),
  	       edge->caller->uid);
!       if (!edge->inline_failed)
  	fprintf(f, "(inlined) ");
      }
  
*************** dump_cgraph_node (FILE *f, struct cgraph
*** 464,470 ****
      {
        fprintf (f, "%s/%i ", cgraph_node_name (edge->callee),
  	       edge->callee->uid);
!       if (edge->inline_call)
  	fprintf(f, "(inlined) ");
      }
    fprintf (f, "\n");
--- 470,476 ----
      {
        fprintf (f, "%s/%i ", cgraph_node_name (edge->callee),
  	       edge->callee->uid);
!       if (!edge->inline_failed)
  	fprintf(f, "(inlined) ");
      }
    fprintf (f, "\n");
*************** cgraph_clone_edge (struct cgraph_edge *e
*** 712,718 ****
  {
    struct cgraph_edge *new = cgraph_create_edge (n, e->callee, call_expr);
  
!   new->inline_call = e->inline_call;
    return new;
  }
  
--- 718,724 ----
  {
    struct cgraph_edge *new = cgraph_create_edge (n, e->callee, call_expr);
  
!   new->inline_failed = e->inline_failed;
    return new;
  }
  
Index: cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.1.4.12
diff -c -3 -p -r1.1.4.12 cgraph.h
*** cgraph.h	13 Dec 2003 19:39:47 -0000	1.1.4.12
--- cgraph.h	2 Jan 2004 23:51:59 -0000
*************** struct cgraph_edge GTY((chain_next ("%h.
*** 115,121 ****
    struct cgraph_edge *next_caller;
    struct cgraph_edge *next_callee;
    tree call_expr;
!   bool inline_call;
    PTR GTY ((skip (""))) aux;
  };
  
--- 115,123 ----
    struct cgraph_edge *next_caller;
    struct cgraph_edge *next_callee;
    tree call_expr;
!   /* When NULL, inline this call.  When non-NULL, points to the explanation
!      why function was not inlined.  */
!   const char *inline_failed;
    PTR GTY ((skip (""))) aux;
  };
  
*************** void cgraph_create_edges (struct cgraph_
*** 185,191 ****
  void cgraph_optimize (void);
  void cgraph_mark_needed_node (struct cgraph_node *);
  void cgraph_mark_reachable_node (struct cgraph_node *);
! bool cgraph_inline_p (struct cgraph_edge *);
  bool cgraph_preserve_function_body_p (tree);
  void verify_cgraph (void);
  void verify_cgraph_node (struct cgraph_node *);
--- 187,193 ----
  void cgraph_optimize (void);
  void cgraph_mark_needed_node (struct cgraph_node *);
  void cgraph_mark_reachable_node (struct cgraph_node *);
! bool cgraph_inline_p (struct cgraph_edge *, const char **reason);
  bool cgraph_preserve_function_body_p (tree);
  void verify_cgraph (void);
  void verify_cgraph_node (struct cgraph_node *);
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.1.4.27
diff -c -3 -p -r1.1.4.27 cgraphunit.c
*** cgraphunit.c	2 Jan 2004 18:03:12 -0000	1.1.4.27
--- cgraphunit.c	2 Jan 2004 23:51:59 -0000
*************** Software Foundation, 59 Temple Place - S
*** 38,43 ****
--- 38,44 ----
  #include "params.h"
  #include "fibheap.h"
  #include "c-common.h"
+ #include "intl.h"
  
  #define INSNS_PER_CALL 10
  
*************** verify_cgraph_node (struct cgraph_node *
*** 367,373 ****
        }
    for (e = node->callers; e; e = e->next_caller)
      {
!       if (e->inline_call)
  	{
  	  if (node->global.inlined_to
  	      != (e->caller->global.inlined_to
--- 368,374 ----
        }
    for (e = node->callers; e; e = e->next_caller)
      {
!       if (!e->inline_failed)
  	{
  	  if (node->global.inlined_to
  	      != (e->caller->global.inlined_to
*************** static void
*** 451,456 ****
--- 452,458 ----
  cgraph_analyze_function (struct cgraph_node *node)
  {
    tree decl = node->decl;
+   struct cgraph_edge *e;
  
    current_function_decl = decl;
  
*************** cgraph_analyze_function (struct cgraph_n
*** 464,469 ****
--- 466,474 ----
    if (node->local.inlinable)
      node->local.disregard_inline_limits
        = (*lang_hooks.tree_inlining.disregard_inline_limits) (decl);
+   for (e = node->callers; e; e = e->next_caller)
+     e->inline_failed = (!node->local.inlinable ? N_("function not inlinable")
+ 			: N_("function not considered for inlining"));
    if (flag_really_no_inline && !node->local.disregard_inline_limits)
      node->local.inlinable = 0;
    /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
*************** cgraph_mark_functions_to_output (void)
*** 581,587 ****
  	abort ();
  
        for (e = node->callers; e; e = e->next_caller)
! 	if (!e->inline_call)
  	  break;
  
        /* We need to output all local functions that are used and not
--- 585,591 ----
  	abort ();
  
        for (e = node->callers; e; e = e->next_caller)
! 	if (e->inline_failed)
  	  break;
  
        /* We need to output all local functions that are used and not
*************** cgraph_expand_function (struct cgraph_no
*** 634,639 ****
--- 638,644 ----
  
  /* Fill array order with all nodes with output flag set in the reverse
     topological order.  */
+ 
  static int
  cgraph_postorder (struct cgraph_node **order)
  {
*************** cgraph_remove_unreachable_nodes (void)
*** 727,733 ****
  
        for (e = node->callees; e; e = e->next_callee)
  	if (!e->callee->aux
! 	    && (e->inline_call || !DECL_SAVED_TREE (e->callee->decl)
  		|| !DECL_EXTERNAL (e->callee->decl)))
  	  {
  	    e->callee->aux = first;
--- 732,738 ----
  
        for (e = node->callees; e; e = e->next_callee)
  	if (!e->callee->aux
! 	    && (!e->inline_failed || !DECL_SAVED_TREE (e->callee->decl)
  		|| !DECL_EXTERNAL (e->callee->decl)))
  	  {
  	    e->callee->aux = first;
*************** cgraph_estimate_growth (struct cgraph_no
*** 803,809 ****
    struct cgraph_edge *e;
  
    for (e = node->callers; e; e = e->next_caller)
!     if (!e->inline_call)
        growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
  		 - e->caller->global.insns);
  
--- 808,814 ----
    struct cgraph_edge *e;
  
    for (e = node->callers; e; e = e->next_caller)
!     if (e->inline_failed)
        growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
  		 - e->caller->global.insns);
  
*************** cgraph_clone_inlined_nodes (struct cgrap
*** 853,859 ****
  
    /* Recursivly clone all bodies.  */
    for (e = e->callee->callees; e; e = e->next_callee)
!     if (e->inline_call)
        cgraph_clone_inlined_nodes (e, duplicate);
  }
  
--- 858,864 ----
  
    /* Recursivly clone all bodies.  */
    for (e = e->callee->callees; e; e = e->next_callee)
!     if (!e->inline_failed)
        cgraph_clone_inlined_nodes (e, duplicate);
  }
  
*************** cgraph_mark_inline_edge (struct cgraph_e
*** 865,873 ****
    int old_insns = 0, new_insns = 0;
    struct cgraph_node *to = NULL, *what;
  
!   if (e->inline_call)
      abort ();
!   e->inline_call = true;
  
    if (!e->callee->global.inlined && flag_unit_at_a_time)
      {
--- 870,878 ----
    int old_insns = 0, new_insns = 0;
    struct cgraph_node *to = NULL, *what;
  
!   if (!e->inline_failed)
      abort ();
!   e->inline_failed = NULL;
  
    if (!e->callee->global.inlined && flag_unit_at_a_time)
      {
*************** cgraph_mark_inline_edge (struct cgraph_e
*** 884,890 ****
    what = e->callee;
  
    /* Now update size of caller and all functions caller is inlined into. */
!   for (;e && e->inline_call; e = e->caller->callers)
      {
        old_insns = e->caller->global.insns;
        new_insns = cgraph_estimate_size_after_inlining (1, e->caller,
--- 889,895 ----
    what = e->callee;
  
    /* Now update size of caller and all functions caller is inlined into. */
!   for (;e && !e->inline_failed; e = e->caller->callers)
      {
        old_insns = e->caller->global.insns;
        new_insns = cgraph_estimate_size_after_inlining (1, e->caller,
*************** cgraph_mark_inline (struct cgraph_edge *
*** 915,921 ****
    for (e = what->callers; e; e = next)
      {
        next = e->next_caller;
!       if (e->caller == to && !e->inline_call)
  	{
            cgraph_mark_inline_edge (e);
  	  if (e == edge)
--- 920,926 ----
    for (e = what->callers; e; e = next)
      {
        next = e->next_caller;
!       if (e->caller == to && e->inline_failed)
  	{
            cgraph_mark_inline_edge (e);
  	  if (e == edge)
*************** cgraph_mark_inline (struct cgraph_edge *
*** 932,938 ****
     as it would cause too large growth of function bodies.  */
  
  static bool
! cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what)
  {
    int times = 0;
    struct cgraph_edge *e;
--- 937,944 ----
     as it would cause too large growth of function bodies.  */
  
  static bool
! cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
! 			    const char **reason)
  {
    int times = 0;
    struct cgraph_edge *e;
*************** cgraph_check_inline_limits (struct cgrap
*** 958,964 ****
    newsize = cgraph_estimate_size_after_inlining (times, to, what);
    if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
        && newsize > limit)
!     return false;
    return true;
  }
  
--- 964,974 ----
    newsize = cgraph_estimate_size_after_inlining (times, to, what);
    if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
        && newsize > limit)
!     {
!       if (reason)
!         *reason = N_("--param large-function-growth limit reached");
!       return false;
!     }
    return true;
  }
  
*************** cgraph_default_inline_p (struct cgraph_n
*** 981,992 ****
  
  static bool
  cgraph_recursive_inlining_p (struct cgraph_node *to,
! 			     struct cgraph_node *what)
  {
    if (to->global.inlined_to)
!     return what->decl == to->global.inlined_to->decl;
    else
!     return what->decl == to->decl;
  }
  
  /* Recompute heap nodes for each of callees.  */
--- 991,1010 ----
  
  static bool
  cgraph_recursive_inlining_p (struct cgraph_node *to,
! 			     struct cgraph_node *what,
! 			     const char **reason)
  {
+   bool recursive;
    if (to->global.inlined_to)
!     recursive = what->decl == to->global.inlined_to->decl;
    else
!     recursive = what->decl == to->decl;
!   /* Marking recursive function inlinine has sane semantic and thus we should
!      not warn on it.  */
!   if (recursive && reason)
!     *reason = (what->local.disregard_inline_limits
! 	       ? N_("recursive inlining") : "");
!   return recursive;
  }
  
  /* Recompute heap nodes for each of callees.  */
*************** update_callee_keys (fibheap_t heap, stru
*** 997,1006 ****
    struct cgraph_edge *e;
  
    for (e = node->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));
!     else if (e->inline_call)
        update_callee_keys (heap, heap_node, e->callee);
  }
  
--- 1015,1024 ----
    struct cgraph_edge *e;
  
    for (e = node->callees; e; e = e->next_callee)
!     if (e->inline_failed && heap_node[e->callee->uid])
        fibheap_replace_key (heap, heap_node[e->callee->uid],
  			   cgraph_estimate_growth (e->callee));
!     else if (!e->inline_failed)
        update_callee_keys (heap, heap_node, e->callee);
  }
  
*************** lookup_recursive_calls (struct cgraph_no
*** 1022,1028 ****
  	*last = e;
        }
    for (e = where->callees; e; e = e->next_callee)
!     if (e->inline_call)
        lookup_recursive_calls (node, e->callee, first, last);
  }
  
--- 1040,1046 ----
  	*last = e;
        }
    for (e = where->callees; e; e = e->next_callee)
!     if (!e->inline_failed)
        lookup_recursive_calls (node, e->callee, first, last);
  }
  
*************** cgraph_decide_recursive_inlining (struct
*** 1063,1069 ****
    master_clone = cgraph_clone_node (node);
    master_clone->needed = true;
    for (e = master_clone->callees; e; e = e->next_callee)
!     if (e->inline_call)
        cgraph_clone_inlined_nodes (e, true);
  
    /* Do the inlining and update list of recursive call during process.  */
--- 1081,1087 ----
    master_clone = cgraph_clone_node (node);
    master_clone->needed = true;
    for (e = master_clone->callees; e; e = e->next_callee)
!     if (!e->inline_failed)
        cgraph_clone_inlined_nodes (e, true);
  
    /* Do the inlining and update list of recursive call during process.  */
*************** cgraph_decide_recursive_inlining (struct
*** 1108,1113 ****
--- 1126,1145 ----
    cgraph_remove_node (master_clone);
  }
  
+ /* Set inline_failed for all callers of given function to REASON.  */
+ 
+ static void
+ cgraph_set_inline_failed (struct cgraph_node *node, const char *reason)
+ {
+   struct cgraph_edge *e;
+ 
+   if (cgraph_dump_file)
+     fprintf (cgraph_dump_file, "Inlining failed: %s\n", reason);
+   for (e = node->callers; e; e = e->next_caller)
+     if (e->inline_failed)
+       e->inline_failed = reason;
+ }
+ 
  /* 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_decide_inlining_of_small_function
*** 1129,1153 ****
  
    for (node = cgraph_nodes; node; node = node->next)
      {
-       struct cgraph_edge *e;
- 
        if (!node->local.inlinable || !node->callers
! 	  || !cgraph_default_inline_p (node))
  	continue;
  
!       /* Rule out always_inline functions we dealt with earlier.  */
!       for (e = node->callers; e; e = e->next_caller)
! 	if (e->inline_call)
! 	  break;
!       if (e)
! 	continue;
        heap_node[node->uid] =
  	fibheap_insert (heap, cgraph_estimate_growth (node), node);
      }
  
    if (cgraph_dump_file)
      fprintf (cgraph_dump_file, "\nDeciding on smaller functions:\n");
!   while ((node = fibheap_extract_min (heap)) && overall_insns <= max_insns)
      {
        struct cgraph_edge *e, *next;
        int old_insns = overall_insns;
--- 1161,1183 ----
  
    for (node = cgraph_nodes; node; node = node->next)
      {
        if (!node->local.inlinable || !node->callers
! 	  || node->local.disregard_inline_limits)
  	continue;
  
!       if (!cgraph_default_inline_p (node))
! 	{
! 	  cgraph_set_inline_failed (node,
! 	    N_("--param max-inline-insns-single limit reached"));
! 	  continue;
! 	}
        heap_node[node->uid] =
  	fibheap_insert (heap, cgraph_estimate_growth (node), node);
      }
  
    if (cgraph_dump_file)
      fprintf (cgraph_dump_file, "\nDeciding on smaller functions:\n");
!   while (overall_insns <= max_insns && (node = fibheap_extract_min (heap)))
      {
        struct cgraph_edge *e, *next;
        int old_insns = overall_insns;
*************** cgraph_decide_inlining_of_small_function
*** 1161,1183 ****
  		 cgraph_estimate_growth (node));
        if (!cgraph_default_inline_p (node))
  	{
! 	  if (cgraph_dump_file)
! 	    fprintf (cgraph_dump_file, " Function too large.\n");
  	  continue;
  	}
        for (e = node->callers; e; e = next)
  	{
  	  next = e->next_caller;
! 	  if (!e->inline_call && e->caller->decl != node->decl)
  	    {
  	      struct cgraph_node *where;
  
! 	      if (cgraph_recursive_inlining_p (e->caller, e->callee)
! 		  || !cgraph_check_inline_limits (e->caller, e->callee))
  		{
  		  if (cgraph_dump_file)
! 		    fprintf (cgraph_dump_file, " Not inlining into %s.\n",
! 			     cgraph_node_name (e->caller));
  		  continue;
  		}
  	      next = cgraph_mark_inline (e);
--- 1191,1215 ----
  		 cgraph_estimate_growth (node));
        if (!cgraph_default_inline_p (node))
  	{
! 	  cgraph_set_inline_failed (node,
! 	    N_("--param max-inline-insns-single limit reached after inlining into the callee"));
  	  continue;
  	}
        for (e = node->callers; e; e = next)
  	{
  	  next = e->next_caller;
! 	  if (e->inline_failed)
  	    {
  	      struct cgraph_node *where;
  
! 	      if (cgraph_recursive_inlining_p (e->caller, e->callee,
! 				      	       &e->inline_failed)
! 		  || !cgraph_check_inline_limits (e->caller, e->callee,
! 			  			  &e->inline_failed))
  		{
  		  if (cgraph_dump_file)
! 		    fprintf (cgraph_dump_file, " Not inlining into %s:%s.\n",
! 			     cgraph_node_name (e->caller), e->inline_failed);
  		  continue;
  		}
  	      next = cgraph_mark_inline (e);
*************** cgraph_decide_inlining_of_small_function
*** 1208,1215 ****
  		 " Inlined for a net change of %+i insns.\n",
  		 overall_insns - old_insns);
      }
!   if (cgraph_dump_file && !fibheap_empty (heap))
!     fprintf (cgraph_dump_file, "\nReached the inline-unit-growth limit.\n");
    fibheap_delete (heap);
    free (heap_node);
  }
--- 1240,1248 ----
  		 " Inlined for a net change of %+i insns.\n",
  		 overall_insns - old_insns);
      }
!   while ((node = fibheap_extract_min (heap)) != NULL)
!     if (!node->local.disregard_inline_limits)
!       cgraph_set_inline_failed (node, N_("--param inline-unit-growth limit reached"));
    fibheap_delete (heap);
    free (heap_node);
  }
*************** cgraph_decide_inlining (void)
*** 1264,1272 ****
        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 (order[i], e->callee))
  	    continue;
  	  cgraph_mark_inline (e);
  	  if (cgraph_dump_file)
--- 1297,1306 ----
        for (; e; e = e->next_callee)
  	{
  	  old_insns = overall_insns;
! 	  if (!e->inline_failed || !e->callee->local.disregard_inline_limits)
  	    continue;
! 	  if (cgraph_recursive_inlining_p (order[i], e->callee,
! 				  	   &e->inline_failed))
  	    continue;
  	  cgraph_mark_inline (e);
  	  if (cgraph_dump_file)
*************** cgraph_decide_inlining (void)
*** 1295,1301 ****
  	  node = order[i];
  
  	  if (node->callers && !node->callers->next_caller && !node->needed
! 	      && node->local.inlinable && !node->callers->inline_call
  	      && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
  	    {
  	      bool ok = true;
--- 1329,1335 ----
  	  node = order[i];
  
  	  if (node->callers && !node->callers->next_caller && !node->needed
! 	      && node->local.inlinable && node->callers->inline_failed
  	      && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
  	    {
  	      bool ok = true;
*************** cgraph_decide_inlining (void)
*** 1303,1309 ****
  
  	      /* Verify that we won't duplicate the caller.  */
  	      for (node1 = node->callers->caller;
! 		   node1->callers && node1->callers->inline_call
  		   && ok; node1 = node1->callers->caller)
  		if (node1->callers->next_caller || node1->needed)
  		  ok = false;
--- 1337,1343 ----
  
  	      /* Verify that we won't duplicate the caller.  */
  	      for (node1 = node->callers->caller;
! 		   node1->callers && node1->callers->inline_failed
  		   && ok; node1 = node1->callers->caller)
  		if (node1->callers->next_caller || node1->needed)
  		  ok = false;
*************** cgraph_decide_inlining (void)
*** 1319,1325 ****
  
  		  old_insns = overall_insns;
  
! 		  if (cgraph_check_inline_limits (node->callers->caller, node))
  		    {
  		      cgraph_mark_inline (node->callers);
  		      if (cgraph_dump_file)
--- 1353,1360 ----
  
  		  old_insns = overall_insns;
  
! 		  if (cgraph_check_inline_limits (node->callers->caller, node,
! 					  	  NULL))
  		    {
  		      cgraph_mark_inline (node->callers);
  		      if (cgraph_dump_file)
*************** cgraph_decide_inlining_incrementally (st
*** 1366,1373 ****
    /* 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->inline_call
!         && !cgraph_recursive_inlining_p (node, e->callee)
  	/* ??? It is possible that renaming variable removed the function body
  	   in duplicate_decls. See gcc.c-torture/compile/20011119-2.c  */
  	&& DECL_SAVED_TREE (e->callee->decl))
--- 1401,1408 ----
    /* 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->inline_failed
!         && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
  	/* ??? It is possible that renaming variable removed the function body
  	   in duplicate_decls. See gcc.c-torture/compile/20011119-2.c  */
  	&& DECL_SAVED_TREE (e->callee->decl))
*************** cgraph_decide_inlining_incrementally (st
*** 1377,1398 ****
    if (!flag_really_no_inline)
      for (e = node->callees; e; e = e->next_callee)
        if (e->callee->local.inlinable
! 	  && !e->inline_call
! 	  && !cgraph_recursive_inlining_p (node, e->callee)
! 	  && cgraph_default_inline_p (e->callee)
! 	  && cgraph_check_inline_limits (node, e->callee)
  	  && DECL_SAVED_TREE (e->callee->decl))
! 	cgraph_mark_inline (e);
  }
  
  
  /* Return true when CALLER_DECL should be inlined into CALLEE_DECL.  */
  
  bool
! cgraph_inline_p (struct cgraph_edge *e)
  {
!   return e->inline_call;
  }
  /* Expand all functions that must be output.
  
     Attempt to topologically sort the nodes so function is output when
--- 1412,1441 ----
    if (!flag_really_no_inline)
      for (e = node->callees; e; e = e->next_callee)
        if (e->callee->local.inlinable
! 	  && e->inline_failed
! 	  && !e->callee->local.disregard_inline_limits
! 	  && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
! 	  && cgraph_check_inline_limits (node, e->callee, &e->inline_failed)
  	  && DECL_SAVED_TREE (e->callee->decl))
! 	{
! 	  if (cgraph_default_inline_p (e->callee))
! 	    cgraph_mark_inline (e);
! 	  else
! 	    e->inline_failed
! 	      = N_("--param max-inline-insns-single limit reached");
! 	}
  }
  
  
  /* Return true when CALLER_DECL should be inlined into CALLEE_DECL.  */
  
  bool
! cgraph_inline_p (struct cgraph_edge *e, const char **reason)
  {
!   *reason = e->inline_failed;
!   return !e->inline_failed;
  }
+ 
  /* Expand all functions that must be output.
  
     Attempt to topologically sort the nodes so function is output when
*************** cgraph_expand_all_functions (void)
*** 1441,1447 ****
  /* Mark all local functions.
  
     A local function is one whose calls can occur only in the
!    current compilation unit, so we change its calling convention.
     We simply mark all static functions whose address is not taken
     as local.  */
  
--- 1484,1491 ----
  /* Mark all local functions.
  
     A local function is one whose calls can occur only in the
!    current compilation unit and all it's calls are explicit,
!    so we can change its calling convention.
     We simply mark all static functions whose address is not taken
     as local.  */
  
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.26.2.74
diff -c -3 -p -r1.26.2.74 tree-inline.c
*** tree-inline.c	17 Dec 2003 18:55:41 -0000	1.26.2.74
--- tree-inline.c	2 Jan 2004 23:51:59 -0000
*************** expand_call_inline (tree *tp, int *walk_
*** 1381,1386 ****
--- 1381,1387 ----
    tree return_slot_addr;
    location_t saved_location;
    struct cgraph_edge *edge;
+   const char *reason;
  
    /* See what we've got.  */
    id = (inline_data *) data;
*************** expand_call_inline (tree *tp, int *walk_
*** 1466,1483 ****
        /* FN must have address taken so it can be passed as argument.  */
        if (!dest->needed)
  	abort ();
!       cgraph_create_edge (id->node, dest, t);
        goto egress;
      }
  
    /* Don't try to inline functions that are not well-suited to
       inlining.  */
!   if (!DECL_SAVED_TREE (fn) || !cgraph_inline_p (edge))
      {
!       if (warn_inline && DECL_INLINE (fn) && DECL_DECLARED_INLINE_P (fn)
! 	  && !DECL_IN_SYSTEM_HEADER (fn))
  	{
! 	  warning ("%Jinlining failed in call to '%F'", fn, fn);
  	  warning ("called from here");
  	}
        goto egress;
--- 1467,1486 ----
        /* FN must have address taken so it can be passed as argument.  */
        if (!dest->needed)
  	abort ();
!       cgraph_create_edge (id->node, dest, t)->inline_failed
! 	= N_("originally indirect function call not considered for inlining");
        goto egress;
      }
  
    /* Don't try to inline functions that are not well-suited to
       inlining.  */
!   if (!cgraph_inline_p (edge, &reason))
      {
!       if (warn_inline && DECL_DECLARED_INLINE_P (fn)
! 	  && !DECL_IN_SYSTEM_HEADER (fn)
! 	  && strlen (reason))
  	{
! 	  warning ("%Jinlining failed in call to '%F': %s", fn, fn, reason);
  	  warning ("called from here");
  	}
        goto egress;
*************** optimize_inline_calls (tree fn)
*** 1838,1844 ****
  
        /* Double check that we inlined everything we are supposed to inline.  */
        for (e = id.node->callees; e; e = e->next_callee)
! 	if (e->inline_call)
  	  abort ();
      }
  #endif
--- 1841,1847 ----
  
        /* Double check that we inlined everything we are supposed to inline.  */
        for (e = id.node->callees; e; e = e->next_callee)
! 	if (!e->inline_failed)
  	  abort ();
      }
  #endif
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.100
diff -c -3 -p -r1.1.4.100 tree-optimize.c
*** tree-optimize.c	2 Jan 2004 18:03:12 -0000	1.1.4.100
--- tree-optimize.c	2 Jan 2004 23:51:59 -0000
*************** tree_rest_of_compilation (tree fndecl, b
*** 352,360 ****
  
  	  saved_node = cgraph_clone_node (node);
  	  for (e = saved_node->callees; e; e = e->next_callee)
! 	    if (e->inline_call)
  	      {
! 		e->inline_call = 0;
  		cgraph_mark_inline_edge (e);
  	      }
  	}
--- 352,360 ----
  
  	  saved_node = cgraph_clone_node (node);
  	  for (e = saved_node->callees; e; e = e->next_callee)
! 	    if (!e->inline_failed)
  	      {
! 		e->inline_failed = "";
  		cgraph_mark_inline_edge (e);
  	      }
  	}
*************** tree_rest_of_compilation (tree fndecl, b
*** 365,371 ****
      {
        struct cgraph_edge *e;
        for (e = node->callees; e; e = e->next_callee)
! 	if (e->inline_call || warn_inline)
  	  break;
        if (e)
  	{
--- 365,371 ----
      {
        struct cgraph_edge *e;
        for (e = node->callees; e; e = e->next_callee)
! 	if (!e->inline_failed || warn_inline)
  	  break;
        if (e)
  	{



More information about the Gcc-patches mailing list