mirror of git://gcc.gnu.org/git/gcc.git
coverage.c (get_coverage_counts): Use current_function_decl.
* coverage.c (get_coverage_counts): Use current_function_decl. * profile.c (read_thunk_profile): New function. (branch_prob): Add THUNK parameter. * tree-profile.c (tree_profiling): Handle thunks. * value-prof.c (init_node_map): Handle thunks. * value-prof.h (branch_prob): Upate prototype. (read_thunk_profile): Declare. * g++.dg/tree-prof/devirt.C: Update testcase. From-SVN: r267495
This commit is contained in:
parent
a554497024
commit
962e88a9f5
|
|
@ -1,3 +1,13 @@
|
||||||
|
2019-01-01 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
|
* coverage.c (get_coverage_counts): Use current_function_decl.
|
||||||
|
* profile.c (read_thunk_profile): New function.
|
||||||
|
(branch_prob): Add THUNK parameter.
|
||||||
|
* tree-profile.c (tree_profiling): Handle thunks.
|
||||||
|
* value-prof.c (init_node_map): Handle thunks.
|
||||||
|
* value-prof.h (branch_prob): Upate prototype.
|
||||||
|
(read_thunk_profile): Declare.
|
||||||
|
|
||||||
2019-01-01 Jakub Jelinek <jakub@redhat.com>
|
2019-01-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
Update copyright years.
|
Update copyright years.
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ get_coverage_counts (unsigned counter, unsigned cfg_checksum,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gcc_assert (coverage_node_map_initialized_p ());
|
gcc_assert (coverage_node_map_initialized_p ());
|
||||||
elt.ident = cgraph_node::get (cfun->decl)->profile_id;
|
elt.ident = cgraph_node::get (current_function_decl)->profile_id;
|
||||||
}
|
}
|
||||||
elt.ctr = counter;
|
elt.ctr = counter;
|
||||||
entry = counts_hash->find (&elt);
|
entry = counts_hash->find (&elt);
|
||||||
|
|
|
||||||
|
|
@ -963,6 +963,25 @@ compare_freqs (const void *p1, const void *p2)
|
||||||
return e2->dest->index - e1->dest->index;
|
return e2->dest->index - e1->dest->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only read execution count for thunks. */
|
||||||
|
|
||||||
|
void
|
||||||
|
read_thunk_profile (struct cgraph_node *node)
|
||||||
|
{
|
||||||
|
tree old = current_function_decl;
|
||||||
|
current_function_decl = node->decl;
|
||||||
|
gcov_type *counts = get_coverage_counts (GCOV_COUNTER_ARCS, 0, 0, 1);
|
||||||
|
if (counts)
|
||||||
|
{
|
||||||
|
node->callees->count = node->count
|
||||||
|
= profile_count::from_gcov_type (counts[0]);
|
||||||
|
free (counts);
|
||||||
|
}
|
||||||
|
current_function_decl = old;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Instrument and/or analyze program behavior based on program the CFG.
|
/* Instrument and/or analyze program behavior based on program the CFG.
|
||||||
|
|
||||||
This function creates a representation of the control flow graph (of
|
This function creates a representation of the control flow graph (of
|
||||||
|
|
@ -983,7 +1002,7 @@ compare_freqs (const void *p1, const void *p2)
|
||||||
Main entry point of this file. */
|
Main entry point of this file. */
|
||||||
|
|
||||||
void
|
void
|
||||||
branch_prob (void)
|
branch_prob (bool thunk)
|
||||||
{
|
{
|
||||||
basic_block bb;
|
basic_block bb;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
@ -1000,6 +1019,8 @@ branch_prob (void)
|
||||||
|
|
||||||
hash_set <location_triplet_hash> streamed_locations;
|
hash_set <location_triplet_hash> streamed_locations;
|
||||||
|
|
||||||
|
if (!thunk)
|
||||||
|
{
|
||||||
/* We can't handle cyclic regions constructed using abnormal edges.
|
/* We can't handle cyclic regions constructed using abnormal edges.
|
||||||
To avoid these we replace every source of abnormal edge by a fake
|
To avoid these we replace every source of abnormal edge by a fake
|
||||||
edge from entry node and every destination by fake edge to exit.
|
edge from entry node and every destination by fake edge to exit.
|
||||||
|
|
@ -1115,6 +1136,7 @@ branch_prob (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
el = create_edge_list ();
|
el = create_edge_list ();
|
||||||
num_edges = NUM_EDGES (el);
|
num_edges = NUM_EDGES (el);
|
||||||
|
|
@ -1143,7 +1165,18 @@ branch_prob (void)
|
||||||
on the spanning tree. We insert as many abnormal and critical edges
|
on the spanning tree. We insert as many abnormal and critical edges
|
||||||
as possible to minimize number of edge splits necessary. */
|
as possible to minimize number of edge splits necessary. */
|
||||||
|
|
||||||
|
if (!thunk)
|
||||||
find_spanning_tree (el);
|
find_spanning_tree (el);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
edge e;
|
||||||
|
edge_iterator ei;
|
||||||
|
/* Keep only edge from entry block to be instrumented. */
|
||||||
|
FOR_EACH_BB_FN (bb, cfun)
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
|
EDGE_INFO (e)->ignore = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Fake edges that are not on the tree will not be instrumented, so
|
/* Fake edges that are not on the tree will not be instrumented, so
|
||||||
mark them ignored. */
|
mark them ignored. */
|
||||||
|
|
@ -1183,8 +1216,17 @@ branch_prob (void)
|
||||||
the checksum in only once place, since it depends on the shape
|
the checksum in only once place, since it depends on the shape
|
||||||
of the control flow which can change during
|
of the control flow which can change during
|
||||||
various transformations. */
|
various transformations. */
|
||||||
|
if (thunk)
|
||||||
|
{
|
||||||
|
/* At stream in time we do not have CFG, so we can not do checksums. */
|
||||||
|
cfg_checksum = 0;
|
||||||
|
lineno_checksum = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
cfg_checksum = coverage_compute_cfg_checksum (cfun);
|
cfg_checksum = coverage_compute_cfg_checksum (cfun);
|
||||||
lineno_checksum = coverage_compute_lineno_checksum ();
|
lineno_checksum = coverage_compute_lineno_checksum ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Write the data from which gcov can reconstruct the basic block
|
/* Write the data from which gcov can reconstruct the basic block
|
||||||
graph and function line numbers (the gcno file). */
|
graph and function line numbers (the gcno file). */
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
2019-01-01 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
|
* g++.dg/tree-prof/devirt.C: Update testcase.
|
||||||
|
|
||||||
2019-01-01 Jakub Jelinek <jakub@redhat.com>
|
2019-01-01 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
Update copyright years.
|
Update copyright years.
|
||||||
|
|
|
||||||
|
|
@ -119,5 +119,5 @@ main ()
|
||||||
__builtin_abort ();
|
__builtin_abort ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* { dg-final-use-not-autofdo { scan-tree-dump-times "folding virtual function call to virtual unsigned int mozPersonalDictionary::_ZThn16" 3 "dom3" } } */
|
/* { dg-final-use-not-autofdo { scan-tree-dump-times "folding virtual function call to virtual unsigned int mozPersonalDictionary::_ZThn16" 1 "dom3" } } */
|
||||||
/* { dg-final-use-not-autofdo { scan-tree-dump-times "folding virtual function call to virtual unsigned int mozPersonalDictionary::AddRef" 3 "dom3" } } */
|
/* { dg-final-use-not-autofdo { scan-tree-dump-times "folding virtual function call to virtual unsigned int mozPersonalDictionary::AddRef" 1 "dom3" } } */
|
||||||
|
|
|
||||||
|
|
@ -739,7 +739,8 @@ tree_profiling (void)
|
||||||
|
|
||||||
FOR_EACH_DEFINED_FUNCTION (node)
|
FOR_EACH_DEFINED_FUNCTION (node)
|
||||||
{
|
{
|
||||||
if (!gimple_has_body_p (node->decl))
|
bool thunk = false;
|
||||||
|
if (!gimple_has_body_p (node->decl) && !node->thunk.thunk_p)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Don't profile functions produced for builtin stuff. */
|
/* Don't profile functions produced for builtin stuff. */
|
||||||
|
|
@ -760,22 +761,43 @@ tree_profiling (void)
|
||||||
if (!include_source_file_for_profile (file))
|
if (!include_source_file_for_profile (file))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (node->thunk.thunk_p)
|
||||||
|
{
|
||||||
|
/* We can not expand variadic thunks to Gimple. */
|
||||||
|
if (stdarg_p (TREE_TYPE (node->decl)))
|
||||||
|
continue;
|
||||||
|
thunk = true;
|
||||||
|
/* When generate profile, expand thunk to gimple so it can be
|
||||||
|
instrumented same way as other functions. */
|
||||||
|
if (profile_arc_flag)
|
||||||
|
node->expand_thunk (false, true);
|
||||||
|
/* Read cgraph profile but keep function as thunk at profile-use
|
||||||
|
time. */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
read_thunk_profile (node);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
|
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
|
||||||
|
|
||||||
if (dump_file)
|
if (dump_file)
|
||||||
dump_function_header (dump_file, cfun->decl, dump_flags);
|
dump_function_header (dump_file, cfun->decl, dump_flags);
|
||||||
|
|
||||||
/* Local pure-const may imply need to fixup the cfg. */
|
/* Local pure-const may imply need to fixup the cfg. */
|
||||||
if (execute_fixup_cfg () & TODO_cleanup_cfg)
|
if (gimple_has_body_p (node->decl)
|
||||||
|
&& (execute_fixup_cfg () & TODO_cleanup_cfg))
|
||||||
cleanup_tree_cfg ();
|
cleanup_tree_cfg ();
|
||||||
|
|
||||||
branch_prob ();
|
branch_prob (thunk);
|
||||||
|
|
||||||
if (! flag_branch_probabilities
|
if (! flag_branch_probabilities
|
||||||
&& flag_profile_values)
|
&& flag_profile_values)
|
||||||
gimple_gen_ic_func_profiler ();
|
gimple_gen_ic_func_profiler ();
|
||||||
|
|
||||||
if (flag_branch_probabilities
|
if (flag_branch_probabilities
|
||||||
|
&& !thunk
|
||||||
&& flag_profile_values
|
&& flag_profile_values
|
||||||
&& flag_value_profile_transformations)
|
&& flag_value_profile_transformations)
|
||||||
gimple_value_profile_transformations ();
|
gimple_value_profile_transformations ();
|
||||||
|
|
|
||||||
|
|
@ -1188,7 +1188,7 @@ init_node_map (bool local)
|
||||||
cgraph_node_map = new hash_map<profile_id_hash, cgraph_node *>;
|
cgraph_node_map = new hash_map<profile_id_hash, cgraph_node *>;
|
||||||
|
|
||||||
FOR_EACH_DEFINED_FUNCTION (n)
|
FOR_EACH_DEFINED_FUNCTION (n)
|
||||||
if (n->has_gimple_body_p ())
|
if (n->has_gimple_body_p () || n->thunk.thunk_p)
|
||||||
{
|
{
|
||||||
cgraph_node **val;
|
cgraph_node **val;
|
||||||
if (local)
|
if (local)
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,8 @@ extern struct cgraph_node* find_func_by_profile_id (int func_id);
|
||||||
|
|
||||||
/* In profile.c. */
|
/* In profile.c. */
|
||||||
extern void init_branch_prob (void);
|
extern void init_branch_prob (void);
|
||||||
extern void branch_prob (void);
|
extern void branch_prob (bool);
|
||||||
|
extern void read_thunk_profile (struct cgraph_node *);
|
||||||
extern void end_branch_prob (void);
|
extern void end_branch_prob (void);
|
||||||
|
|
||||||
#endif /* GCC_VALUE_PROF_H */
|
#endif /* GCC_VALUE_PROF_H */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue