toplev.c (rest_of_compilation): Fix webizer pass ordering.
authorJan Hubicka <jh@suse.cz>
Mon, 20 Oct 2003 21:46:55 +0000 (23:46 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 20 Oct 2003 21:46:55 +0000 (21:46 +0000)
* toplev.c (rest_of_compilation): Fix webizer pass ordering.

* cgraphunit.c (decide_is_function_needed):  Fix test dealing
with functions implicitly made inline.

* cgraphunit.c (cgraph_decide_inlining_incrementally):  New function.
(cgraph_finalize_function): Use it.
(cgraph_mark_inline): Allow incrmental decisions
* invoke.texi (max-inline-slope, min-inline-insns): Kill.
* params.def (PARAM_MAX_INLINE_SLOPE, PARAM_MIN_INLINE_INSNS): Kill.
* tree-inline.c (limits_allow_inlining): Kill.
(expand_call_inline): Always use unit-at-a-time path.

* decl.c (start_cleanup_fn):  Set DECL_DECLARED_INLINE_P to deffer
the expansion.

* testsuite/g++.dg/opt/inline4.C: Do not use min-inline-insns
parameter.
* testsuite/gcc.dg/inline-2.c: Likewise.

From-SVN: r72721

15 files changed:
gcc/ChangeLog
gcc/cgraphunit.c
gcc/config/i386/i386.md
gcc/coverage.h
gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/doc/invoke.texi
gcc/flags.h
gcc/opts.c
gcc/params.def
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/inline4.C
gcc/testsuite/gcc.dg/inline-2.c
gcc/toplev.c
gcc/tree-inline.c

index 1e0075cd68028a29bdf016996d290626c0af5782..2d59559816af17d1f598feedb7a5656554d4ff6b 100644 (file)
@@ -1,3 +1,18 @@
+2003-10-20  Jan Hubicka  <jh@suse.cz>
+
+       * toplev.c (rest_of_compilation): Fix webizer pass ordering.
+
+       * cgraphunit.c (decide_is_function_needed):  Fix test dealing
+       with functions implicitly made inline.
+
+       * cgraphunit.c (cgraph_decide_inlining_incrementally):  New function.
+       (cgraph_finalize_function): Use it.
+       (cgraph_mark_inline): Allow incrmental decisions
+       * invoke.texi (max-inline-slope, min-inline-insns): Kill.
+       * params.def (PARAM_MAX_INLINE_SLOPE, PARAM_MIN_INLINE_INSNS): Kill.
+       * tree-inline.c (limits_allow_inlining): Kill.
+       (expand_call_inline): Always use unit-at-a-time path.
+
 2003-10-20  Zack Weinberg  <zack@codesourcery.com>
 
        * fixinc/inclhack.def (hpux11_snprintf): New edit.
index 7b85e77c226d09eb35c352467193af4a8595f725..c20367d1d00aba3139a959586f1697b7874c184f 100644 (file)
@@ -49,6 +49,7 @@ static void cgraph_mark_local_functions (void);
 static void cgraph_optimize_function (struct cgraph_node *);
 static bool cgraph_default_inline_p (struct cgraph_node *n);
 static void cgraph_analyze_function (struct cgraph_node *node);
+static void cgraph_decide_inlining_incrementally (struct cgraph_node *);
 
 /* Statistics we collect about inlining algorithm.  */
 static int ncalls_inlined;
@@ -114,7 +115,7 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
          /* When declared inline, defer even the uninlinable functions.
             This allows them to be eliminated when unused.  */
          && !DECL_DECLARED_INLINE_P (decl) 
-         && (node->local.inlinable || !cgraph_default_inline_p (node))))
+         && (!node->local.inlinable || !cgraph_default_inline_p (node))))
     return true;
 
   return false;
@@ -206,7 +207,10 @@ cgraph_finalize_function (tree decl, bool nested)
   /* If not unit at a time, then we need to create the call graph
      now, so that called functions can be queued and emitted now.  */
   if (!flag_unit_at_a_time)
-    cgraph_analyze_function (node);
+    {
+      cgraph_analyze_function (node);
+      cgraph_decide_inlining_incrementally (node);
+    }
 
   if (decide_is_function_needed (node, decl))
     cgraph_mark_needed_node (node);
@@ -852,6 +856,7 @@ cgraph_mark_inline (struct cgraph_node *to, struct cgraph_node *what,
   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)
