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]

Inline functions called once III


Hi,
This is update of the patch to inline functions called once to the current
unit-at-a-time infrastructure.

Regtested and bootstrapped i386 with -O3 (so the code is excersised)

Honza

/* { dg-options "-O2 -finline-functions-called-once" } */
/* { dg-final { scan-assembler-not "big_function_2" } } */
static void
big_function_2(void);
void
big_function_1()
{
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	big_function_2();
}
void
big_function_2()
{
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
	while (t());
}
Tue Feb 18 13:52:22 CET 2003  Jan Hubicka  <jh at suse dot cz>

	* c-decl.c: (finish_function): Update call of tree_inlinable_function_p.
	* cgraph.h: (cgraph_local_info): Add can_inline_once
	(cgraph_global_info): Add inline_once.
	(cgraph_node): Add previous.
	(cgraph_remove_node): New.
	* cgraphunit.c (cgraph_mark_functions_to_inline_once): New static
	function.
	(cgraph_optimize): Call it.
	(cgraph_finalize_function):  Set inlinable flags.
	(cgraph_finalize_compilation_unit):  Actually remove the reclaimed nodes.
	(cgraph_mark_functions_to_output):  Use new inlining heuristics flags.
	(cgraph_expand_function): Likewise.
	* cgraph.c 
	(cgraph_node): Put nodes into doubly linked chain.
	(cgraph_remove_node): New function.
	* flags.h (flag_inline_functions_called_once): Declare.
	* toplev.c (flag_inline_functions_called_once): New global variable.
	(lang_independent-options): Add inline-functions-called-once.
	(parse_options_and_default_flags): Set flag_inline_functions_called_once
	for -O3 and -Os.
	(process_options): Imply flag_unit_at_a_time when needed.
	* tree-inline.c: Include cgraph.h
	(inlinable_functions_p): Add extra argument to bypass limits.
	(expand_call_inline):  Obey cgraph flag.
	* tree-inline.h (tree_inlinable_function_p): Update prototype.
	* doc/invoke.texi (-finline-functions-called-once):  Document.
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.367
diff -c -3 -p -r1.367 c-decl.c
*** gcc/c-decl.c	2 Mar 2003 21:18:09 -0000	1.367
--- gcc/c-decl.c	5 Mar 2003 15:16:56 -0000
*************** finish_function (nested, can_defer_p)
*** 6444,6450 ****
  	     predicates depend on cfun and current_function_decl to
  	     function completely.  */
  	  timevar_push (TV_INTEGRATION);
