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 1e0075c..2d59559 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 7b85e77..c20367d 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 863dce5..835480d 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 5ae27f8..9756bba 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 1acee5f..c2cb189 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 8ca69d1..0f1170c 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 4dbe1ee..52bdd6d 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 5b6f728..c2b2fad 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 6439e26..dafd371 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 c5dfca8..b08603b 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 0f005e8..20bac33 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 2d3eb37..1db4fe1 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 28991bc..80e7848 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 151f6c6..a393c52 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 375a570..b827dfc 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);