/* The profile merging function for choosing the most common difference between two consecutive evaluations of the value. It is given an array COUNTERS of N_COUNTERS old counters and it reads the same number of counters from the gcov file. The counters are split into 4-tuples where the members of the tuple have meanings: -- the last value of the measured entity -- the stored candidate on the most common difference -- counter -- total number of evaluations of the value */ void __gcov_merge_delta (gcov_type *counters, unsigned n_counters) { unsigned i, n_measures; gcov_type value, counter, all; gcc_assert (!(n_counters % 4)); n_measures = n_counters / 4; for (i = 0; i < n_measures; i++, counters += 4) { /* last = */ gcov_read_counter (); value = gcov_read_counter (); counter = gcov_read_counter (); all = gcov_read_counter (); if (counters[1] == value) counters[2] += counter; else if (counter > counters[2]) { counters[1] = value; counters[2] = counter - counters[2]; } else counters[2] -= counter; counters[3] += all; } }
/* The profile merging function for choosing the most common value. It is given an array COUNTERS of N_COUNTERS old counters and it reads the same number of counters from the gcov file. The counters are split into 3-tuples where the members of the tuple have meanings: -- the stored candidate on the most common value of the measured entity -- counter -- total number of evaluations of the value */ void __gcov_merge_single (gcov_type *counters, unsigned n_counters) { unsigned i, n_measures; gcov_type value, counter, all; gcc_assert (!(n_counters % 3)); n_measures = n_counters / 3; for (i = 0; i < n_measures; i++, counters += 3) { value = gcov_read_counter (); counter = gcov_read_counter (); all = gcov_read_counter (); if (counters[0] == value) counters[1] += counter; else if (counter > counters[1]) { counters[0] = value; counters[1] = counter - counters[1]; } else counters[1] -= counter; counters[2] += all; } }
bool autofdo_source_profile::read () { if (gcov_read_unsigned () != GCOV_TAG_AFDO_FUNCTION) { inform (0, "Not expected TAG."); return false; } /* Skip the length of the section. */ gcov_read_unsigned (); /* Read in the function/callsite profile, and store it in local data structure. */ unsigned function_num = gcov_read_unsigned (); for (unsigned i = 0; i < function_num; i++) { function_instance::function_instance_stack stack; function_instance *s = function_instance::read_function_instance ( &stack, gcov_read_counter ()); afdo_profile_info->sum_all += s->total_count (); map_[s->name ()] = s; } return true; }
function_instance * function_instance::read_function_instance (function_instance_stack *stack, gcov_type head_count) { unsigned name = gcov_read_unsigned (); unsigned num_pos_counts = gcov_read_unsigned (); unsigned num_callsites = gcov_read_unsigned (); function_instance *s = new function_instance (name, head_count); stack->safe_push (s); for (unsigned i = 0; i < num_pos_counts; i++) { unsigned offset = gcov_read_unsigned () & 0xffff0000; unsigned num_targets = gcov_read_unsigned (); gcov_type count = gcov_read_counter (); s->pos_counts[offset].count = count; for (unsigned j = 0; j < stack->length (); j++) (*stack)[j]->total_count_ += count; for (unsigned j = 0; j < num_targets; j++) { /* Only indirect call target histogram is supported now. */ gcov_read_unsigned (); gcov_type target_idx = gcov_read_counter (); s->pos_counts[offset].targets[target_idx] = gcov_read_counter (); } } for (unsigned i = 0; i < num_callsites; i++) { unsigned offset = gcov_read_unsigned (); function_instance *callee_function_instance = read_function_instance (stack, 0); s->callsites[std::make_pair (offset, callee_function_instance->name ())] = callee_function_instance; } stack->pop (); return s; }
static void read_profile (void) { if (gcov_open (auto_profile_file, 1) == 0) error ("Cannot open profile file %s.", auto_profile_file); if (gcov_read_unsigned () != GCOV_DATA_MAGIC) error ("AutoFDO profile magic number does not mathch."); /* Skip the version number. */ unsigned version = gcov_read_unsigned (); if (version != AUTO_PROFILE_VERSION) error ("AutoFDO profile version %u does match %u.", version, AUTO_PROFILE_VERSION); /* Skip the empty integer. */ gcov_read_unsigned (); /* string_table. */ afdo_string_table = new string_table (); if (!afdo_string_table->read()) error ("Cannot read string table from %s.", auto_profile_file); /* autofdo_source_profile. */ afdo_source_profile = autofdo_source_profile::create (); if (afdo_source_profile == NULL) error ("Cannot read function profile from %s.", auto_profile_file); /* autofdo_module_profile. */ fake_read_autofdo_module_profile (); /* Read in the working set. */ if (gcov_read_unsigned () != GCOV_TAG_AFDO_WORKING_SET) error ("Cannot read working set from %s.", auto_profile_file); /* Skip the length of the section. */ gcov_read_unsigned (); gcov_working_set_t set[128]; for (unsigned i = 0; i < 128; i++) { set[i].num_counters = gcov_read_unsigned (); set[i].min_counter = gcov_read_counter (); } add_working_set (set); }
/* The profile merging function that just adds the counters. It is given an array COUNTERS of N_COUNTERS old counters and it reads the same number of counters from the gcov file. */ void __gcov_merge_ior (gcov_type *counters, unsigned n_counters) { for (; n_counters; counters++, n_counters--) *counters |= gcov_read_counter (); }