! 	  uninlinable = ! tree_inlinable_function_p (fndecl);
  	  
  	  if (! uninlinable && can_defer_p
  	      /* Save function tree for inlining.  Should return 0 if the
--- 6444,6450 ----
  	     predicates depend on cfun and current_function_decl to
  	     function completely.  */
  	  timevar_push (TV_INTEGRATION);
! 	  uninlinable = ! tree_inlinable_function_p (fndecl, 0);
  	  
  	  if (! uninlinable && can_defer_p
  	      /* Save function tree for inlining.  Should return 0 if the
Index: gcc/cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.5
diff -c -3 -p -r1.5 cgraph.c
*** gcc/cgraph.c	5 Mar 2003 01:33:25 -0000	1.5
--- gcc/cgraph.c	5 Mar 2003 15:16:56 -0000
*************** bool cgraph_global_info_ready = false;
*** 48,54 ****
  
  static struct cgraph_edge *create_edge PARAMS ((struct cgraph_node *,
  						struct cgraph_node *));
! static void remove_edge PARAMS ((struct cgraph_node *, struct cgraph_node *));
  static hashval_t hash_node PARAMS ((const PTR));
  static int eq_node PARAMS ((const PTR, const PTR));
  
--- 48,54 ----
  
  static struct cgraph_edge *create_edge PARAMS ((struct cgraph_node *,
  						struct cgraph_node *));
! static void cgraph_remove_edge PARAMS ((struct cgraph_node *, struct cgraph_node *));
  static hashval_t hash_node PARAMS ((const PTR));
  static int eq_node PARAMS ((const PTR, const PTR));
  
*************** cgraph_node (decl)
*** 95,100 ****
--- 95,103 ----
    node = xcalloc (sizeof (*node), 1);
    node->decl = decl;
    node->next = cgraph_nodes;
+   if (cgraph_nodes)
+     cgraph_nodes->previous = node;
+   node->previous = NULL;
    cgraph_nodes = node;
    cgraph_n_nodes++;
    *slot = node;
*************** create_edge (caller, callee)
*** 127,133 ****
  /* Remove the edge from CALLER to CALLEE in the cgraph.  */
  
  static void
! remove_edge (caller, callee)
       struct cgraph_node *caller, *callee;
  {
    struct cgraph_edge **edge, **edge2;
--- 130,136 ----
  /* Remove the edge from CALLER to CALLEE in the cgraph.  */
  
  static void
! cgraph_remove_edge (caller, callee)
       struct cgraph_node *caller, *callee;
  {
    struct cgraph_edge **edge, **edge2;
*************** remove_edge (caller, callee)
*** 146,151 ****
--- 149,185 ----
    *edge2 = (*edge2)->next_callee;
  }
  
+ /* Remove the node from cgraph.  */
+ 
+ void
+ cgraph_remove_node (node)
+      struct cgraph_node *node;
+ {
+   while (node->callers)
+     cgraph_remove_edge (node->callers->caller, node);
+   while (node->callees)
+     cgraph_remove_edge (node, node->callees->callee);
+   while (node->nested)
+     cgraph_remove_node (node->nested);
+   if (node->origin)
+     {
+       struct cgraph_node **node2 = &node->origin->nested;
+ 
+       while (*node2 != node)
+ 	node2 = &(*node2)->next_nested;
+       (*node2)->next_nested = node->next_nested;
+     }
+   if (node->previous)
+     node->previous->next = node->next;
+   else
+     cgraph_nodes = node;
+   if (node->next)
+     node->next->previous = node->previous;
+   DECL_SAVED_TREE (node->decl) = NULL;
+   /* Do not free the structure itself so the walk over chain can continue.  */
+ }
+ 
+ 
  /* Record call from CALLER to CALLEE  */
  
  struct cgraph_edge *
*************** void
*** 159,165 ****
  cgraph_remove_call (caller, callee)
       tree caller, callee;
  {
!   remove_edge (cgraph_node (caller), cgraph_node (callee));
  }
  
  /* Return true when CALLER_DECL calls CALLEE_DECL.  */
--- 193,199 ----
  cgraph_remove_call (caller, callee)
       tree caller, callee;
  {
!   cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee));
  }
  
  /* Return true when CALLER_DECL calls CALLEE_DECL.  */
Index: gcc/cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.2
diff -c -3 -p -r1.2 cgraph.h
*** gcc/cgraph.h	5 Mar 2003 01:33:25 -0000	1.2
--- gcc/cgraph.h	5 Mar 2003 15:16:56 -0000
*************** struct cgraph_local_info
*** 30,36 ****
--- 30,40 ----
    /* Set when function function is visiable in current compilation unit only
       and it's address is never taken.  */
    bool local;
+   /* Set when function is small enought to be inlinable many times.  */
    bool inline_many;
+   /* Set when function can be inlined once (false only for functions calling
+      alloca, using varargs and so on).  */
+   bool can_inline_once;
  };
  
  /* Information about the function that needs to be computed globally
*************** struct cgraph_local_info
*** 38,45 ****
  
  struct cgraph_global_info
  {
!   /* Empty for the moment.  */
!   int dummy;
  };
  
  
--- 42,49 ----
  
  struct cgraph_global_info
  {
!   /* Set when the function will be inlined exactly once.  */
!   bool inline_once;
  };
  
  
*************** struct cgraph_node
*** 51,57 ****
    tree decl;
    struct cgraph_edge *callees;
    struct cgraph_edge *callers;
!   struct cgraph_node *next;
    /* For nested functions points to function the node is nested in.  */
    struct cgraph_node *origin;
    /* Points to first nested function, if any.  */
--- 55,61 ----
    tree decl;
    struct cgraph_edge *callees;
    struct cgraph_edge *callers;
!   struct cgraph_node *next, *previous;
    /* For nested functions points to function the node is nested in.  */
    struct cgraph_node *origin;
    /* Points to first nested function, if any.  */
