Hi,
while debugging quite werid libgcov issue I noticed that we skip profiling 
DECL_EXTERNAL
functions.  THis is not quite correct: if the function gets inlined during the 
train run,
the counters are used and ought to be streamed.  With LTO the profile will get 
merged with
the offline copy from other unit, without LTO we can be pretty sure the 
function will be inlined
in -fprofile-use run, too (if it matters) and thus ought to be instrumented as 
well or we hit
problems with empty profile.

I also revisited coverage_compute_profile_id to be non-zero, since function IDs 
was nonzero before
and made it prettier with unique name symbols.

Bootstrapped/regtested x86_64-linux, comitted.

        * coverage.c (coverage_compute_profile_id): Return non-0;
        also handle symbols with unique name.
        (coverage_end_function): Do not skip DECL_EXTERNAL functions.
Index: coverage.c
===================================================================
--- coverage.c  (revision 214223)
+++ coverage.c  (working copy)
@@ -579,7 +579,7 @@ coverage_compute_profile_id (struct cgra
   unsigned chksum;
 
   /* Externally visible symbols have unique name.  */
-  if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl))
+  if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl) || n->unique_name)
     {
       chksum = coverage_checksum_string
        (0, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
@@ -601,8 +601,10 @@ coverage_compute_profile_id (struct cgra
        (chksum, aux_base_name);
     }
 
-  /* Non-negative integers are hopefully small enough to fit in all targets.  
*/
-  return chksum & 0x7fffffff;
+  /* Non-negative integers are hopefully small enough to fit in all targets.
+     Gcov file formats wants non-zero function IDs.  */
+  chksum = chksum & 0x7fffffff;
+  return chksum + (!chksum);
 }
 
 /* Compute cfg checksum for the function FN given as argument.
@@ -692,30 +694,24 @@ coverage_end_function (unsigned lineno_c
     {
       struct coverage_data *item = 0;
 
-      /* If the function is extern (i.e. extern inline), then we won't
-        be outputting it, so don't chain it onto the function
-        list.  */
-      if (!DECL_EXTERNAL (current_function_decl))
-       {
-         item = ggc_alloc<coverage_data> ();
+      item = ggc_alloc<coverage_data> ();
 
-          if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
-           item->ident = current_function_funcdef_no + 1;
-          else
-            {
-              gcc_assert (coverage_node_map_initialized_p ());
-              item->ident = cgraph_node::get (cfun->decl)->profile_id;
-            }
-
-         item->lineno_checksum = lineno_checksum;
-         item->cfg_checksum = cfg_checksum;
-
-         item->fn_decl = current_function_decl;
-         item->next = 0;
-         *functions_tail = item;
-         functions_tail = &item->next;
+      if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
+       item->ident = current_function_funcdef_no + 1;
+      else
+       {
+         gcc_assert (coverage_node_map_initialized_p ());
+         item->ident = cgraph_node::get (cfun->decl)->profile_id;
        }
 
+      item->lineno_checksum = lineno_checksum;
+      item->cfg_checksum = cfg_checksum;
+
+      item->fn_decl = current_function_decl;
+      item->next = 0;
+      *functions_tail = item;
+      functions_tail = &item->next;
+
       for (i = 0; i != GCOV_COUNTERS; i++)
        {
          tree var = fn_v_ctrs[i];

Reply via email to