ipa-inline.c (edge_badness): Reduce precision; use scc hints.
authorJan Hubicka <jh@suse.cz>
Sun, 28 Oct 2012 09:50:58 +0000 (10:50 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 28 Oct 2012 09:50:58 +0000 (09:50 +0000)
* ipa-inline.c (edge_badness): Reduce precision; use scc hints.
(inline_small_functions): Fix dumps; update all callees after inlining.
* ipa-inline.h (INLINE_HINT_in_scc, INLINE_HINT_same_scc): New constants.
(inline summary): Add SCC_NO.
* ipa-inline-analysis.c (dump_inline_hints): Dump SCC hints.
(reset_inline_summary): Reset scc_no.
(estimate_node_size_and_time): Set in_scc hint.
(do_estimate_edge_time): Add same_scc hint.
(do_estimate_edge_hints): Likewise.

From-SVN: r192888

gcc/ChangeLog
gcc/ipa-inline-analysis.c
gcc/ipa-inline.c
gcc/ipa-inline.h

index e3e6c29de878637f383df6d4a2fcef44882acd72..1e6f1fd8d985960516ff5ebe461c992b7aa7015f 100644 (file)
@@ -1,3 +1,15 @@
+2012-10-28  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-inline.c (edge_badness): Reduce precision; use scc hints.
+       (inline_small_functions): Fix dumps; update all callees after inlining.
+       * ipa-inline.h (INLINE_HINT_in_scc, INLINE_HINT_same_scc): New constants.
+       (inline summary): Add SCC_NO.
+       * ipa-inline-analysis.c (dump_inline_hints): Dump SCC hints.
+       (reset_inline_summary): Reset scc_no.
+       (estimate_node_size_and_time): Set in_scc hint.
+       (do_estimate_edge_time): Add same_scc hint.
+       (do_estimate_edge_hints): Likewise.
+
 2012-10-28  Andreas Schwab  <schwab@linux-m68k.org>
 
        * doc/cppopts.texi: Fix use of @item vs. @itemx inside @table.
index 915f5f2059bf399dd7c9d8833e5de708a8f2f770..8dd9c6927ed935a16b24ad44da4dc51eb42fe198 100644 (file)
@@ -639,6 +639,16 @@ dump_inline_hints (FILE *f, inline_hints hints)
       hints &= ~INLINE_HINT_loop_stride;
       fprintf (f, " loop_stride");
     }
+  if (hints & INLINE_HINT_same_scc)
+    {
+      hints &= ~INLINE_HINT_same_scc;
+      fprintf (f, " same_scc");
+    }
+  if (hints & INLINE_HINT_in_scc)
+    {
+      hints &= ~INLINE_HINT_in_scc;
+      fprintf (f, " in_scc");
+    }
   gcc_assert (!hints);
 }
 
@@ -973,6 +983,7 @@ reset_inline_summary (struct cgraph_node *node)
   info->stack_frame_offset = 0;
   info->size = 0;
   info->time = 0;
+  info->scc_no = 0;
   if (info->loop_iterations)
     {
       pool_free (edge_predicate_pool, info->loop_iterations);
@@ -2825,7 +2836,8 @@ estimate_node_size_and_time (struct cgraph_node *node,
   if (info->loop_stride
       && !evaluate_predicate (info->loop_stride, possible_truths))
     hints |=INLINE_HINT_loop_stride;
-
+  if (info->scc_no)
+    hints |= INLINE_HINT_in_scc;
 
   estimate_calls_size_and_time (node, &size, &time, &hints, possible_truths,
                                known_vals, known_binfos, known_aggs);
@@ -3323,6 +3335,9 @@ do_estimate_edge_time (struct cgraph_edge *edge)
   /* When caching, update the cache entry.  */
   if (edge_growth_cache)
     {
+      struct cgraph_node *to = (edge->caller->global.inlined_to
+                               ? edge->caller->global.inlined_to
+                               : edge->caller);
       if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache)
          <= edge->uid)
        VEC_safe_grow_cleared (edge_growth_cache_entry, heap, edge_growth_cache,
@@ -3332,6 +3347,9 @@ do_estimate_edge_time (struct cgraph_edge *edge)
 
       VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size
        = size + (size >= 0);
+      if (inline_summary (to)->scc_no
+         && inline_summary (to)->scc_no == inline_summary (callee)->scc_no)
+       hints |= INLINE_HINT_same_scc;
       VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints
        = hints + 1;
     }
@@ -3392,6 +3410,9 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
   VEC (tree, heap) *known_vals;
   VEC (tree, heap) *known_binfos;
   VEC (ipa_agg_jump_function_p, heap) *known_aggs;
+  struct cgraph_node *to = (edge->caller->global.inlined_to
+                           ? edge->caller->global.inlined_to
+                           : edge->caller);
 
   /* When we do caching, use do_estimate_edge_time to populate the entry.  */
 
@@ -3417,6 +3438,9 @@ do_estimate_edge_hints (struct cgraph_edge *edge)
   VEC_free (tree, heap, known_vals);
   VEC_free (tree, heap, known_binfos);
   VEC_free (ipa_agg_jump_function_p, heap, known_aggs);
+  if (inline_summary (to)->scc_no
+      && inline_summary (to)->scc_no == inline_summary (callee)->scc_no)
+    hints |= INLINE_HINT_same_scc;
   return hints;
 }
 
