Thanks! Can you attach the patch file for the proposed change? David
On Fri, Nov 1, 2013 at 2:08 PM, Rong Xu <x...@google.com> wrote: > libgcov.c is the main file to generate libgcov.a. This single source generates > 21 object files and then archives to a library. These objects are of > very different purposes but they are in the same file guarded by various > macros. > The source file becomes quite large and its readability becomes very > low. In its current state: > 1) The code is very hard to understand by new developers; > 2) It makes regressions more likely when making simple changes; > More importantly, > 3) it makes code reuse/sharing very difficult. For instance, Using > libgcov to implement an offline profile tool (see below); kernel FDO > support etc. > > We came to this issue when working on an offline tool to handle > profile counters. > Our plan is to have a profile-tool can merge, diff, collect statistics, and > better dump raw profile counters. This is one of the most requested features > from out internal users. This tool can also be very useful for any > FDO/coverage > users. In the first part of tool, we want to have the weight > merge. Again, to reuse the code, we have to change libgcov.c. But we don't > want > to further diverge libgcov.a in our google branches from the trunk. > > Another issue in libgcov.c is function gcov_exit(). It is a huge function > with about 467 lines of code. This function traverses gcov_list and dumps all > the gcda files. The code for merging the gcda files also sits in the same > function. The structure makes the code-reuse and extension really difficult > (like in kernel FDO, we have to break this function to reuse some of the > code). > > We propose to break gcov_exit into smaller functions and split libgcov.c into > several files. Our plan for profile-tool is listed in (3). > > 1. break gcov_exit() into the following structure: > gcov_exit() > --> gcov_exit_compute_summary() > --> allocate_filename_struct() > for gi_ptr in gcov_list > --> gcov_exit_dump_gcov() > --> gcov_exit_open_gcda_file() > --> gcov_exit_merge_gcda () > --> gcov_exit_write_gcda () > > 2. split libgcov.c into the following files: > libgcov-profiler.c > libgcov-merge.c > libgcov-interface.c > libgcov-driver.c > libgcov-driver-system.c (source included into libgcov-driver.c) > > The details of the splitting: > libgcov-interface.c > /* This file contains API functions to other programs and the supporting > functions. */ > __gcov_dump() > __gcov_execl() > __gcov_execle() > __gcov_execlp() > __gcov_execv() > __gcov_execve() > __gcov_execvp() > __gcov_flush() > __gcov_fork() > __gcov_reset() > init_mx() > init_mx_once() > > libgcov-profiler.c > /* This file contains runtime profile handlers. */ > variables: > __gcov_indirect_call_callee > __gcov_indirect_call_counters > functions: > __gcov_average_profiler() > __gcov_indirect_call_profiler() > __gcov_indirect_call_profiler_v2() > __gcov_interval_profiler() > __gcov_ior_profiler() > __gcov_one_value_profiler() > __gcov_one_value_profiler_body() > __gcov_pow2_profiler() > > libgcov-merge.c > /* This file contains the merge functions for various counters. */ > functions: > __gcov_merge_add() > __gcov_merge_delta() > __gcov_merge_ior() > __gcov_merge_single() > > libcov-driver.c > /* This file contains the gcov dumping functions. We separate the > system dependent part to libgcov-driver-system.c. */ > variables: > gcov_list > gcov_max_filename > gcov_dump_complete > ------ newly added file static variables -- > this_prg > all_prg > crc32 > gi_filename > fn_buffer > fn_tail > sum_buffer > next_sum_buffer > sum_tail > ----- end ----- > functions: > free_fn_data() > buffer_fn_data() > crc32_unsigned() > gcov_version() > gcov_histogram_insert() > gcov_compute_histogram() > gcov_clear() > __gcov_init() > gcov_exit() > ------- newly added static functions -- > gcov_exit_compute_summary () > gcov_exit_merge_gcda() > gcov_exit_write_gcda() > gcov_exit_dump_gcov() > ----- end ----- > > libgcov-driver-system.c > /* system dependent part of ligcov-driver.c. */ > functions: > create_file_directory() > ------- newly added static functions -- > gcov_error() /* This replaces all fprintf(stderr, ...) */ > allocate_filename_struct() > gcov_exit_open_gcda_file() > > 3. add offline profile-tool support. > We will change the interface of merge functions to make it > take in-memory gcov_info list, and a weight as the arguments. > > We will add libgcov-tool.c. It has two APIs: > (1) read_profile_dir(): read a profile directory and reconstruct the > gcov_info link list in-memory. > (2) merge_profiles(): merge two in-memory gcov_info link list. > > We also add profile-tool.c in gcc directory. It will source-include > libgcov-tool.c and build a host binary. (We don't do library style > because that will need a hard dependence from gcc to libgcc). > profile-tool.c will mainly handle user options and the write-out of > gcov-info link list. Some changes in gcov-io.[ch] will be also needed. > > Thanks, > > -Rong