Commit 962e88a9 by Jan Hubicka Committed by Jan Hubicka

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
parent a5544970
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>
Update copyright years.
......
......@@ -329,7 +329,7 @@ get_coverage_counts (unsigned counter, unsigned cfg_checksum,
else
{
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;
entry = counts_hash->find (&elt);
......
......@@ -963,6 +963,25 @@ compare_freqs (const void *p1, const void *p2)
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.
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. */
void
branch_prob (void)
branch_prob (bool thunk)
{
basic_block bb;
unsigned i;
......@@ -1000,6 +1019,8 @@ branch_prob (void)
hash_set <location_triplet_hash> streamed_locations;
if (!thunk)
{
/* We can't handle cyclic regions constructed using abnormal edges.
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.
......@@ -1115,6 +1136,7 @@ branch_prob (void)
}
}
}
}
el = create_edge_list ();
num_edges = NUM_EDGES (el);
......@@ -1143,7 +1165,18 @@ branch_prob (void)
on the spanning tree. We insert as many abnormal and critical edges
as possible to minimize number of edge splits necessary. */
if (!thunk)
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
mark them ignored. */
......@@ -1183,8 +1216,17 @@ branch_prob (void)
the checksum in only once place, since it depends on the shape
of the control flow which can change during
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);
lineno_checksum = coverage_compute_lineno_checksum ();
}
/* Write the data from which gcov can reconstruct the basic block
graph and function line numbers (the gcno file). */
......
2019-01-01 Jan Hubicka <hubicka@ucw.cz>
* g++.dg/tree-prof/devirt.C: Update testcase.
2019-01-01 Jakub Jelinek <jakub@redhat.com>
Update copyright years.
......
......@@ -119,5 +119,5 @@ main ()
__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::AddRef" 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" 1 "dom3" } } */
......@@ -739,7 +739,8 @@ tree_profiling (void)
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;
/* Don't profile functions produced for builtin stuff. */
......@@ -760,22 +761,43 @@ tree_profiling (void)
if (!include_source_file_for_profile (file))
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));
if (dump_file)
dump_function_header (dump_file, cfun->decl, dump_flags);
/* 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 ();
branch_prob ();
branch_prob (thunk);
if (! flag_branch_probabilities
&& flag_profile_values)
gimple_gen_ic_func_profiler ();
if (flag_branch_probabilities
&& !thunk
&& flag_profile_values
&& flag_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 *>;
FOR_EACH_DEFINED_FUNCTION (n)
if (n->has_gimple_body_p ())
if (n->has_gimple_body_p () || n->thunk.thunk_p)
{
cgraph_node **val;
if (local)
......
......@@ -112,7 +112,8 @@ extern struct cgraph_node* find_func_by_profile_id (int func_id);
/* In profile.c. */
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);
#endif /* GCC_VALUE_PROF_H */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment