params.def (PARAM_INDIR_CALL_TOPN_PROFILE): New param.
authorRong Xu <xur@gcc.gnu.org>
Tue, 7 Oct 2014 04:06:12 +0000 (04:06 +0000)
committerRong Xu <xur@gcc.gnu.org>
Tue, 7 Oct 2014 04:06:12 +0000 (04:06 +0000)
2014-10-06  Rong Xu  <xur@google.com>

* gcc/params.def (PARAM_INDIR_CALL_TOPN_PROFILE): New param.
* gcc/tree-profile.c: (params.h): New include.
        (init_ic_make_global_vars): Make __gcov_indirect_call_topn_callee
        and __gcov_indirect_call_topn_counters for
        indirect_call_topn_profile.
(gimple_init_edge_profiler): New decls for
        __gcov_indirect_call_topn_profiler.
(gimple_gen_ic_profiler): Generate the correct profiler call.
(gimple_gen_ic_func_profiler): Fix format.
* gcc/value-prof.c (params.h): New include.
        (dump_histogram_value): Hanlde indirect_call_topn counters.
(stream_in_histogram_value): Ditto.
(gimple_indirect_call_to_profile): Use indirect_call_topn
        profile when PARAM_INDIR_CALL_TOPN_PROFILE is set.
(gimple_find_values_to_profile): Hanlde indirect_call_topn
        counters.
* gcc/value-prof.h (enum hist_type): Histrogram type for
        indirect_call_topn counters.
* gcc/profile.c (instrument_values): Instrument
        indirect_call_topn counters.

From-SVN: r215963

gcc/params.def
gcc/profile.c
gcc/tree-profile.c
gcc/value-prof.c
gcc/value-prof.h

index aefdd071f7aa4be9e3dd8d4c0b3389e57e4ee848..beff7e632124129f9751ab701a45b5ae59e4dbc1 100644 (file)
@@ -882,6 +882,14 @@ DEFPARAM (PARAM_PROFILE_FUNC_INTERNAL_ID,
          "use internal function id in profile lookup",
           0, 0, 1)
 
+/* When the parameter is 1, track the most frequent N target
+   addresses in indirect-call profile. This disables
+   indirect_call_profiler_v2 which tracks single target.  */
+DEFPARAM (PARAM_INDIR_CALL_TOPN_PROFILE,
+         "indir-call-topn-profile",
+         "track topn target addresses in indirect-call profile",
+          0, 0, 1)
+
 /* Avoid SLP vectorization of large basic blocks.  */
 DEFPARAM (PARAM_SLP_MAX_INSNS_IN_BB,
           "slp-max-insns-in-bb",
index 7d8b54c4b4ed682b67e968dd8768322b45f6cccc..6be8a030fc6e0ade3632f1e18cbddf9e2fac5e2f 100644 (file)
@@ -183,6 +183,7 @@ instrument_values (histogram_values values)
          break;
 
        case HIST_TYPE_INDIR_CALL:
+       case HIST_TYPE_INDIR_CALL_TOPN:
          gimple_gen_ic_profiler (hist, t, 0);
          break;
 
index ba90196c7ce08a2e11593253bb906ac46604e5c2..48d13a22d341f94764e9ed2f5e3af79be930cea2 100644 (file)
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "tree-cfgcleanup.h"
 #include "tree-nested.h"
+#include "params.h"
 
 static GTY(()) tree gcov_type_node;
 static GTY(()) tree tree_interval_profiler_fn;
@@ -101,7 +102,10 @@ init_ic_make_global_vars (void)
     {
       ic_void_ptr_var
        = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-                     get_identifier ("__gcov_indirect_call_callee"),
+                     get_identifier (
+                             (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
+                              "__gcov_indirect_call_topn_callee" :
+                              "__gcov_indirect_call_callee")),
                      ptr_void);
       TREE_PUBLIC (ic_void_ptr_var) = 1;
       DECL_EXTERNAL (ic_void_ptr_var) = 1;
@@ -131,7 +135,10 @@ init_ic_make_global_vars (void)
     {
       ic_gcov_type_ptr_var
        = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-                     get_identifier ("__gcov_indirect_call_counters"),
+                     get_identifier (
+                             (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
+                              "__gcov_indirect_call_topn_counters" :
+                              "__gcov_indirect_call_counters")),
                      gcov_type_ptr);
       TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
       DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
@@ -226,8 +233,10 @@ gimple_init_edge_profiler (void)
                                              ptr_void,
                                              NULL_TREE);
          tree_indirect_call_profiler_fn
-                 = build_fn_decl ("__gcov_indirect_call_profiler_v2",
-                                        ic_profiler_fn_type);
+                 = build_fn_decl ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
+                                    "__gcov_indirect_call_topn_profiler":
+                                    "__gcov_indirect_call_profiler_v2"),
+                                  ic_profiler_fn_type);
         }
       TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
       DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
