tree-inline.c (inlinable_function_p): Improve heuristics by using a smoother function...
authorKurt Garloff <garloff@suse.de>
Sat, 27 Apr 2002 18:59:40 +0000 (11:59 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 27 Apr 2002 18:59:40 +0000 (11:59 -0700)
        * tree-inline.c (inlinable_function_p): Improve heuristics
        by using a smoother function to cut down allowable inlinable size.
        * param.def: Add parameters max-inline-insns-single,
        max-inline-slope, min-inline-insns that determine the exact
        shape of the above function.
        * param.h: Likewise.

From-SVN: r52832

gcc/ChangeLog
gcc/params.def
gcc/params.h
gcc/tree-inline.c

index 0fd205f5b131168bc1dda954a7db6e6ceabe1125..60324ffa73dfdc4be145611f712752efadfd2b4e 100644 (file)
@@ -1,3 +1,12 @@
+2002-04-27  Kurt Garloff <garloff@suse.de>
+
+       * tree-inline.c (inlinable_function_p): Improve heuristics
+       by using a smoother function to cut down allowable inlinable size.
+       * param.def: Add parameters max-inline-insns-single,
+       max-inline-slope, min-inline-insns that determine the exact
+       shape of the above function.
+       * param.h: Likewise.
+
 2002-04-26  Richard Henderson  <rth@redhat.com>
 
        * c-parse.in (malloced_yyss, malloced_yyvs): New.
@@ -50,7 +59,7 @@
 
 2002-04-26  Richard Henderson  <rth@redhat.com>
 
-        * c-parse.in (yyoverflow): Revert.
+       * c-parse.in (yyoverflow): Revert.
 
 2002-04-26  David Edelsohn  <edelsohn@gnu.org>
            Richard Henderson  <rth@redhat.com>
index a064ca28132e0e655c33f90bdc445dd7549559f2..2b2cfe67c4dc5dcd189cb09c85fc44bfb749633e 100644 (file)
@@ -35,17 +35,71 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
    Be sure to add an entry to invoke.texi summarizing the parameter.  */
 
-/* The maximum number of instructions accepted for inlining a
-   function.  Increasing values mean more agressive inlining.
-   This affects currently only functions explicitly marked as
-   inline (or methods defined within the class definition for C++).
-   The original default value of 10000 was arbitrary and caused
-   significant compile-time performance regressions.  */
+/* The single function inlining limit. This is the maximum size
+   of a function counted in internal gcc instructions (not in
+   real machine instructions) that is eligible for inlining
+   by the tree inliner.
+   The default value is 300.
+   Only functions marked inline (or methods defined in the class
+   definition for C++) are affected by this, unless you set the
+   -finline-functions (included in -O3) compiler option.
+   There are more restrictions to inlining: If inlined functions
+   call other functions, the already inlined instructions are
+   counted and once the recursive inline limit (see 
+   "max-inline-insns" parameter) is exceeded, the acceptable size
+   gets decreased.  */
+DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
+         "max-inline-insns-single",
+         "The maximum number of instructions in a single function eliglible for inlining",
+         300)
+
+/* The repeated inlining limit. After this number of instructions 
+   (in the internal gcc representation, not real machine instructions)
+   got inlined by repeated inlining, gcc starts to decrease the maximum
+   number of inlinable instructions in the tree inliner.
+   This is done by a linear function, see "max-inline-slope" parameter.
+   It is necessary in order to limit the compile-time resources, that 
+   could otherwise become very high.
+   It is recommended to set this value to twice the value of the single
+   function limit (set by the "max-inline-insns-single" parameter) or
+   higher. The default value is 600.
+   Higher values mean that more inlining is done, resulting in
+   better performance of the code, at the expense of higher 
+   compile-time resource (time, memory) requirements and larger
+   binaries.  
+   This parameters also controls the maximum size of functions considered
+   for inlining in the RTL inliner.  */
 DEFPARAM (PARAM_MAX_INLINE_INSNS,
          "max-inline-insns",
-         "The maximum number of instructions in a function that is eligible for inlining",
+         "The maximuem number of instructions by repeated inlining before gcc starts to throttle inlining",
          600)
 
