@@ -0,0 +1,1298 @@
+# The patch is backport of following revisions:
+# git repo: https://github.com/marxin/gcc/tree/single-value-profile-gcc-9
+# r272179
+# r272143
+# r272116
+# r272114
+# r272111
+# r272108
+# r272107
+# r272106
+# r272030
+
+diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
+index 29585cf15aa..af940fa66d4 100644
+--- a/gcc/doc/invoke.texi
++++ b/gcc/doc/invoke.texi
+@@ -12128,9 +12128,6 @@ will not try to thread through its block.
+ Maximum number of nested calls to search for control dependencies
+ during uninitialized variable analysis.
+
+-@item indir-call-topn-profile
+-Track top N target addresses in indirect-call profile.
+-
+ @item max-once-peeled-insns
+ The maximum number of insns of a peeled loop that rolls only once.
+
+diff --git a/gcc/gcov-counter.def b/gcc/gcov-counter.def
+index 3a0e620987a..b0596c8dc6b 100644
+--- a/gcc/gcov-counter.def
++++ b/gcc/gcov-counter.def
+@@ -49,6 +49,3 @@ DEF_GCOV_COUNTER(GCOV_COUNTER_IOR, "ior", _ior)
+
+ /* Time profile collecting first run of a function */
+ DEF_GCOV_COUNTER(GCOV_TIME_PROFILER, "time_profiler", _time_profile)
+-
+-/* Top N value tracking for indirect calls. */
+-DEF_GCOV_COUNTER(GCOV_COUNTER_ICALL_TOPNV, "indirect_call_topn", _icall_topn)
+diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
+index 9edb2923982..0f2905c17ec 100644
+--- a/gcc/gcov-io.h
++++ b/gcc/gcov-io.h
+@@ -266,11 +266,12 @@ GCOV_COUNTERS
+ #define GCOV_N_VALUE_COUNTERS \
+ (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
+
+-/* The number of hottest callees to be tracked. */
+-#define GCOV_ICALL_TOPN_VAL 2
++/* Number of single value histogram values that live
++ on disk representation. */
++#define GCOV_DISK_SINGLE_VALUES 4
+
+-/* The number of counter entries per icall callsite. */
+-#define GCOV_ICALL_TOPN_NCOUNTS (1 + GCOV_ICALL_TOPN_VAL * 4)
++/* Total number of single value counters. */
++#define GCOV_SINGLE_VALUE_COUNTERS (2 * GCOV_DISK_SINGLE_VALUES + 1)
+
+ /* Convert a counter index to a tag. */
+ #define GCOV_TAG_FOR_COUNTER(COUNT) \
+diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
+index e4c9dda0df1..91425022036 100644
+--- a/gcc/ipa-icf.c
++++ b/gcc/ipa-icf.c
+@@ -2768,20 +2768,20 @@ sem_item_optimizer::build_graph (void)
+ void
+ sem_item_optimizer::parse_nonsingleton_classes (void)
+ {
+- unsigned int init_called_count = 0;
++ unsigned int counter = 0;
+
+ for (unsigned i = 0; i < m_items.length (); i++)
+ if (m_items[i]->cls->members.length () > 1)
+ {
+ m_items[i]->init ();
+- init_called_count++;
++ ++counter;
+ }
+
+ if (dump_file)
+- fprintf (dump_file, "Init called for %u items (%.2f%%).\n",
+- init_called_count,
+- m_items.length () ? 100.0f * init_called_count / m_items.length ()
+- : 0.0f);
++ {
++ float f = m_items.length () ? 100.0f * counter / m_items.length () : 0.0f;
++ fprintf (dump_file, "Init called for %u items (%.2f%%).\n", counter, f);
++ }
+ }
+
+ /* Equality function for semantic items is used to subdivide existing
+@@ -3300,13 +3300,9 @@ sem_item_optimizer::dump_cong_classes (void)
+ if (!dump_file)
+ return;
+
+- fprintf (dump_file,
+- "Congruence classes: %u (unique hash values: %lu), with total: "
+- "%u items\n", m_classes_count,
+- (unsigned long) m_classes.elements (), m_items.length ());
+-
+ /* Histogram calculation. */
+ unsigned int max_index = 0;
++ unsigned int single_element_classes = 0;
+ unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
+
+ for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
+@@ -3318,21 +3314,25 @@ sem_item_optimizer::dump_cong_classes (void)
+
+ if (c > max_index)
+ max_index = c;
++
++ if (c == 1)
++ ++single_element_classes;
+ }
+
++ fprintf (dump_file,
++ "Congruence classes: %lu with total: %u items (in a non-singular "
++ "class: %u)\n", (unsigned long) m_classes.elements (),
++ m_items.length (), m_items.length () - single_element_classes);
+ fprintf (dump_file,
+ "Class size histogram [num of members]: number of classe number "
+ "of classess\n");
+-
+ for (unsigned int i = 0; i <= max_index; i++)
+ if (histogram[i])
+- fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
+-
+- fprintf (dump_file, "\n\n");
++ fprintf (dump_file, "%6u: %6u\n", i, histogram[i]);
+
+ if (dump_flags & TDF_DETAILS)
+- for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
+- it != m_classes.end (); ++it)
++ for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
++ it != m_classes.end (); ++it)
+ {
+ fprintf (dump_file, " group: with %u classes:\n",
+ (*it)->classes.length ());
+diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
+index de9563d808c..c80ea7a9b95 100644
+--- a/gcc/ipa-profile.c
++++ b/gcc/ipa-profile.c
+@@ -191,17 +191,17 @@ ipa_profile_generate_summary (void)
+ takes away bad histograms. */
+ if (h)
+ {
+- /* counter 0 is target, counter 1 is number of execution we called target,
+- counter 2 is total number of executions. */
+- if (h->hvalue.counters[2])
++ gcov_type val, count, all;
++ if (get_most_common_single_value (NULL, "indirect call",
++ h, &val, &count, &all))
+ {
+ struct cgraph_edge * e = node->get_edge (stmt);
+ if (e && !e->indirect_unknown_callee)
+ continue;
+- e->indirect_info->common_target_id
+- = h->hvalue.counters [0];
++
++ e->indirect_info->common_target_id = val;
+ e->indirect_info->common_target_probability
+- = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]);
++ = GCOV_COMPUTE_SCALE (count, all);
+ if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE)
+ {
+ if (dump_file)
+diff --git a/gcc/params.def b/gcc/params.def
+index 3c9c5fc0f13..f38798a60c4 100644
+--- a/gcc/params.def
++++ b/gcc/params.def
+@@ -992,14 +992,6 @@ 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_v3 which tracks single target. */
+-DEFPARAM (PARAM_INDIR_CALL_TOPN_PROFILE,
+- "indir-call-topn-profile",
+- "Track top N 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",
+diff --git a/gcc/profile.c b/gcc/profile.c
+index a1dba1ac8fb..9aff9ef2b21 100644
+--- a/gcc/profile.c
++++ b/gcc/profile.c
+@@ -172,7 +172,6 @@ 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;
+
+diff --git a/gcc/testsuite/gcc.dg/ipa/pr68035.c b/gcc/testsuite/gcc.dg/ipa/pr68035.c
+index a8cb77971f6..f6adad9f24d 100644
+--- a/gcc/testsuite/gcc.dg/ipa/pr68035.c
++++ b/gcc/testsuite/gcc.dg/ipa/pr68035.c
|