@@ -1221,6 +1226,59 @@ cgraph_decide_inlining (void)
   free (inlined_callees);
 }
 
+/* Decide on the inlining.  We do so in the topological order to avoid
+   expenses on updating datastructures.  */
+
+static void
+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);
+}
+
+
 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL.  */
 
 bool
index 863dce5a4db3b7ee1bf50f20468521f9ea7af3f3..835480d3a47c98193a0dfbd858cba3306369e2f1 100644 (file)
                   (unspec:SF [(match_dup 2)
                               (match_operand:SF 1 "register_operand" "")]
                    UNSPEC_FPATAN))
-             (clobber (match_dup 1))])]
+             (clobber (match_scratch:SF 3 ""))])]
   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
    && flag_unsafe_math_optimizations"
 {
index 5ae27f805f278cff5ad0bcbeee37ac76db68e36b..9756bbaafa8fb99f7bfca0c4cdae9352792d1f7e 100644 (file)
@@ -25,6 +25,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 extern void coverage_init (const char *);
 extern void coverage_finish (void);
+extern void coverage_read_counts_file (void);
 
 /* Complete the coverage information for the current function. Once
    per function.  */
index 1acee5ff41530226517ae879264c069254bf8416..c2cb189b8b240324a52fbda5af57921f6816b08d 100644 (file)
@@ -1,3 +1,8 @@
+2003-10-20  Jan Hubicka  <jh@suse.cz>
+
+       * decl.c (start_cleanup_fn):  Set DECL_DECLARED_INLINE_P to deffer
+       the expansion.
+
 2003-10-20  Mark Mitchell  <mark@codesourcery.com>
 
        * Make-lang.in (c++.install-info): Remove.
index 8ca69d139895cfa3082dc90447fc9e132e27d240..0f1170c842e474a7c1bc6268eea8eba4b929794c 100644 (file)
@@ -5073,6 +5073,8 @@ start_cleanup_fn (void)
      it is only called via a function pointer, but we avoid unnecessary
      emissions this way.  */
   DECL_INLINE (fndecl) = 1;
+  DECL_DECLARED_INLINE_P (fndecl) = 1;
+  DECL_INTERFACE_KNOWN (fndecl) = 1;
   /* Build the parameter.  */
   if (flag_use_cxa_atexit)
     {
index 4dbe1ee1c61ce77305e3c2743940064071ccf33a..52bdd6d13621af98d3155f0c09252940254b02a6 100644 (file)
@@ -4784,22 +4784,6 @@ larger binaries.  Very high values are not advisable, as too large
 binaries may adversely affect runtime performance.
 The default value is 200.
 
-@item max-inline-slope
-After exceeding the maximum number of inlined instructions by repeated
-inlining, a linear function is used to decrease the allowable size
-for single functions.  The slope of that function is the negative
-reciprocal of the number specified here.
-This parameter is ignored when @option{-funit-at-a-time} is used.
-The default value is 32.
-
-@item min-inline-insns
-The repeated inlining is throttled more and more by the linear function
-after exceeding the limit.  To avoid too much throttling, a minimum for
-this function is specified here to allow repeated inlining for very small
-functions even when a lot of repeated inlining already has been done.
-This parameter is ignored when @option{-funit-at-a-time} is used.
-The default value is 10.
-
 @item large-function-insns
 The limit specifying really large functions.  For functions greater than this
 limit inlining is constrained by @option{--param large-function-growth}.
index 5b6f7283b6c0f57e0e16b0dba3709bc510e1071e..c2b2fad8f17019e769c113a110aa6d56fd75b000 100644 (file)
@@ -719,6 +719,10 @@ extern int flag_unit_at_a_time;
 
 extern int flag_web;
 
+/* Nonzero means that we defer emitting functions until they are actually
+   used.  */
+extern int flag_remove_unreachable_functions;
+
 /* A string that's used when a random name is required.  NULL means
    to make it really random.  */
 
index 6439e26670f039e10c03f8038c69fd7dd6aa09c6..dafd37104b42bf7e09c84735e210b4f9a29cbe38 100644 (file)
@@ -1061,13 +1061,6 @@ common_handle_option (size_t scode, const char *arg,
       set_param_value ("max-inline-insns-single", value / 2);
       set_param_value ("max-inline-insns-auto", value / 2);
       set_param_value ("max-inline-insns-rtl", value);
-      if (value / 4 < MIN_INLINE_INSNS)
-       {
-         if (value / 4 > 10)
-           set_param_value ("min-inline-insns", value / 4);
-         else
-           set_param_value ("min-inline-insns", 10);
-       }
       break;
 
     case OPT_finstrument_functions:
index c5dfca864d52ec66f37cd5d179997b6416a44a49..b08603b1f29f57428da968d0c813bfe029f31372 100644 (file)
@@ -84,32 +84,6 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS,
          "The maximum number of instructions by repeated inlining before gcc starts to throttle inlining",
          200)
 
-/* 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 value 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 function 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",
-         10)
-
 /* For languages that (still) use the RTL inliner, we can specify
    limits for the RTL inliner separately.
    The parameter here defines the maximum number of RTL instructions
index 0f005e8bffc3a0a4139adfedc6246535dc9f021a..20bac3351bd8b665091d95d911bf71ab680a471b 100644 (file)
@@ -1,3 +1,9 @@
+2003-10-20  Jan Hubicka  <jh@suse.cz>
+
+       * testsuite/g++.dg/opt/inline4.C: Do not use min-inline-insns
+       parameter.
+       * testsuite/gcc.dg/inline-2.c: Likewise.
+
 2003-10-20  Phil Edwards  <phil@codesourcery.com>
 
        * gcc.dg/20021014-1.c:  XFAIL for *-*-windiss targets.
index 2d3eb379648db28d7536b933745e8db44cbd9f2d..1db4fe1860bd4fb8e2c94c6b905d701d573eaefa 100644 (file)
@@ -1,4 +1,4 @@
-// { dg-options "-O2 -ftemplate-depth-20000 --param min-inline-insns=100 --param max-inline-insns=3" }
+// { dg-options "-O2 -ftemplate-depth-20000" }
 
 template <int I>
 inline void g() { g<I-1>(); return; }
index 28991bccb9f639879155534f4380cee4eefb28ac..80e7848aca2c2ea592ea762b150c5dedf29aaf59 100644 (file)
@@ -11,7 +11,8 @@ static int foo(void)
 
 int bar(void)
 {
-  return foo() + 1;
+  /* Call twice to avoid bypassing the limit for functions called once.  */
+  return foo() + foo() + 1;
 }
 
 /* { dg-final { scan-assembler-not "jsr" { target alpha*-*-* } } } */
index 151f6c652806bdbb0e568b7a864e2202cf73723f..a393c52003e8803aaaf0b7d8d617835e0855c84d 100644 (file)
@@ -3364,9 +3364,6 @@ rest_of_compilation (tree decl)
 
   rest_of_handle_cfg (decl, insns);
 
-  if (flag_web)
-    rest_of_handle_web (decl, insns);
-
   if (optimize > 0
       || profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
     {
@@ -3394,6 +3391,9 @@ rest_of_compilation (tree decl)
          || flag_unroll_loops))
     rest_of_handle_loop2 (decl, insns);
 
+  if (flag_web)
+    rest_of_handle_web (decl, insns);
+
   if (flag_rerun_cse_after_loop)
     rest_of_handle_cse2 (decl, insns);
 
index 375a5702291b316e37e9960c44341dd68f6d2bcc..b827dfc1c29190d5a37e2f007ecd924ba2d3da47 100644 (file)
@@ -119,7 +119,6 @@ static tree copy_body (inline_data *);
 static tree expand_call_inline (tree *, int *, void *);
 static void expand_calls_inline (tree *, inline_data *);
 static bool inlinable_function_p (tree);
-static int limits_allow_inlining (tree, inline_data *);
 static tree remap_decl (tree, inline_data *);
 static tree remap_type (tree, inline_data *);
 #ifndef INLINER_FOR_JAVA
@@ -1219,97 +1218,6 @@ inlinable_function_p (tree fn)
   return inlinable;
 }
 
