re PR ipa/44563 (GCC uses a lot of RAM when compiling a large numbers of functions)
authorJan Hubicka <hubicka@gcc.gnu.org>
Fri, 17 Dec 2010 00:08:02 +0000 (00:08 +0000)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 17 Dec 2010 00:08:02 +0000 (00:08 +0000)
PR middle-end/44563
* ipa-inline.c: Update doplevel comment.
(cgraph_estimate_size_after_inlining): Remove times attribute.
(cgraph_mark_inline_edge): Update.
(cgraph_mark_inline): Remove.
(cgraph_estimate_growth): Update.
(cgraph_check_inline_limits): Remove one only argument.
(cgraph_edge_badness): Update.
(cgraph_decide_recursive_inlining): Update.
(cgraph_decide_inlining_of_small_function): Fix handling of tree_can_inline_p
and call_stmt_cannot_inline_p.
(cgraph_flatten): Likewise.
(cgraph_decide_inlining): Update.
(cgraph_decide_inlining_incrementally): Fix handling of call_stmt_cannot_inline_p.

From-SVN: r167964

gcc/ChangeLog
gcc/ipa-inline.c

index 0bf3695441332ce956468598295cc214bf1e3828..0e3794355dd198498186dd159ad38c5453ef2b2f 100644 (file)
@@ -1,3 +1,20 @@
+2010-12-16  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/44563 
+       * ipa-inline.c: Update doplevel comment. 
+       (cgraph_estimate_size_after_inlining): Remove times attribute. 
+       (cgraph_mark_inline_edge): Update. 
+       (cgraph_mark_inline): Remove. 
+       (cgraph_estimate_growth): Update. 
+       (cgraph_check_inline_limits): Remove one only argument. 
+       (cgraph_edge_badness): Update. 
+       (cgraph_decide_recursive_inlining): Update. 
+       (cgraph_decide_inlining_of_small_function): Fix handling of tree_can_inline_p 
+       and call_stmt_cannot_inline_p. 
+       (cgraph_flatten): Likewise. 
+       (cgraph_decide_inlining): Update. 
+       (cgraph_decide_inlining_incrementally): Fix handling of call_stmt_cannot_inline_p. 
+
 2010-12-16  Joseph Myers  <joseph@codesourcery.com>
 
        * config/darwin.opt (dylinker, headerpad_max_install_names,
        * config/spu/t-spu-elf (dp-bit.c, fp-bit.c): Don't undefine
        US_SOFTWARE_GOFAST.
 
+2010-12-14  Jan Hubicka  <jh@suse.cz>
+
+       * config/darwin.opt (dylinker, headerpad_max_install_names,
+       keep_private_externs, nofixprebinding, nomultidefs, noprebind,
+       noseglinkedit, object, prebind, prebind_all_twolevel_modules,
+       preload, private_bundle, pthread, seglinkedit, twolevel_namespace,
+       twolevel_namespace_hints, whatsloaded, whyload, y, Mach, X): New
+       Driver options.
+       * config/darwin.h (LINK_SPEC): Remove '*' after
+       headerpad_max_install_names.
+
+2010-12-16  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR tree-optimization/46924
+       * graphite-sese-to-poly.c (detect_commutative_reduction): Do not
+       detect reductions outside the current SESE region.
+       * sese.h (stmt_in_sese_p): New.
+       (defined_in_sese_p): Call stmt_in_sese_p.
+
+2010-12-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/46966
+       * graphite-sese-to-poly.c (build_scop_drs): Call free_gimple_bb for
+       for bbs that are removed from SCOP_BBS vector.
+
+2010-12-16  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree-ssa-sccvn.c (vn_reference_lookup_3): Always punt if the call to
+       get_ref_base_and_extent returns -1 as the max size.
+
+2010-12-16  Konrad Eisele  <konrad@gaisler.com>
+            Eric Botcazou  <ebotcazou@adacore.com>
+
+       Support for LEON processor
+       * config.gcc (sparc-*-elf*): Deal with sparc-leon specifically.
+       (sparc-*-linux*): Likewise.
+       (sparc-*-rtems*): Remove Solaris left-overs.
+       (sparc*-*-*): Remove obsolete sparc86x setting.
+       (sparc-leon*): Default to --with-cpu=v8 and --with-tune=leon.
+       * doc/invoke.texi (SPARC Options): Document -mcpu/-mtune=leon.
+       * config/sparc/sparc.h (TARGET_CPU_leon): Define.
+       (TARGET_CPU_sparc86x): Delete.
+       (TARGET_CPU_cypress): Define as alias to TARGET_CPU_v7.
+       (TARGET_CPU_f930): Define as alias to TARGET_CPU_sparclite.
+       (TARGET_CPU_f934): Likewise.
+       (TARGET_CPU_tsc701): Define as alias to TARGET_CPU_sparclet.
+       (CPP_CPU_SPEC): Add entry for -mcpu=leon.
+       (enum processor_type): Add PROCESSOR_LEON.  Reorganize.
+       * config/sparc/sparc.c (leon_costs): New cost array.
+       (sparc_option_override): Add entry for TARGET_CPU_leon and -mcpu=leon.
+       Initialize cost array to leon_costs if -mtune=leon.
+       * config/sparc/sparc.md (cpu attribute): Add leon.  Reorganize.
+       Include leon.md scheduling description.
+       * config/sparc/leon.md: New file.
+       * config/sparc/t-elf: Do not assemble Solaris startup files.
+       * config/sparc/t-leon: New file.
+       * config/sparc/t-leon3: Likewise.
+
+2010-12-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/43655
+       * tree-ssa-ter.c (is_replaceable_p): Don't use
+       gimple_references_memory_p for -O0, instead check for load
+       by looking at rhs.
+
+2010-12-16  Sebastian Pop  <sebastian.pop@amd.com>
+
+       PR tree-optimization/46404
+       * graphite-clast-to-gimple.c (gloog): Call scev_reset.
+
+2010-12-16  Anatoly Sokolov  <aesok@post.ru>
+
+       * config/sh/sh.h (OUTPUT_ADDR_CONST_EXTRA): Remove.
+       * config/sh/sh.c (sh_asm_output_addr_const_extra): New function.
+       (TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA): Define.
+
+2010-12-16  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
+
+       * config/spu/t-spu-elf (LIB2_SIDITI_CONV_FUNC): Define.
+       * config/spu/spu.h (MIN_UNITS_PER_WORD): Do not define.
+       (LIBGCC2_UNITS_PER_WORD): Define if not already defined.
+
+2010-12-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR debug/46893
+       * cfgexpand.c (expand_debug_expr): If GET_MODE (op0) is VOIDmode,
+       use TYPE_MODE (TREE_TYPE (tem)) instead of mode1.
+
+2010-12-16  Chung-Lin Tang  <cltang@codesourcery.com>
+
+       PR target/46883
+       * config/arm/arm.md
+       (zero_extendhisi2 for register input splitter): Change
+       "register_operand" to "s_register_operand".
+       (zero_extendqisi2 for register input splitter): Same.
+
+2010-12-16  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/46939
+       * predic.c (predict_paths_leading_to_edge): New function.
+       (apply_return_prediction): Use it.
+       (predict_paths_for_bb): Do not special case abnormals.
+
+2010-12-16  Joseph Myers  <joseph@codesourcery.com>
+
+       * config.gcc (powerpc-*-lynxos*): Don't add lynx.opt to
+       extra_options twice.
+
+2010-12-15  Joseph Myers  <joseph@codesourcery.com>
+
+       * doc/tm.texi.in (US_SOFTWARE_GOFAST): Don't document.
+       * doc/tm.texi: Regenerate.
+       * system.h (US_SOFTWARE_GOFAST): Poison.
+       * config.gcc (enable_gofast): Don't handle.
+       * config/gofast.h: Remove.
+       * config/mips/t-gofast: Remove.
+       * config/fp-bit.c (US_SOFTWARE_GOFAST): Don't handle.
+       * config/fp-bit.h (US_SOFTWARE_GOFAST): Don't handle.
+       * config/mips/elforion.h: Don't mention GOFAST in comment.
+       * config/mips/mips.c: Don't include gofast.h.
+       (mips_init_libfuncs): Don't call gofast_maybe_init_libfuncs.
+       * config/mips/t-sr71k (dp-bit.c, fp-bit.c): Don't define
+       US_SOFTWARE_GOFAST.
+       * config/sparc/sparc.c: Don't include gofast.h.
+       (sparc_init_libfuncs): Don't call gofast_maybe_init_libfuncs.
+       * config/spu/t-spu-elf (dp-bit.c, fp-bit.c): Don't undefine
+       US_SOFTWARE_GOFAST.
+
 2010-12-14  Jan Hubicka  <jh@suse.cz>
 
        * tree.c (get_file_function_name): Avoid using random seed on GLOBAL_sub_I
index e8c78f9f5fb7c78afdf6f9b90960bc5ad83b3c6d..7ac50dd31bb9a07835e3f141cfddf22ba5255def 100644 (file)
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3.  If not see
 
     There are three major parts of this file:
 
-    cgraph_mark_inline implementation
+    cgraph_mark_inline_edge implementation
 
       This function allows to mark given call inline and performs necessary
       modifications of cgraph (production of the clones and updating overall
@@ -91,18 +91,6 @@ along with GCC; see the file COPYING3.  If not see
      optimized allowing it to unfold abstraction penalty on C++ effectively and
      cheaply.
 
-   pass_ipa_early_inlining
-
-     With profiling, the early inlining is also necessary to reduce
-     instrumentation costs on program with high abstraction penalty (doing
-     many redundant calls).  This can't happen in parallel with early
-     optimization and profile instrumentation, because we would end up
-     re-instrumenting already instrumented function bodies we brought in via
-     inlining.
-
-     To avoid this, this pass is executed as IPA pass before profiling.  It is
-     simple wrapper to pass_early_inlining and ensures first inlining.
-
    pass_ipa_inline
 
      This is the main pass implementing simple greedy algorithm to do inlining
@@ -110,12 +98,6 @@ along with GCC; see the file COPYING3.  If not see
      inlining of functions called once.  The pass compute just so called inline
      plan (representation of inlining to be done in callgraph) and unlike early
      inlining it is not performing the inlining itself.
-
-   pass_apply_inline
-
-     This pass performs actual inlining according to pass_ipa_inline on given
-     function.  Possible the function body before inlining is saved when it is
-     needed for further inlining later.
  */
 
 #include "config.h"
@@ -199,14 +181,14 @@ cgraph_estimate_time_after_inlining (int frequency, struct cgraph_node *to,
   return time;
 }
 
-/* Estimate self time of the function after inlining WHAT into TO.  */
+/* Estimate self size of the function after inlining WHAT into TO.  */
 
 static inline int
-cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
+cgraph_estimate_size_after_inlining (struct cgraph_node *to,
                                     struct cgraph_node *what)
 {
   int size = ((what->global.size - inline_summary (what)->size_inlining_benefit)
-             * times + to->global.size);
+             + to->global.size);
   gcc_assert (size >= 0);
   return size;
 }
@@ -335,7 +317,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
     {
       to = e->caller;
       old_size = e->caller->global.size;
-      new_size = cgraph_estimate_size_after_inlining (1, to, what);
+      new_size = cgraph_estimate_size_after_inlining (to, what);
       to->global.size = new_size;
       to->global.time = cgraph_estimate_time_after_inlining (freq, to, what);
     }
@@ -352,30 +334,6 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
     return false;
 }
 