+/* After the repeated inline limit has been exceeded (see
+   "max-inline-insns" parameter), a linear function is used to
+   decrease the size of single functions eligible for inlining.
+   The slope of this linear function is given the negative
+   reciprocal value (-1/x) of this parameter. 
+   The default vlue is 32.
+   This linear function is used until it falls below a minimum
+   value specified by the "min-inline-insns" parameter.  */
+DEFPARAM (PARAM_MAX_INLINE_SLOPE,
+         "max-inline-slope",
+         "The slope of the linear funtion throttling inlining after the recursive inlining limit has been reached is given by the negative reciprocal value of this parameter",
+         32)
+
+/* When gcc has inlined so many instructions (by repeated
+   inlining) that the throttling limits the inlining very much,
+   inlining for very small functions is still desirable to
+   achieve good runtime performance. The size of single functions 
+   (measured in gcc instructions) which will still be eligible for 
+   inlining then is given by this parameter. It defaults to 130.
+   Only much later (after exceeding 128 times the recursive limit)
+   inlining is cut down completely.  */
+DEFPARAM (PARAM_MIN_INLINE_INSNS,
+         "min-inline-insns",
+         "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining",
+         130)
+
 /* The maximum number of instructions to consider when looking for an
    instruction to fill a delay slot.  If more than this arbitrary
    number of instructions is searched, the time savings from filling
index 36800af2ec45a31d3ff2793e8d5029ff0d9dd73a..c4474e418ee4ed089e46282e6eef2bafd43003a1 100644 (file)
@@ -84,8 +84,14 @@ typedef enum compiler_param
   (compiler_params[(int) ENUM].value)
   
 /* Macros for the various parameters.  */
+#define MAX_INLINE_INSNS_SINGLE \
+  PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)
 #define MAX_INLINE_INSNS \
   PARAM_VALUE (PARAM_MAX_INLINE_INSNS)
+#define MAX_INLINE_SLOPE \
+  PARAM_VALUE (PARAM_MAX_INLINE_SLOPE)
+#define MIN_INLINE_INSNS \
+  PARAM_VALUE (PARAM_MIN_INLINE_INSNS)
 #define MAX_DELAY_SLOT_INSN_SEARCH \
   PARAM_VALUE (PARAM_MAX_DELAY_SLOT_INSN_SEARCH)
 #define MAX_DELAY_SLOT_LIVE_SEARCH \
index 759b55e141813c12d9efe61820fa23b708ba737b..1385e8389be3cd10912d67da882eac70e5dda044 100644 (file)
@@ -668,6 +668,7 @@ inlinable_function_p (fn, id)
      inline_data *id;
 {
   int inlinable;
+  int currfn_insns;
 
   /* If we've already decided this function shouldn't be inlined,
      there's no need to check again.  */
@@ -676,6 +677,9 @@ inlinable_function_p (fn, id)
 
   /* Assume it is not inlinable.  */
   inlinable = 0;
+       
+  /* The number of instructions (estimated) of current function. */
+  currfn_insns = DECL_NUM_STMTS (fn) * INSNS_PER_STMT;
 
   /* If we're not inlining things, then nothing is inlinable.  */
   if (! flag_inline_trees)
@@ -689,10 +693,10 @@ inlinable_function_p (fn, id)
   else if (! DECL_INLINE (fn))
     ;
   /* We can't inline functions that are too big.  Only allow a single
-     function to eat up half of our budget.  Make special allowance
-     for extern inline functions, though.  */
+     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)
-          && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 2)
+          && currfn_insns > MAX_INLINE_INSNS_SINGLE)
     ;
   /* All is well.  We can inline this function.  Traditionally, GCC
      has refused to inline functions using alloca, or functions whose
@@ -704,15 +708,31 @@ inlinable_function_p (fn, id)
   /* Squirrel away the result so that we don't have to check again.  */
   DECL_UNINLINABLE (fn) = ! inlinable;
 
-  /* Even if this function is not itself too big to inline, it might
-     be that we've done so much inlining already that we don't want to
-     risk too much inlining any more and thus halve the acceptable
-     size.  */
+  /* 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)
-      && ((DECL_NUM_STMTS (fn) + (id ? id->inlined_stmts : 0)) * INSNS_PER_STMT
-         > MAX_INLINE_INSNS)
-      && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 4)
-    inlinable = 0;
+      && inlinable)
+    { 
+      int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
+                    + currfn_insns;
+      /* In the extreme case that we have exceeded the recursive inlining
+         limit by a huge factor (128), we just say no. Should not happen
+         in real life. */
+      if (sum_insns > MAX_INLINE_INSNS * 128)
+        inlinable = 0;
+      /* If we did not hit the extreme limit, we use a linear function
+         with slope -1/MAX_INLINE_SLOPE to exceedingly decrease the
+         allowable size. We always allow a size of MIN_INLINE_INSNS
+         though. */
+      else if ((sum_insns > MAX_INLINE_INSNS)
+              && (currfn_insns > MIN_INLINE_INSNS))
+        {
+         int max_curr = MAX_INLINE_INSNS_SINGLE
+                       - (sum_insns - MAX_INLINE_INSNS) / MAX_INLINE_SLOPE;
+         if (currfn_insns > max_curr)
+           inlinable = 0;
+       }
+    }
 
   if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
     inlinable = 0;
@@ -968,7 +988,8 @@ expand_call_inline (tp, walk_subtrees, data)
 
   /* Our function now has more statements than it did before.  */
   DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn);
-  id->inlined_stmts += DECL_NUM_STMTS (fn);
+  /* For accounting, subtract one for the saved call/ret. */
+  id->inlined_stmts += DECL_NUM_STMTS (fn) - 1;
 
   /* Recurse into the body of the just inlined function.  */
   expand_calls_inline (inlined_body, id);