index 3f9a800b55d7ce854da9197d494331204f20f366..227941af8a7cdd51f4f490fcae8a2b07e8dccf51 100644 (file)
@@ -845,8 +845,8 @@ edge_badness (struct cgraph_edge *edge, bool dump)
         precision for small bandesses (those are interesting) yet we don't
         overflow for growths that are still in interesting range.
 
-        Fixed point arithmetic with point at 8th bit. */
-      badness = ((gcov_type)growth) * (1<<(19+8));
+        Fixed point arithmetic with point at 6th bit. */
+      badness = ((gcov_type)growth) * (1<<(19+6));
       badness = (badness + div / 2) / div;
 
       /* Overall growth of inlining all calls of function matters: we want to
@@ -861,9 +861,9 @@ edge_badness (struct cgraph_edge *edge, bool dump)
         We might mix the valud into the fraction by taking into account
         relative growth of the unit, but for now just add the number
         into resulting fraction.  */
-      if (badness > INT_MAX / 2)
+      if (badness > INT_MAX / 4)
        {
-         badness = INT_MAX / 2;
+         badness = INT_MAX / 4;
          if (dump)
            fprintf (dump_file, "Badness overflow\n");
        }
@@ -871,6 +871,10 @@ edge_badness (struct cgraph_edge *edge, bool dump)
                   | INLINE_HINT_loop_iterations
                   | INLINE_HINT_loop_stride))
        badness /= 8;
+      if (hints & (INLINE_HINT_same_scc))
+       badness *= 4;
+      if (hints & (INLINE_HINT_in_scc))
+       badness *= 2;
       if (dump)
        {
          fprintf (dump_file,
@@ -1337,16 +1341,10 @@ inline_small_functions (void)
   if (flag_indirect_inlining)
     new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8);
 
-  if (dump_file)
-    fprintf (dump_file,
-            "\nDeciding on inlining of small functions.  Starting with size %i.\n",
-            initial_size);
-
   /* Compute overall unit size and other global parameters used by badness
      metrics.  */
 
   max_count = 0;
-  initialize_growth_caches ();
 
   FOR_EACH_DEFINED_FUNCTION (node)
     if (!node->global.inlined_to)
@@ -1355,15 +1353,25 @@ inline_small_functions (void)
            || node->thunk.thunk_p)
          {
            struct inline_summary *info = inline_summary (node);
+           struct ipa_dfs_info *dfs = (struct ipa_dfs_info *) node->symbol.aux;
 
            if (!DECL_EXTERNAL (node->symbol.decl))
              initial_size += info->size;
+           info->scc_no = (dfs && dfs->next_cycle && dfs->next_cycle != node
+                           ? dfs->scc_no + 1 : 0);
          }
 
        for (edge = node->callers; edge; edge = edge->next_caller)
          if (max_count < edge->count)
            max_count = edge->count;
       }
+  ipa_free_postorder_info ();
+  initialize_growth_caches ();
+
+  if (dump_file)
+    fprintf (dump_file,
+            "\nDeciding on inlining of small functions.  Starting with size %i.\n",
+            initial_size);
 
   overall_size = initial_size;
   max_size = compute_max_insns (overall_size);
@@ -1528,7 +1536,7 @@ inline_small_functions (void)
          reset_edge_caches (edge->callee);
           reset_node_growth_cache (callee);
 
-         update_callee_keys (edge_heap, edge->callee, updated_nodes);
+         update_callee_keys (edge_heap, where, updated_nodes);
        }
       where = edge->caller;
       if (where->global.inlined_to)
index df8b3a7e2029ae3c6aba82dcbc30a415698e8fe8..ca59a7f70998ebb7258178e1257c4af7acdb0aa7 100644 (file)
@@ -47,7 +47,9 @@ typedef struct GTY(()) condition
 enum inline_hints_vals {
   INLINE_HINT_indirect_call = 1,
   INLINE_HINT_loop_iterations = 2,
-  INLINE_HINT_loop_stride = 4
+  INLINE_HINT_loop_stride = 4,
+  INLINE_HINT_same_scc = 8,
+  INLINE_HINT_in_scc = 16
 };
 typedef int inline_hints;
 
@@ -127,6 +129,8 @@ struct GTY(()) inline_summary
   /* Predicate on when some loop in the function becomes to have known
      stride.   */
   struct predicate * GTY((skip)) loop_stride;
+  /* Number of SCC on the beggining of inlining process.  */
+  int scc_no;
 };