+}
+
+/* Load value histograms values whose description is stored in VALUES array
+ from .gcda file.
+
+ CFG_CHECKSUM is the precomputed checksum for the CFG. */
+
+static void
+compute_value_histograms (histogram_values values, unsigned cfg_checksum,
+ unsigned lineno_checksum)
+{
+ unsigned i, j, t, any;
+ unsigned n_histogram_counters[GCOV_N_VALUE_COUNTERS];
+ gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
+ gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
+ gcov_type *aact_count;
+
+ for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+ n_histogram_counters[t] = 0;
+
+ for (i = 0; i < VEC_length (histogram_value, values); i++)
+ {
+ histogram_value hist = VEC_index (histogram_value, values, i);
+ n_histogram_counters[(int) hist->type] += hist->n_counters;
+ }
+
+ any = 0;
+ for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+ {
+ if (!n_histogram_counters[t])
+ {
+ histogram_counts[t] = NULL;
+ continue;
+ }
+
+ histogram_counts[t] =
+ get_coverage_counts (COUNTER_FOR_HIST_TYPE (t),
+ n_histogram_counters[t], cfg_checksum,
+ lineno_checksum, NULL);
+ if (histogram_counts[t])
+ any = 1;
+ act_count[t] = histogram_counts[t];
+ }
+ if (!any)
+ return;
+
+ for (i = 0; i < VEC_length (histogram_value, values); i++)
+ {
+ histogram_value hist = VEC_index (histogram_value, values, i);
+ gimple stmt = hist->hvalue.stmt;
+
+ t = (int) hist->type;
+
+ aact_count = act_count[t];
+ act_count[t] += hist->n_counters;
+
+ gimple_add_histogram_value (cfun, stmt, hist);
+ hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
+ for (j = 0; j < hist->n_counters; j++)
+ hist->hvalue.counters[j] = aact_count[j];
+ }
+
+ for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
+ free (histogram_counts[t]);
+}
+
+/* The entry basic block will be moved around so that it has index=1,
+ there is nothing at index 0 and the exit is at n_basic_block. */
+#define BB_TO_GCOV_INDEX(bb) ((bb)->index - 1)
+/* When passed NULL as file_name, initialize.
+ When passed something else, output the necessary commands to change
+ line to LINE and offset to FILE_NAME. */
+static void
+output_location (char const *file_name, int line,
+ gcov_position_t *offset, basic_block bb)
+{
+ static char const *prev_file_name;
+ static int prev_line;
+ bool name_differs, line_differs;
+
+ if (!file_name)
+ {
+ prev_file_name = NULL;
+ prev_line = -1;
+ return;
+ }
+
+ name_differs = !prev_file_name || filename_cmp (file_name, prev_file_name);
+ line_differs = prev_line != line;
+
+ if (name_differs || line_differs)
+ {
+ if (!*offset)
+ {
+ *offset = gcov_write_tag (GCOV_TAG_LINES);
+ gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
+ name_differs = line_differs=true;
+ }
+
+ /* If this is a new source file, then output the
+ file's name to the .bb file. */
+ if (name_differs)
+ {
+ prev_file_name = file_name;
+ gcov_write_unsigned (0);
+ gcov_write_string (prev_file_name);
+ }
+ if (line_differs)
+ {
+ gcov_write_unsigned (line);
+ prev_line = line;
+ }
+ }