*************** struct cgraph_node *cgraph_node		PARAMS 
*** 95,100 ****
--- 99,105 ----
  bool cgraph_calls_p			PARAMS ((tree, tree));
  struct cgraph_local_info *cgraph_local_info PARAMS ((tree));
  struct cgraph_global_info *cgraph_global_info PARAMS ((tree));
+ void cgraph_remove_node			PARAMS ((struct cgraph_node *));
  
  /* In cgraphunit.c  */
  void cgraph_finalize_function		PARAMS ((tree, tree));
Index: gcc/cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.2
diff -c -3 -p -r1.2 cgraphunit.c
*** gcc/cgraphunit.c	5 Mar 2003 01:33:25 -0000	1.2
--- gcc/cgraphunit.c	5 Mar 2003 15:16:56 -0000
*************** static void cgraph_mark_functions_to_out
*** 40,45 ****
--- 40,46 ----
  static void cgraph_expand_function PARAMS ((struct cgraph_node *));
  static tree record_call_1 PARAMS ((tree *, int *, void *));
  static void cgraph_mark_local_functions PARAMS ((void));
+ static void cgraph_mark_functions_to_inline_once PARAMS ((void));
  
  /* Analyze function once it is parsed.  Set up the local information
     available - create cgraph edges for function calles via BODY.  */
*************** cgraph_finalize_function (decl, body)
*** 53,60 ****
  
    node->decl = decl;
  
    if (flag_inline_trees)
!     node->local.inline_many = tree_inlinable_function_p (decl);
    else
      node->local.inline_many = 0;
  
--- 54,65 ----
  
    node->decl = decl;
  
+   if (flag_inline_functions_called_once)
+     node->local.can_inline_once = tree_inlinable_function_p (decl, 1);
+   else
+     node->local.can_inline_once = 0;
    if (flag_inline_trees)
!     node->local.inline_many = tree_inlinable_function_p (decl, 0);
    else
      node->local.inline_many = 0;
  
*************** cgraph_finalize_compilation_unit ()
*** 200,206 ****
  
        if (!node->reachable && DECL_SAVED_TREE (decl))
  	{
! 	  DECL_SAVED_TREE (decl) = NULL;
  	  announce_function (decl);
  	}
      }
--- 205,211 ----
  
        if (!node->reachable && DECL_SAVED_TREE (decl))
  	{
! 	  cgraph_remove_node (node);
  	  announce_function (decl);
  	}
      }
*************** cgraph_mark_functions_to_output ()
*** 221,227 ****
  
        if (DECL_SAVED_TREE (decl)
  	  && (node->needed
! 	      || (!node->local.inline_many && node->reachable)
  	      || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
  	  && !TREE_ASM_WRITTEN (decl) && !node->origin
  	  && !DECL_EXTERNAL (decl))
--- 226,233 ----
  
        if (DECL_SAVED_TREE (decl)
  	  && (node->needed
! 	      || (!node->local.inline_many && !node->global.inline_once
! 		  && node->reachable)
  	      || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
  	  && !TREE_ASM_WRITTEN (decl) && !node->origin
  	  && !DECL_EXTERNAL (decl))
*************** cgraph_expand_function (node)
*** 242,248 ****
  
    /* Avoid RTL inlining from taking place.  */
    (*lang_hooks.callgraph.expand_function) (decl);
!   if (DECL_UNINLINABLE (decl))
      DECL_SAVED_TREE (decl) = NULL;
    current_function_decl = NULL;
  }
--- 248,260 ----
  
    /* Avoid RTL inlining from taking place.  */
    (*lang_hooks.callgraph.expand_function) (decl);
! 
!   /* When we decided to inline the function once, we never ever should need to
!      output it separately.  */
!   if (node->global.inline_once)
!     abort ();
!   if (!node->local.inline_many
!       || !node->callers)
      DECL_SAVED_TREE (decl) = NULL;
    current_function_decl = NULL;
  }
*************** cgraph_mark_local_functions ()
*** 354,359 ****
--- 366,406 ----
      }
  }
  