-/* 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.
-
-   Return nonzero if the function FN can be inlined into the inlining
-   context ID.  */
-
-static int
-limits_allow_inlining (tree fn, inline_data *id)
-{
-  int estimated_insns = 0;
-  size_t i;
-
-  /* Don't even bother if the function is not inlinable.  */
-  if (!inlinable_function_p (fn))
-    return 0;
-
-  /* Investigate the size of the function.  Return at once
-     if the function body size is too large.  */
-  if (!(*lang_hooks.tree_inlining.disregard_inline_limits) (fn))
-    {
-      int currfn_max_inline_insns;
-
-      /* If we haven't already done so, get an estimate of the number of
-        instructions that will be produces when expanding this function.  */
-      if (!DECL_ESTIMATED_INSNS (fn))
-       DECL_ESTIMATED_INSNS (fn)
-         = (*lang_hooks.tree_inlining.estimate_num_insns) (fn);
-      estimated_insns = DECL_ESTIMATED_INSNS (fn);
-
-      /* We may be here either because fn is declared inline or because
-        we use -finline-functions.  For the second case, we are more
-        restrictive.
-
-        FIXME: -finline-functions should imply -funit-at-a-time, it's
-               about equally expensive but unit-at-a-time produces
-               better code.  */
-      currfn_max_inline_insns = DECL_DECLARED_INLINE_P (fn) ?
-               MAX_INLINE_INSNS_SINGLE : MAX_INLINE_INSNS_AUTO;
-
-      /* If the function is too big to be inlined, adieu.  */
-      if (estimated_insns > currfn_max_inline_insns)
-       return 0;
-
-      /* We now know that we don't disregard the inlining limits and that 
-        we basically should be able to inline this function.
-        We always allow inlining functions if we estimate that they are
-        smaller than MIN_INLINE_INSNS.  Otherwise, investigate further.  */
-      if (estimated_insns > MIN_INLINE_INSNS)
-       {
-         int sum_insns = (id ? id->inlined_insns : 0) + estimated_insns;
-
-         /* In the extreme case that we have exceeded the recursive inlining
-            limit by a huge factor (128), we just say no.
-
-            FIXME:  Should not happen in real life, but people have reported
-                    that it actually does!?  */
-         if (sum_insns > MAX_INLINE_INSNS * 128)
-           return 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.  */
-         else if (sum_insns > MAX_INLINE_INSNS)
-           {
-             if (estimated_insns > currfn_max_inline_insns
-                       - (sum_insns - MAX_INLINE_INSNS) / MAX_INLINE_SLOPE)
-               return 0;
-           }
-       }
-    }
-
-  /* Don't allow recursive inlining.  */
-  for (i = 0; i < VARRAY_ACTIVE_SIZE (id->fns); ++i)
-    if (VARRAY_TREE (id->fns, i) == fn)
-      return 0;
-
-  if (DECL_INLINED_FNS (fn))
-    {
-      int j;
-      tree inlined_fns = DECL_INLINED_FNS (fn);
-
-      for (j = 0; j < TREE_VEC_LENGTH (inlined_fns); ++j)
-       if (TREE_VEC_ELT (inlined_fns, j) == VARRAY_TREE (id->fns, 0))
-         return 0;
-    }
-
-  /* Go ahead, this function can be inlined.  */
-  return 1;
-}
-
 /* If *TP is a CALL_EXPR, replace it with its inline expansion.  */
 
 static tree
