summaryrefslogtreecommitdiff
path: root/gcc/tree-profile.c
diff options
context:
space:
mode:
authormarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-11 23:21:02 +0000
committermarxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-11 23:21:02 +0000
commit38fe12e377baa6c8dfe5845687e7ed3d1daf0769 (patch)
tree91cab9d80f43cc346699b11a23a3f3458b7ab15e /gcc/tree-profile.c
parent7ec6ec03e2dc34882d54168b08a50b482d640540 (diff)
downloadgcc-38fe12e377baa6c8dfe5845687e7ed3d1daf0769.tar.gz
Time profiler introduced.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204690 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-profile.c')
-rw-r--r--gcc/tree-profile.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index e98ea686fbc..43d5b923e1f 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -51,9 +51,10 @@ static GTY(()) tree tree_interval_profiler_fn;
static GTY(()) tree tree_pow2_profiler_fn;
static GTY(()) tree tree_one_value_profiler_fn;
static GTY(()) tree tree_indirect_call_profiler_fn;
+static GTY(()) tree tree_time_profiler_fn;
static GTY(()) tree tree_average_profiler_fn;
static GTY(()) tree tree_ior_profiler_fn;
-
+
static GTY(()) tree ic_void_ptr_var;
static GTY(()) tree ic_gcov_type_ptr_var;
@@ -63,7 +64,8 @@ static GTY(()) tree ptr_void;
/* Add code:
__thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
- __thread void* __gcov_indirect_call_callee; // actual callee address
+ __thread void* __gcov_indirect_call_callee; // actual callee address
+ __thread int __gcov_function_counter; // time profiler function counter
*/
static void
init_ic_make_global_vars (void)
@@ -145,6 +147,7 @@ gimple_init_edge_profiler (void)
tree gcov_type_ptr;
tree ic_profiler_fn_type;
tree average_profiler_fn_type;
+ tree time_profiler_fn_type;
if (!gcov_type_node)
{
@@ -222,6 +225,18 @@ gimple_init_edge_profiler (void)
= tree_cons (get_identifier ("leaf"), NULL,
DECL_ATTRIBUTES (tree_indirect_call_profiler_fn));
+ /* void (*) (gcov_type *, gcov_type, void *) */
+ time_profiler_fn_type
+ = build_function_type_list (void_type_node,
+ gcov_type_ptr, NULL_TREE);
+ tree_time_profiler_fn
+ = build_fn_decl ("__gcov_time_profiler",
+ time_profiler_fn_type);
+ TREE_NOTHROW (tree_time_profiler_fn) = 1;
+ DECL_ATTRIBUTES (tree_time_profiler_fn)
+ = tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (tree_time_profiler_fn));
+
/* void (*) (gcov_type *, gcov_type) */
average_profiler_fn_type
= build_function_type_list (void_type_node,
@@ -247,6 +262,7 @@ gimple_init_edge_profiler (void)
DECL_ASSEMBLER_NAME (tree_pow2_profiler_fn);
DECL_ASSEMBLER_NAME (tree_one_value_profiler_fn);
DECL_ASSEMBLER_NAME (tree_indirect_call_profiler_fn);
+ DECL_ASSEMBLER_NAME (tree_time_profiler_fn);
DECL_ASSEMBLER_NAME (tree_average_profiler_fn);
DECL_ASSEMBLER_NAME (tree_ior_profiler_fn);
}
@@ -455,6 +471,23 @@ gimple_gen_ic_func_profiler (void)
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
}
+/* Output instructions as GIMPLE tree at the beginning for each function.
+ TAG is the tag of the section for counters, BASE is offset of the
+ counter position and GSI is the iterator we place the counter. */
+
+void
+gimple_gen_time_profiler (unsigned tag, unsigned base,
+ gimple_stmt_iterator &gsi)
+{
+ tree ref_ptr = tree_coverage_counter_addr (tag, base);
+ gimple call;
+
+ ref_ptr = force_gimple_operand_gsi (&gsi, ref_ptr,
+ true, NULL_TREE, true, GSI_SAME_STMT);
+ call = gimple_build_call (tree_time_profiler_fn, 1, ref_ptr);
+ gsi_insert_before (&gsi, call, GSI_NEW_STMT);
+}
+
/* Output instructions as GIMPLE trees for code to find the most common value
of a difference between two evaluations of an expression.
VALUE is the expression whose value is profiled. TAG is the tag of the