+ /*  Decide what function should be inlined because they are invoked once
+     (so inlining won't result in duplication of the code).  */
+ 
+ static void
+ cgraph_mark_functions_to_inline_once ()
+ {
+   struct cgraph_node *node, *node1;
+ 
+   if (!quiet_flag)
+     fprintf (stderr, "\n\nMarking functions to inline once:");
+ 
+   /* Now look for function called only once and mark them to inline.  From this
+      point number of calls to given function won't grow.  */
+   for (node = cgraph_nodes; node; node = node->next)
+     {
+       if (node->callers && !node->callers->next_caller && !node->needed
+ 	  && node->local.can_inline_once)
+ 	{
+ 	  bool ok = true;
+ 
+ 	  /* Verify that we won't duplicate the caller.  */
+ 	  for (node1 = node->callers->caller;
+ 	       node1->local.inline_many && node1->callers && ok;
+ 	       node1 = node1->callers->caller)
+ 	    if (node1->callers->next_caller)
+ 	      ok = false;
+ 	  if (ok)
+ 	    {
+ 	      node->global.inline_once = true;
+ 	      announce_function (node->decl);
+ 	    }
+ 	}
+     }
+ }
+ 
  
  /* Perform simple optimizations based on callgraph.  */
  
*************** cgraph_optimize ()
*** 364,369 ****
--- 411,419 ----
    bool changed = true;
  
    cgraph_mark_local_functions ();
+ 
+   if (flag_inline_functions_called_once)
+     cgraph_mark_functions_to_inline_once ();
  
    cgraph_global_info_ready = true;
    if (!quiet_flag)
Index: gcc/flags.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flags.h,v
retrieving revision 1.101
diff -c -3 -p -r1.101 flags.h
*** gcc/flags.h	28 Feb 2003 23:57:49 -0000	1.101
--- gcc/flags.h	5 Mar 2003 15:16:56 -0000
*************** extern int flag_rerun_loop_opt;
*** 378,383 ****
--- 378,388 ----
  
  extern int flag_inline_functions;
  
+ /* Nonzero means to inline functions that are known to be called only
+    once independently on their size.  */
+ 
+ extern int flag_inline_functions_called_once;
+ 
  /* Nonzero for -fkeep-inline-functions: even if we make a function
     go inline everywhere, keep its definition around for debugging
     purposes.  */
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.730
diff -c -3 -p -r1.730 toplev.c
*** gcc/toplev.c	5 Mar 2003 01:33:25 -0000	1.730
--- gcc/toplev.c	5 Mar 2003 15:16:57 -0000
*************** int flag_rerun_loop_opt;
*** 681,686 ****
--- 681,691 ----
  
  int flag_inline_functions;
  
+ /* Nonzero for -finline-functions-called-once: ok to inline functions
+    that are known to be called just once independently on their size.  */
+ 
+ int flag_inline_functions_called_once;
+ 
  /* Nonzero for -fkeep-inline-functions: even if we make a function
     go inline everywhere, keep its definition around for debugging
     purposes.  */
*************** static const lang_independent_options f_
*** 1057,1062 ****
--- 1062,1069 ----
     N_("Allow function addresses to be held in registers") },
    {"inline-functions", &flag_inline_functions, 1,
     N_("Integrate simple functions into their callers") },
