I suggest submitting the refactoring part of the changes to GCC trunk first.
thanks, David On Thu, May 2, 2013 at 11:06 AM, Carrot Wei <car...@google.com> wrote: > This patch fixes google bug 8397853 and targets google 4.7 branch. > > In LIPO mode, when coverage_obj_init is called, cgraph_state is > CGRAPH_STATE_FINISHED. The variable gcov_info_var is created but not > initialized. When cgraph_build_static_cdtor is called, the new function and > variables are expanded immediately since cgraph_state is > CGRAPH_STATE_FINISHED. > It causes gcov_info_var into .bss section. But later in function > coverage_obj_finish we initialize gcov_info_var with non zero contents, so it > should not be put into .bss section. > > In FDO mode we don't have this problem because when coverage_obj_init is > called, > cgraph_state is CGRAPH_STATE_IPA_SSA. When cgraph_build_static_cdtor is > called, > the new function is not immediately expanded. The variable will have been > properly initialized when it is expanded. > > It can be fixed by moving the construction of gcov constructor after > initialization of gcov_info_var. > > Tested with following testing: > x86-64 bootstrap. > x86-64 regression test. > power64 regression test on qemu. > > The only regression for power64 is > FAIL: gcc.dg/torture/tls/tls-test.c -O2 -flto -fno-use-linker-plugin > -flto-partition=none execution test > It is a flaky test case in our testing environment since all other executions > with different compiler options failed. All testing of tls-test.c pass native > power64 testing. > > thanks > Carrot > > 2013-05-02 Guozhi Wei <car...@google.com> > > * coverage.c (gcov_info_type): New global variable. > (coverage_obj_init): Move the construction of gcov constructor to > (build_init_ctor): here. > (coverage_obj_finish): Call build_init_ctor after initialization of > gcov_info_var. > > > Index: coverage.c > =================================================================== > --- coverage.c (revision 198425) > +++ coverage.c (working copy) > @@ -123,6 +123,7 @@ > > /* Coverage info VAR_DECL and function info type nodes. */ > static GTY(()) tree gcov_info_var; > +static GTY(()) tree gcov_info_type; > static GTY(()) tree gcov_fn_info_type; > static GTY(()) tree gcov_fn_info_ptr_type; > > @@ -2478,14 +2479,12 @@ > return build_constructor (info_type, v1); > } > > -/* Create the gcov_info types and object. Generate the constructor > - function to call __gcov_init. Does not generate the initializer > +/* Create the gcov_info types and object. Does not generate the initializer > for the object. Returns TRUE if coverage data is being emitted. */ > > static bool > coverage_obj_init (void) > { > - tree gcov_info_type, ctor, stmt, init_fn; > unsigned n_counters = 0; > unsigned ix; > struct coverage_data *fn; > @@ -2531,24 +2530,6 @@ > ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0); > DECL_NAME (gcov_info_var) = get_identifier (name_buf); > > - /* Build a decl for __gcov_init. */ > - init_fn = build_pointer_type (gcov_info_type); > - init_fn = build_function_type_list (void_type_node, init_fn, NULL); > - init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > - get_identifier ("__gcov_init"), init_fn); > - TREE_PUBLIC (init_fn) = 1; > - DECL_EXTERNAL (init_fn) = 1; > - DECL_ASSEMBLER_NAME (init_fn); > - > - /* Generate a call to __gcov_init(&gcov_info). */ > - ctor = NULL; > - stmt = build_fold_addr_expr (gcov_info_var); > - stmt = build_call_expr (init_fn, 1, stmt); > - append_to_statement_list (stmt, &ctor); > - > - /* Generate a constructor to run it. */ > - cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY); > - > return true; > } > > @@ -2570,6 +2551,32 @@ > return ctor; > } > > +/* Generate the constructor function to call __gcov_init. */ > + > +static void > +build_init_ctor () > +{ > + tree ctor, stmt, init_fn; > + > + /* Build a decl for __gcov_init. */ > + init_fn = build_pointer_type (gcov_info_type); > + init_fn = build_function_type_list (void_type_node, init_fn, NULL); > + init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, > + get_identifier ("__gcov_init"), init_fn); > + TREE_PUBLIC (init_fn) = 1; > + DECL_EXTERNAL (init_fn) = 1; > + DECL_ASSEMBLER_NAME (init_fn); > + > + /* Generate a call to __gcov_init(&gcov_info). */ > + ctor = NULL; > + stmt = build_fold_addr_expr (gcov_info_var); > + stmt = build_call_expr (init_fn, 1, stmt); > + append_to_statement_list (stmt, &ctor); > + > + /* Generate a constructor to run it. */ > + cgraph_build_static_cdtor ('I', ctor, DEFAULT_INIT_PRIORITY); > +} > + > /* Finalize the coverage data. Generates the array of pointers to > function objects from CTOR. Generate the gcov_info initializer. */ > > @@ -2589,9 +2596,12 @@ > DECL_NAME (fn_info_ary) = get_identifier (name_buf); > DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor); > varpool_finalize_decl (fn_info_ary); > - > + > DECL_INITIAL (gcov_info_var) > = build_info (TREE_TYPE (gcov_info_var), fn_info_ary); > + > + build_init_ctor (); > + > varpool_finalize_decl (gcov_info_var); > }