@@ -1396,8 +1304,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
     return NULL_TREE;
 
   /* Turn forward declarations into real ones.  */
-  if (flag_unit_at_a_time)
-    fn = cgraph_node (fn)->decl;
+  fn = cgraph_node (fn)->decl;
 
   /* If fn is a declaration of a function in a nested scope that was
      globally declared inline, we don't set its DECL_INITIAL.
@@ -1413,9 +1320,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
 
   /* Don't try to inline functions that are not well-suited to
      inlining.  */
-  if ((flag_unit_at_a_time
-       && (!DECL_SAVED_TREE (fn) || !cgraph_inline_p (id->current_decl, fn)))
-      || (!flag_unit_at_a_time && !limits_allow_inlining (fn, id)))
+  if (!DECL_SAVED_TREE (fn) || !cgraph_inline_p (id->current_decl, fn))
     {
       if (warn_inline && DECL_INLINE (fn) && DECL_DECLARED_INLINE_P (fn)
          && !DECL_IN_SYSTEM_HEADER (fn))
@@ -1653,7 +1558,7 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data)
   id->inlined_insns += DECL_ESTIMATED_INSNS (fn) - 1;
 
   /* Update callgraph if needed.  */
-  if (id->decl && flag_unit_at_a_time)
+  if (id->decl)
     {
       cgraph_remove_call (id->decl, fn);
       cgraph_create_edges (id->decl, *inlined_body);