+   {"inline-functions-called-once", &flag_inline_functions_called_once, 1,
+    N_("Integrate functions into their callers when they are known to be called just once") },
    {"keep-inline-functions", &flag_keep_inline_functions, 1,
     N_("Generate code for funcs even if they are fully inlined") },
    {"inline", &flag_no_inline, 0,
*************** parse_options_and_default_flags (argc, a
*** 5019,5024 ****
--- 5026,5037 ----
        flag_rename_registers = 1;
        flag_unswitch_loops = 1;
        flag_unit_at_a_time = 1;
+       flag_inline_functions_called_once = 1;
+     }
+ 
+   if (optimize_size)
+     {
+       flag_inline_functions_called_once = 1;
      }
  
    if (optimize < 2 || optimize_size)
*************** process_options ()
*** 5223,5228 ****
--- 5236,5246 ----
      flag_asynchronous_unwind_tables = 1;
    if (flag_asynchronous_unwind_tables)
      flag_unwind_tables = 1;
+ 
+   /* Unrolling all loops implies that standard loop unrolling must also
+      be done.  */
+   if (flag_inline_functions_called_once)
+     flag_unit_at_a_time = 1;
  
    /* Disable unit-at-a-time mode for frontends not supporting callgraph
       interface.  */
Index: gcc/tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.47
diff -c -3 -p -r1.47 tree-inline.c
*** gcc/tree-inline.c	3 Mar 2003 21:28:21 -0000	1.47
--- gcc/tree-inline.c	5 Mar 2003 15:16:57 -0000
*************** static tree copy_body_r PARAMS ((tree *,
*** 115,121 ****
  static tree copy_body PARAMS ((inline_data *));
  static tree expand_call_inline PARAMS ((tree *, int *, void *));
  static void expand_calls_inline PARAMS ((tree *, inline_data *));
! static int inlinable_function_p PARAMS ((tree, inline_data *));
  static tree remap_decl PARAMS ((tree, inline_data *));
  #ifndef INLINER_FOR_JAVA
  static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
--- 115,121 ----
  static tree copy_body PARAMS ((inline_data *));
  static tree expand_call_inline PARAMS ((tree *, int *, void *));
  static void expand_calls_inline PARAMS ((tree *, inline_data *));
! static int inlinable_function_p PARAMS ((tree, inline_data *, int));
  static tree remap_decl PARAMS ((tree, inline_data *));
  #ifndef INLINER_FOR_JAVA
  static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
*************** declare_return_variable (id, return_slot
*** 872,881 ****
  /* Returns nonzero if a function can be inlined as a tree.  */
  
  int
! tree_inlinable_function_p (fn)
       tree fn;
  {
!   return inlinable_function_p (fn, NULL);
  }
  
  /* If *TP is possibly call to alloca, return nonzero.  */
--- 872,882 ----
  /* Returns nonzero if a function can be inlined as a tree.  */
  
  int
! tree_inlinable_function_p (fn, nolimit)
       tree fn;
+      int nolimit;
  {
!   return inlinable_function_p (fn, NULL, nolimit);
  }
  
  /* If *TP is possibly call to alloca, return nonzero.  */
*************** find_builtin_longjmp_call (exp)
*** 939,947 ****
     can be inlined at all.  */
  
  static int
! inlinable_function_p (fn, id)
       tree fn;
       inline_data *id;
  {
    int inlinable;
    int currfn_insns;
--- 940,949 ----
     can be inlined at all.  */
  
  static int
! inlinable_function_p (fn, id, nolimit)
       tree fn;
       inline_data *id;
+      int nolimit;
  {
    int inlinable;
    int currfn_insns;
*************** inlinable_function_p (fn, id)
*** 978,989 ****
       front-end that must set DECL_INLINE in this case, because
       dwarf2out loses if a function is inlined that doesn't have
       DECL_INLINE set.  */
!   else if (! DECL_INLINE (fn))
      ;
    /* We can't inline functions that are too big.  Only allow a single
       function to be of MAX_INLINE_INSNS_SINGLE size.  Make special
       allowance for extern inline functions, though.  */
!   else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
  	   && currfn_insns > max_inline_insns_single)
      ;
    /* We can't inline functions that call __builtin_longjmp at all.
--- 980,992 ----
       front-end that must set DECL_INLINE in this case, because
       dwarf2out loses if a function is inlined that doesn't have
       DECL_INLINE set.  */
!   else if (! DECL_INLINE (fn) && !nolimit)
      ;
    /* We can't inline functions that are too big.  Only allow a single
       function to be of MAX_INLINE_INSNS_SINGLE size.  Make special
       allowance for extern inline functions, though.  */
!   else if (!nolimit
! 	   && ! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
  	   && currfn_insns > max_inline_insns_single)
      ;
    /* We can't inline functions that call __builtin_longjmp at all.
*************** inlinable_function_p (fn, id)
*** 1014,1020 ****
    /* In case we don't disregard the inlining limits and we basically
       can inline this function, investigate further.  */
    if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
!       && inlinable)
      {
        int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
  		     + currfn_insns;
--- 1017,1023 ----
    /* In case we don't disregard the inlining limits and we basically
       can inline this function, investigate further.  */
    if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
!       && inlinable && !nolimit)
      {
        int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
  		     + currfn_insns;
*************** expand_call_inline (tp, walk_subtrees, d
*** 1160,1166 ****
  
    /* Don't try to inline functions that are not well-suited to
       inlining.  */
!   if (!inlinable_function_p (fn, id))
      return NULL_TREE;
  
    if (! (*lang_hooks.tree_inlining.start_inlining) (fn))
--- 1163,1171 ----
  
    /* Don't try to inline functions that are not well-suited to
       inlining.  */
!   if ((!flag_unit_at_a_time || !DECL_SAVED_TREE (fn)
!        || !cgraph_global_info (fn)->inline_once)
!       && !inlinable_function_p (fn, id, 0))
      return NULL_TREE;
  
    if (! (*lang_hooks.tree_inlining.start_inlining) (fn))
Index: gcc/tree-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.h,v
retrieving revision 1.4
diff -c -3 -p -r1.4 tree-inline.h
*** gcc/tree-inline.h	31 May 2002 22:15:38 -0000	1.4
--- gcc/tree-inline.h	5 Mar 2003 15:16:57 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 25,31 ****
  /* Function prototypes.  */
  
  void optimize_inline_calls PARAMS ((tree));
! int tree_inlinable_function_p PARAMS ((tree));
  tree walk_tree PARAMS ((tree*, walk_tree_fn, void*, void*));
  tree walk_tree_without_duplicates PARAMS ((tree*, walk_tree_fn, void*));
  tree copy_tree_r PARAMS ((tree*, int*, void*));
--- 25,31 ----
  /* Function prototypes.  */
  
  void optimize_inline_calls PARAMS ((tree));
! int tree_inlinable_function_p PARAMS ((tree, int));
  tree walk_tree PARAMS ((tree*, walk_tree_fn, void*, void*));
  tree walk_tree_without_duplicates PARAMS ((tree*, walk_tree_fn, void*));
  tree copy_tree_r PARAMS ((tree*, int*, void*));
Index: gcc/doc/invoke.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.253
diff -c -3 -p -r1.253 invoke.texi
*** gcc/doc/invoke.texi	5 Mar 2003 01:33:26 -0000	1.253
--- gcc/doc/invoke.texi	5 Mar 2003 15:16:59 -0000
*************** in the following sections.
*** 272,279 ****
  -fexpensive-optimizations  -ffast-math  -ffloat-store @gol
  -fforce-addr  -fforce-mem  -ffunction-sections @gol
  -fgcse  -fgcse-lm  -fgcse-sm -floop-optimize -fcrossjumping @gol
! -fif-conversion -fif-conversion2 @gol
! -finline-functions  -finline-limit= at var{n}  -fkeep-inline-functions @gol
  -fkeep-static-consts  -fmerge-constants  -fmerge-all-constants @gol
  -fmove-all-movables  -fnew-ra  -fno-branch-count-reg @gol
  -fno-default-inline  -fno-defer-pop @gol
--- 272,279 ----
  -fexpensive-optimizations  -ffast-math  -ffloat-store @gol
  -fforce-addr  -fforce-mem  -ffunction-sections @gol
  -fgcse  -fgcse-lm  -fgcse-sm -floop-optimize -fcrossjumping @gol
! -fif-conversion -fif-conversion2 -finline-functions @gol
! -finline-functions-called-once  -finline-limit= at var{n}  -fkeep-inline-functions @gol
  -fkeep-static-consts  -fmerge-constants  -fmerge-all-constants @gol
  -fmove-all-movables  -fnew-ra  -fno-branch-count-reg @gol
  -fno-default-inline  -fno-defer-pop @gol
*************** declared @code{static}, then the functio
*** 3628,3633 ****
--- 3628,3643 ----
  assembler code in its own right.
  
  Enabled at level @option{-O3}.
+ 
+ @item -finline-functions-called-once
+ @opindex finline-functions-called-once
+ Integrate all functions that are known to be called once and whose address is
+ not taken, so the out of line copy of function won't be needed anymore.
+ This should result in both smaller and faster programs in most cases.
+ 
+ Enabled at level @option{-O3} and @option{-Os}.  The function implies
+ @option{-funit-at-a-time} and has effect only for language frontends supporting
+ this mode.
  
  @item -finline-limit= at var{n}
  @opindex finline-limit


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