conditional gcov instrumentation

2009-09-07 Thread Hayawardh V
Hi,
I have been working on a conditional gcov patch, that calls a function
everytime the gcov counter is to be modified, so the function can
decide how to increment the counter.
The function's prototype is :

void __gcov_ctr(gcov_type*) ;

where gcov_type would be, for example, long long depending on the architecture.

This would be useful for kernel coverage instrumentation (eg) tracking
the coverage of only a particular pid, or for implementing atomic
counters per cpu, and probably for many others.
The libgcov could have a weak default implementation which increments
the counter by 1 as usual, and those wanting to add their own
implementation could do so. (Suggested by Peter Oberparleiter).

I am attaching a patch. Please comment.

Regards,
Hayawardh


gcc-4.4.0-gcov-ctr-ptr.patch
Description: Binary data


Re: conditional gcov instrumentation

2009-09-07 Thread Hayawardh V
Reattaching patch if not received.

--- gcc-4.4.0/gcc/tree-profile.c2009-09-03 00:10:48.0 -0400
+++ gcc-4.4.0-gcov-ptr-src/gcc/tree-profile.c   2009-09-03
00:11:01.0 -0400
@@ -183,22 +183,25 @@
 static void
 tree_gen_edge_profiler (int edgeno, edge e)
 {
-  tree ref, one;
-  gimple stmt1, stmt2, stmt3;
+  tree ref;
+  gimple call;
+  tree decl, gcov_ctr_fn_type, ctr_ptr, gcov_type_ptr;

   /* We share one temporary variable declaration per function.  This
  gets re-set in tree_profiling.  */
   if (gcov_type_tmp_var == NULL_TREE)
 gcov_type_tmp_var = create_tmp_var (gcov_type_node, "PROF_edge_counter");
   ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
-  one = build_int_cst (gcov_type_node, 1);
-  stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
-  stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
-   gcov_type_tmp_var, one);
-  stmt3 = gimple_build_assign (unshare_expr (ref), gcov_type_tmp_var);
-  gsi_insert_on_edge (e, stmt1);
-  gsi_insert_on_edge (e, stmt2);
-  gsi_insert_on_edge (e, stmt3);
+  gcov_type_ptr = build_pointer_type (get_gcov_type());
+
+  gcov_ctr_fn_type = build_function_type_list(void_type_node,
gcov_type_ptr, NULL_TREE);
+
+  decl = build_decl(FUNCTION_DECL, get_identifier("__gcov_ctr"),
gcov_ctr_fn_type);
+  ctr_ptr = build_addr(ref, current_function_decl);
+
+  call = gimple_build_call (decl, 1, ctr_ptr);
+
+  gsi_insert_on_edge (e, call);
 }

 /* Emits code to get VALUE to instrument at GSI, and returns the



On Mon, Sep 7, 2009 at 3:51 PM, Hayawardh V wrote:
> Hi,
> I have been working on a conditional gcov patch, that calls a function
> everytime the gcov counter is to be modified, so the function can
> decide how to increment the counter.
> The function's prototype is :
>
> void __gcov_ctr(gcov_type*) ;
>
> where gcov_type would be, for example, long long depending on the 
> architecture.
>
> This would be useful for kernel coverage instrumentation (eg) tracking
> the coverage of only a particular pid, or for implementing atomic
> counters per cpu, and probably for many others.
> The libgcov could have a weak default implementation which increments
> the counter by 1 as usual, and those wanting to add their own
> implementation could do so. (Suggested by Peter Oberparleiter).
>
> I am attaching a patch. Please comment.
>
> Regards,
> Hayawardh
>


Regarding gcov instrumentation in gcc, tree-profile.c

2009-07-12 Thread Hayawardh V
Hi,

I am looking to change the edge instrumentation for gcov. Instead of
just incrementing the edge count by 1, I want it to call an (external)
function which determines whether it should increment, and depending
on the answer, increment the edge.

I modified the tree_gen_edge_profiler function in tree-profile.c as
follows in gcc-4.4, (changed lines prefixed by [*]) :
(to instrument:

temp = function_return_value(); /* function returns 0 or 1 */
edge_count = edge_count + temp;

)

static void
tree_gen_edge_profiler (int edgeno, edge e)
{
 tree ref, one;
 gimple stmt1, stmt2, stmt3;
[*] gimple call;
[*] tree lhs, decl, should_gcov_name, should_gcov_type;

 /* We share one temporary variable declaration per function.  This
    gets re-set in tree_profiling.  */
 if (gcov_type_tmp_var == NULL_TREE)
   gcov_type_tmp_var = create_tmp_var (gcov_type_node, "PROF_edge_counter");
 ref = tree_coverage_counter_ref (GCOV_COUNTER_ARCS, edgeno);
 one = build_int_cst (gcov_type_node, 1);

[*] should_gcov_name = get_identifier("__should_gcov");
[*] should_gcov_type = build_function_type(gcov_type_node, NULL_TREE
/* no args */);

[*] decl = build_decl(FUNCTION_DECL, should_gcov_name, should_gcov_type);

[*] lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
[*] call = gimple_build_call (decl, 0);
[*] gimple_call_set_lhs (call, lhs);

  stmt1 = gimple_build_assign (gcov_type_tmp_var, ref);
  stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, gcov_type_tmp_var,
                                        gcov_type_tmp_var, lhs);
  stmt3 = gimple_build_assign (unshare_expr (ref), gcov_type_tmp_var);
[*]  gsi_insert_on_edge (e, call);
  gsi_insert_on_edge (e, stmt1);
  gsi_insert_on_edge (e, stmt2);
  gsi_insert_on_edge (e, stmt3);
}
When I compile a program using this gcc and -fprofile-arcs, it does
ask for the function __should_gcov. But when I use gcov to read the
gcda file after running the program, there is some format error and it
terminates stating buffer overflow. Hence, the format of the gcda file
is somehow corrupt.
Is there some other place I should modify because of my changes, like
the number of basic blocks etc? (I don't care about the branch
probability etc options -- I just want the line execution count) .
Thanks,
Hayawardh