-/* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER.  */
-
-static void
-cgraph_mark_inline (struct cgraph_edge *edge)
-{
-  struct cgraph_node *to = edge->caller;
-  struct cgraph_node *what = edge->callee;
-  struct cgraph_edge *e, *next;
-
-  gcc_assert (!edge->call_stmt_cannot_inline_p);
-  /* Look for all calls, mark them inline and clone recursively
-     all inlined functions.  */
-  for (e = what->callers; e; e = next)
-    {
-      next = e->next_caller;
-      if (e->caller == to && e->inline_failed)
-       {
-          cgraph_mark_inline_edge (e, true, NULL);
-         if (e == edge)
-           edge = next;
-       }
-    }
-}
-
 /* Estimate the growth caused by inlining NODE into all callees.  */
 
 static int
@@ -393,7 +351,7 @@ cgraph_estimate_growth (struct cgraph_node *node)
       if (e->caller == node)
         self_recursive = true;
       if (e->inline_failed)
-       growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
+       growth += (cgraph_estimate_size_after_inlining (e->caller, node)
                   - e->caller->global.size);
     }
 
@@ -424,21 +382,12 @@ cgraph_estimate_growth (struct cgraph_node *node)
 
 static bool
 cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
-                           cgraph_inline_failed_t *reason, bool one_only)
+                           cgraph_inline_failed_t *reason)
 {
-  int times = 0;
-  struct cgraph_edge *e;
   int newsize;
   int limit;
   HOST_WIDE_INT stack_size_limit, inlined_stack;
 
-  if (one_only)
-    times = 1;
-  else
-    for (e = to->callees; e; e = e->next_callee)
-      if (e->callee == what)
-       times++;
-
   if (to->global.inlined_to)
     to = to->global.inlined_to;
 
@@ -453,7 +402,7 @@ cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
 
   /* Check the size after inlining against the function limits.  But allow
      the function to shrink if it went over the limits by forced inlining.  */
-  newsize = cgraph_estimate_size_after_inlining (times, to, what);
+  newsize = cgraph_estimate_size_after_inlining (to, what);
   if (newsize >= to->global.size
       && newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
       && newsize > limit)
@@ -565,7 +514,7 @@ cgraph_edge_badness (struct cgraph_edge *edge, bool dump)
 {
   gcov_type badness;
   int growth =
-    (cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee)
+    (cgraph_estimate_size_after_inlining (edge->caller, edge->callee)
      - edge->caller->global.size);
 
   if (edge->callee->local.disregard_inline_limits)
@@ -895,7 +844,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
 
   /* Make sure that function is small enough to be considered for inlining.  */
   if (!max_depth
-      || cgraph_estimate_size_after_inlining (1, node, node)  >= limit)
+      || cgraph_estimate_size_after_inlining (node, node)  >= limit)
     return false;
   heap = fibheap_new ();
   lookup_recursive_calls (node, node, heap);
@@ -921,7 +870,7 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
 
   /* Do the inlining and update list of recursive call during process.  */
   while (!fibheap_empty (heap)
-        && (cgraph_estimate_size_after_inlining (1, node, master_clone)
+        && (cgraph_estimate_size_after_inlining (node, master_clone)
             <= limit))
     {
       struct cgraph_edge *curr
@@ -1128,7 +1077,7 @@ cgraph_decide_inlining_of_small_functions (void)
       
       callee = edge->callee;
 
-      growth = (cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee)
+      growth = (cgraph_estimate_size_after_inlining (edge->caller, edge->callee)
                - edge->caller->global.size);
 
       if (dump_file)
@@ -1220,7 +1169,8 @@ cgraph_decide_inlining_of_small_functions (void)
            }
          continue;
        }
-      if (!tree_can_inline_p (edge))
+      if (!tree_can_inline_p (edge)
+         || edge->call_stmt_cannot_inline_p)
        {
          if (dump_file)
            fprintf (dump_file, " inline_failed:%s.\n",
@@ -1244,9 +1194,8 @@ cgraph_decide_inlining_of_small_functions (void)
       else
        {
          struct cgraph_node *callee;
-         if (edge->call_stmt_cannot_inline_p
-             || !cgraph_check_inline_limits (edge->caller, edge->callee,
-                                             &edge->inline_failed, true))
+         if (!cgraph_check_inline_limits (edge->caller, edge->callee,
+                                          &edge->inline_failed))
            {
              if (dump_file)
                fprintf (dump_file, " Not inlining into %s:%s.\n",
@@ -1368,7 +1317,12 @@ cgraph_flatten (struct cgraph_node *node)
       struct cgraph_node *orig_callee;
 
       if (e->call_stmt_cannot_inline_p)
-       continue;
+       {
+         if (dump_file)
+           fprintf (dump_file, "Not inlining: %s",
+                    cgraph_inline_failed_string (e->inline_failed));
+         continue;
+       }
 
       if (!e->callee->analyzed)
        {
@@ -1555,10 +1509,10 @@ cgraph_decide_inlining (void)
                }
 
              if (cgraph_check_inline_limits (node->callers->caller, node,
-                                             &reason, false))
+                                             &reason))
                {
                  struct cgraph_node *caller = node->callers->caller;
-                 cgraph_mark_inline (node->callers);
+                 cgraph_mark_inline_edge (node->callers, true, NULL);
                  if (dump_file)
                    fprintf (dump_file,
                             " Inlined into %s which now has %i size"
@@ -1636,8 +1590,6 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
        if (!e->callee->local.disregard_inline_limits
            && (mode != INLINE_ALL || !e->callee->local.inlinable))
          continue;
-       if (e->call_stmt_cannot_inline_p)
-         continue;
        if (dump_file)
          fprintf (dump_file,
                   "Considering to always inline inline candidate %s.\n",
@@ -1648,7 +1600,8 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
              fprintf (dump_file, "Not inlining: recursive call.\n");
            continue;
          }
-       if (!tree_can_inline_p (e))
+       if (!tree_can_inline_p (e)
+           || e->call_stmt_cannot_inline_p)
          {
            if (dump_file)
              fprintf (dump_file,
@@ -1675,7 +1628,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
          fprintf (dump_file, " Inlining %s into %s.\n",
                   cgraph_node_name (e->callee),
                   cgraph_node_name (e->caller));
-       cgraph_mark_inline (e);
+       cgraph_mark_inline_edge (e, true, NULL);
        inlined = true;
       }
 
@@ -1725,25 +1678,24 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
          if (((mode == INLINE_SIZE || mode == INLINE_SIZE_NORECURSIVE)
               || (!flag_inline_functions
                   && !DECL_DECLARED_INLINE_P (e->callee->decl)))
-             && (cgraph_estimate_size_after_inlining (1, e->caller, e->callee)
+             && (cgraph_estimate_size_after_inlining (e->caller, e->callee)
                  > e->caller->global.size + allowed_growth)
              && cgraph_estimate_growth (e->callee) > allowed_growth)
            {
              if (dump_file)
                fprintf (dump_file,
                         "Not inlining: code size would grow by %i.\n",
-                        cgraph_estimate_size_after_inlining (1, e->caller,
+                        cgraph_estimate_size_after_inlining (e->caller,
                                                              e->callee)
                         - e->caller->global.size);
              continue;
            }
-         if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed,
-                                          false)
-             || e->call_stmt_cannot_inline_p)
+         if (e->call_stmt_cannot_inline_p
+             || !tree_can_inline_p (e))
            {
              if (dump_file)
-               fprintf (dump_file, "Not inlining: %s.\n",
-                        cgraph_inline_failed_string (e->inline_failed));
+               fprintf (dump_file,
+                        "Not inlining: call site not inlinable.\n");
              continue;
            }
          if (!e->callee->analyzed)
@@ -1753,11 +1705,10 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
                         "Not inlining: Function body no longer available.\n");
              continue;
            }
-         if (!tree_can_inline_p (e))
+         if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed))
            {
              if (dump_file)
-               fprintf (dump_file,
-                        "Not inlining: %s.",
+               fprintf (dump_file, "Not inlining: %s.\n",
                         cgraph_inline_failed_string (e->inline_failed));
              continue;
            }
@@ -1767,7 +1718,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
                fprintf (dump_file, " Inlining %s into %s.\n",
                         cgraph_node_name (e->callee),
                         cgraph_node_name (e->caller));
-             cgraph_mark_inline (e);
+             cgraph_mark_inline_edge (e, true, NULL);
              inlined = true;
            }
        }