@@ -398,6 +407,12 @@ gimple_gen_ic_profiler (histogram_value value, unsigned tag, unsigned base)
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
   tree ref_ptr = tree_coverage_counter_addr (tag, base);
 
+  if ( (PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
+        tag == GCOV_COUNTER_V_INDIR) ||
+       (!PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) &&
+        tag == GCOV_COUNTER_ICALL_TOPNV))
+    return;
+
   ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
                                      true, NULL_TREE, true, GSI_SAME_STMT);
 
@@ -442,8 +457,7 @@ gimple_gen_ic_func_profiler (void)
     stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
                                             &current_function_decl)
    */
-  gsi =
-                                            gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
+  gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun))));
 
   cur_func = force_gimple_operand_gsi (&gsi,
                                       build_addr (current_function_decl,
index e3579678b71cc44f0d534dde6415089703206517..37710ca6da61a3e4e36f6fcde1b45bd98f31e4ee 100644 (file)
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "builtins.h"
 #include "tree-nested.h"
 #include "hash-set.h"
+#include "params.h"
 
 /* In this file value profile based optimizations are placed.  Currently the
    following optimizations are implemented (for more detailed descriptions
@@ -359,6 +360,22 @@ dump_histogram_value (FILE *dump_file, histogram_value hist)
       }
       fprintf (dump_file, ".\n");
       break;
+    case HIST_TYPE_INDIR_CALL_TOPN:
+      fprintf (dump_file, "Indirect call topn ");
+      if (hist->hvalue.counters)
+       {
+           int i;
+
+           fprintf (dump_file, "accu:%"PRId64, hist->hvalue.counters[0]);
+           for (i = 1; i < (GCOV_ICALL_TOPN_VAL << 2); i += 2)
+             {
+               fprintf (dump_file, " target:%"PRId64 " value:%"PRId64,
+                       (int64_t) hist->hvalue.counters[i],
+                       (int64_t) hist->hvalue.counters[i+1]);
+             }
+        }
+      fprintf (dump_file, ".\n");
+      break;
     case HIST_TYPE_MAX:
       gcc_unreachable ();
    }
@@ -432,9 +449,14 @@ stream_in_histogram_value (struct lto_input_block *ib, gimple stmt)
          break;
 
        case HIST_TYPE_IOR:
-  case HIST_TYPE_TIME_PROFILE:
+        case HIST_TYPE_TIME_PROFILE:
          ncounters = 1;
          break;
+
+        case HIST_TYPE_INDIR_CALL_TOPN:
+          ncounters = (GCOV_ICALL_TOPN_VAL << 2) + 1;
+          break;
+
        case HIST_TYPE_MAX:
          gcc_unreachable ();
        }
@@ -1920,8 +1942,12 @@ gimple_indirect_call_to_profile (gimple stmt, histogram_values *values)
 
   values->reserve (3);
 
-  values->quick_push (gimple_alloc_histogram_value (cfun, HIST_TYPE_INDIR_CALL,
-                                                   stmt, callee));
+  values->quick_push (gimple_alloc_histogram_value (
+                        cfun,
+                        PARAM_VALUE (PARAM_INDIR_CALL_TOPN_PROFILE) ?
+                          HIST_TYPE_INDIR_CALL_TOPN :
+                          HIST_TYPE_INDIR_CALL,
+                       stmt, callee));
 
   return;
 }
@@ -2011,9 +2037,9 @@ gimple_find_values_to_profile (histogram_values *values)
          hist->n_counters = 3;
          break;
 
-  case HIST_TYPE_TIME_PROFILE:
-    hist->n_counters = 1;
-    break;
+        case HIST_TYPE_TIME_PROFILE:
+          hist->n_counters = 1;
+          break;
 
        case HIST_TYPE_AVERAGE:
          hist->n_counters = 2;
@@ -2023,6 +2049,10 @@ gimple_find_values_to_profile (histogram_values *values)
          hist->n_counters = 1;
          break;
 
+        case HIST_TYPE_INDIR_CALL_TOPN:
+          hist->n_counters = GCOV_ICALL_TOPN_NCOUNTS;
+          break;
+
        default:
          gcc_unreachable ();
        }
index 9d2c3516d2227aea04ffce56f78feba0200ff2ba..00a89fab2a43ad8ffdb798fa76e1ad2cc5dc528d 100644 (file)
@@ -35,6 +35,8 @@ enum hist_type
   HIST_TYPE_AVERAGE,   /* Compute average value (sum of all values).  */
   HIST_TYPE_IOR,       /* Used to compute expected alignment.  */
   HIST_TYPE_TIME_PROFILE, /* Used for time profile */
+  HIST_TYPE_INDIR_CALL_TOPN, /* Tries to identify the top N most frequently
+                                called functions in indirect call.  */
   HIST_TYPE_MAX
 };