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

Reply via email to