mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 19:11:21 +08:00
Make direct emission of time profiler counter
* libgcov-profiler.c (__gcov_time_profiler): Remove. (__gcov_time_profiler_atomic): Likewise. * profile.c (instrument_values): Fix coding style. (branch_prob): Use renamed function. * tree-profile.c (init_ic_make_global_vars): Likewise. (gimple_init_edge_profiler): Rename to gimple_init_gcov_profiler. tree_time_profiler_counter variable declaration. (gimple_gen_time_profiler): Rewrite to do a direct gimple code emission. * value-prof.h: Remove an argument. * gcc.dg/no_profile_instrument_function-attr-1.c: Update scanned output. * gcc.dg/tree-prof/time-profiler-3.c: New test. From-SVN: r241821
This commit is contained in:
parent
5de3e2d862
commit
7d29f8e3dc
@ -1,3 +1,15 @@
|
||||
2016-11-03 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* profile.c (instrument_values): Fix coding style.
|
||||
(branch_prob): Use renamed function.
|
||||
* tree-profile.c (init_ic_make_global_vars): Likewise.
|
||||
(gimple_init_edge_profiler): Rename to
|
||||
gimple_init_gcov_profiler.
|
||||
tree_time_profiler_counter variable declaration.
|
||||
(gimple_gen_time_profiler): Rewrite to do a direct gimple code
|
||||
emission.
|
||||
* value-prof.h: Remove an argument.
|
||||
|
||||
2016-11-03 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_xcoff_declare_object_name): Use
|
||||
|
@ -192,15 +192,9 @@ instrument_values (histogram_values values)
|
||||
gimple_gen_ior_profiler (hist, t, 0);
|
||||
break;
|
||||
|
||||
case HIST_TYPE_TIME_PROFILE:
|
||||
{
|
||||
basic_block bb =
|
||||
split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
|
||||
gimple_stmt_iterator gsi = gsi_start_bb (bb);
|
||||
|
||||
gimple_gen_time_profiler (t, 0, gsi);
|
||||
break;
|
||||
}
|
||||
case HIST_TYPE_TIME_PROFILE:
|
||||
gimple_gen_time_profiler (t, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
@ -1305,7 +1299,7 @@ branch_prob (void)
|
||||
{
|
||||
unsigned n_instrumented;
|
||||
|
||||
gimple_init_edge_profiler ();
|
||||
gimple_init_gcov_profiler ();
|
||||
|
||||
n_instrumented = instrument_edges (el);
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2016-11-03 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* gcc.dg/no_profile_instrument_function-attr-1.c: Update scanned
|
||||
output.
|
||||
* gcc.dg/tree-prof/time-profiler-3.c: New test.
|
||||
|
||||
2016-11-03 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
PR libgcc/78067
|
||||
|
@ -19,5 +19,5 @@ int main ()
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__gcov0\\.main.* = PROF_edge_counter" 1 "optimized"} } */
|
||||
/* { dg-final { scan-tree-dump-times "__gcov_indirect_call_profiler_v2" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__gcov_time_profiler" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__gcov_time_profiler_counter = " 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__gcov_init" 1 "optimized" } } */
|
||||
|
22
gcc/testsuite/gcc.dg/tree-prof/time-profiler-3.c
Normal file
22
gcc/testsuite/gcc.dg/tree-prof/time-profiler-3.c
Normal file
@ -0,0 +1,22 @@
|
||||
/* { dg-options "-O2 -fdump-ipa-profile -fprofile-update=atomic" } */
|
||||
/* { dg-require-effective-target profile_update_atomic } */
|
||||
|
||||
__attribute__ ((noinline))
|
||||
int foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__ ((noinline))
|
||||
int bar()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
return foo ();
|
||||
}
|
||||
/* { dg-final-use-not-autofdo { scan-ipa-dump-times "Read tp_first_run: 0" 1 "profile"} } */
|
||||
/* { dg-final-use-not-autofdo { scan-ipa-dump-times "Read tp_first_run: 1" 1 "profile"} } */
|
||||
/* { dg-final-use-not-autofdo { scan-ipa-dump-times "Read tp_first_run: 2" 1 "profile"} } */
|
@ -56,9 +56,9 @@ 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 tree_time_profiler_counter;
|
||||
|
||||
|
||||
static GTY(()) tree ic_void_ptr_var;
|
||||
@ -75,7 +75,7 @@ static GTY(()) tree ptr_void;
|
||||
static void
|
||||
init_ic_make_global_vars (void)
|
||||
{
|
||||
tree gcov_type_ptr;
|
||||
tree gcov_type_ptr;
|
||||
|
||||
ptr_void = build_pointer_type (void_type_node);
|
||||
|
||||
@ -119,7 +119,7 @@ init_ic_make_global_vars (void)
|
||||
/* Create the type and function decls for the interface with gcov. */
|
||||
|
||||
void
|
||||
gimple_init_edge_profiler (void)
|
||||
gimple_init_gcov_profiler (void)
|
||||
{
|
||||
tree interval_profiler_fn_type;
|
||||
tree pow2_profiler_fn_type;
|
||||
@ -127,7 +127,6 @@ gimple_init_edge_profiler (void)
|
||||
tree gcov_type_ptr;
|
||||
tree ic_profiler_fn_type;
|
||||
tree average_profiler_fn_type;
|
||||
tree time_profiler_fn_type;
|
||||
const char *profiler_fn_name;
|
||||
const char *fn_name;
|
||||
|
||||
@ -201,17 +200,17 @@ 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);
|
||||
fn_name = concat ("__gcov_time_profiler", fn_suffix, NULL);
|
||||
tree_time_profiler_fn = build_fn_decl (fn_name, time_profiler_fn_type);
|
||||
free (CONST_CAST (char *, fn_name));
|
||||
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));
|
||||
tree_time_profiler_counter
|
||||
= build_decl (UNKNOWN_LOCATION, VAR_DECL,
|
||||
get_identifier ("__gcov_time_profiler_counter"),
|
||||
get_gcov_type ());
|
||||
TREE_PUBLIC (tree_time_profiler_counter) = 1;
|
||||
DECL_EXTERNAL (tree_time_profiler_counter) = 1;
|
||||
TREE_STATIC (tree_time_profiler_counter) = 1;
|
||||
DECL_ARTIFICIAL (tree_time_profiler_counter) = 1;
|
||||
DECL_INITIAL (tree_time_profiler_counter) = NULL;
|
||||
|
||||
varpool_node::finalize_decl (tree_time_profiler_counter);
|
||||
|
||||
/* void (*) (gcov_type *, gcov_type) */
|
||||
average_profiler_fn_type
|
||||
@ -239,7 +238,6 @@ 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);
|
||||
}
|
||||
@ -426,7 +424,7 @@ gimple_gen_ic_func_profiler (void)
|
||||
if (c_node->only_called_directly_p ())
|
||||
return;
|
||||
|
||||
gimple_init_edge_profiler ();
|
||||
gimple_init_gcov_profiler ();
|
||||
|
||||
/* Insert code:
|
||||
|
||||
@ -460,16 +458,74 @@ gimple_gen_ic_func_profiler (void)
|
||||
counter position and GSI is the iterator we place the counter. */
|
||||
|
||||
void
|
||||
gimple_gen_time_profiler (unsigned tag, unsigned base,
|
||||
gimple_stmt_iterator &gsi)
|
||||
gimple_gen_time_profiler (unsigned tag, unsigned base)
|
||||
{
|
||||
tree ref_ptr = tree_coverage_counter_addr (tag, base);
|
||||
gcall *call;
|
||||
tree type = get_gcov_type ();
|
||||
basic_block cond_bb
|
||||
= split_edge (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
|
||||
|
||||
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);
|
||||
basic_block update_bb = split_edge (single_succ_edge (cond_bb));
|
||||
|
||||
edge true_edge = single_succ_edge (cond_bb);
|
||||
true_edge->flags = EDGE_TRUE_VALUE;
|
||||
true_edge->probability = PROB_VERY_UNLIKELY;
|
||||
edge e
|
||||
= make_edge (cond_bb, single_succ_edge (update_bb)->dest, EDGE_FALSE_VALUE);
|
||||
e->probability = REG_BR_PROB_BASE - true_edge->probability;
|
||||
|
||||
gimple_stmt_iterator gsi = gsi_start_bb (cond_bb);
|
||||
tree original_ref = tree_coverage_counter_ref (tag, base);
|
||||
tree ref = force_gimple_operand_gsi (&gsi, original_ref, true, NULL_TREE,
|
||||
true, GSI_SAME_STMT);
|
||||
tree one = build_int_cst (type, 1);
|
||||
|
||||
/* Emit: if (counters[0] != 0). */
|
||||
gcond *cond = gimple_build_cond (EQ_EXPR, ref, build_int_cst (type, 0),
|
||||
NULL, NULL);
|
||||
gsi_insert_before (&gsi, cond, GSI_NEW_STMT);
|
||||
|
||||
gsi = gsi_start_bb (update_bb);
|
||||
|
||||
/* Emit: counters[0] = ++__gcov_time_profiler_counter. */
|
||||
if (flag_profile_update == PROFILE_UPDATE_ATOMIC)
|
||||
{
|
||||
tree ptr = make_temp_ssa_name (type, NULL, "time_profiler_counter_ptr");
|
||||
tree addr = build1 (ADDR_EXPR, build_pointer_type (type),
|
||||
tree_time_profiler_counter);
|
||||
gassign *assign = gimple_build_assign (ptr, NOP_EXPR, addr);
|
||||
gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
|
||||
tree f = builtin_decl_explicit (LONG_LONG_TYPE_SIZE > 32
|
||||
? BUILT_IN_ATOMIC_ADD_FETCH_8:
|
||||
BUILT_IN_ATOMIC_ADD_FETCH_4);
|
||||
gcall *stmt = gimple_build_call (f, 3, ptr, one,
|
||||
build_int_cst (integer_type_node,
|
||||
MEMMODEL_RELAXED));
|
||||
tree result_type = TREE_TYPE (TREE_TYPE (f));
|
||||
tree tmp = make_temp_ssa_name (result_type, NULL, "time_profile");
|
||||
gimple_set_lhs (stmt, tmp);
|
||||
gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
|
||||
tmp = make_temp_ssa_name (type, NULL, "time_profile");
|
||||
assign = gimple_build_assign (tmp, NOP_EXPR,
|
||||
gimple_call_lhs (stmt));
|
||||
gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
|
||||
assign = gimple_build_assign (original_ref, tmp);
|
||||
gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree tmp = make_temp_ssa_name (type, NULL, "time_profile");
|
||||
gassign *assign = gimple_build_assign (tmp, tree_time_profiler_counter);
|
||||
gsi_insert_before (&gsi, assign, GSI_NEW_STMT);
|
||||
|
||||
tmp = make_temp_ssa_name (type, NULL, "time_profile");
|
||||
assign = gimple_build_assign (tmp, PLUS_EXPR, gimple_assign_lhs (assign),
|
||||
one);
|
||||
gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
|
||||
assign = gimple_build_assign (original_ref, tmp);
|
||||
gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
|
||||
assign = gimple_build_assign (tree_time_profiler_counter, tmp);
|
||||
gsi_insert_after (&gsi, assign, GSI_NEW_STMT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output instructions as GIMPLE trees to increment the average histogram
|
||||
|
@ -96,15 +96,14 @@ bool check_ic_target (gcall *, struct cgraph_node *);
|
||||
|
||||
|
||||
/* In tree-profile.c. */
|
||||
extern void gimple_init_edge_profiler (void);
|
||||
extern void gimple_init_gcov_profiler (void);
|
||||
extern void gimple_gen_edge_profiler (int, edge);
|
||||
extern void gimple_gen_interval_profiler (histogram_value, unsigned, unsigned);
|
||||
extern void gimple_gen_pow2_profiler (histogram_value, unsigned, unsigned);
|
||||
extern void gimple_gen_one_value_profiler (histogram_value, unsigned, unsigned);
|
||||
extern void gimple_gen_ic_profiler (histogram_value, unsigned, unsigned);
|
||||
extern void gimple_gen_ic_func_profiler (void);
|
||||
extern void gimple_gen_time_profiler (unsigned, unsigned,
|
||||
gimple_stmt_iterator &);
|
||||
extern void gimple_gen_time_profiler (unsigned, unsigned);
|
||||
extern void gimple_gen_average_profiler (histogram_value, unsigned, unsigned);
|
||||
extern void gimple_gen_ior_profiler (histogram_value, unsigned, unsigned);
|
||||
extern void stream_out_histogram_value (struct output_block *, histogram_value);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2016-11-03 Martin Liska <mliska@suse.cz>
|
||||
|
||||
* libgcov-profiler.c (__gcov_time_profiler): Remove.
|
||||
(__gcov_time_profiler_atomic): Likewise.
|
||||
|
||||
2016-11-03 Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||
|
||||
PR libgcc/78067
|
||||
|
@ -342,30 +342,9 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
|
||||
#ifdef L_gcov_time_profiler
|
||||
|
||||
/* Counter for first visit of each function. */
|
||||
static gcov_type function_counter;
|
||||
gcov_type __gcov_time_profiler_counter ATTRIBUTE_HIDDEN;
|
||||
|
||||
/* Sets corresponding COUNTERS if there is no value. */
|
||||
|
||||
void
|
||||
__gcov_time_profiler (gcov_type* counters)
|
||||
{
|
||||
if (!counters[0])
|
||||
counters[0] = ++function_counter;
|
||||
}
|
||||
|
||||
#if GCOV_SUPPORTS_ATOMIC
|
||||
/* Sets corresponding COUNTERS if there is no value.
|
||||
Function is thread-safe. */
|
||||
|
||||
void
|
||||
__gcov_time_profiler_atomic (gcov_type* counters)
|
||||
{
|
||||
if (!counters[0])
|
||||
counters[0] = __atomic_add_fetch (&function_counter, 1, __ATOMIC_RELAXED);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef L_gcov_average_profiler
|
||||
/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
|
||||
|
Loading…
x
Reference in New Issue
Block a user