Commit 2b5f0895 by Xinliang David Li Committed by Xinliang David Li

add dbgcnt support for devirt

From-SVN: r210657
parent 9c5f6203
2014-05-20 Xinliang David Li <davidxl@google.com>
* cgraphunit.c (walk_polymorphic_call_targets): Add
dbgcnt and fopt-info support.
* ipa-prop.c (ipa_make_edge_direct_to_target): Ditto.
* ipa-devirt.c (ipa_devirt): Ditto.
* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
Ditto.
* ipa.c (walk_polymorphic_call_targets): Ditto.
* gimple-fold.c (fold_gimple_assign): Ditto.
(gimple_fold_call): Ditto.
* dbgcnt.def: New counter.
2014-05-20 DJ Delorie <dj@redhat.com> 2014-05-20 DJ Delorie <dj@redhat.com>
* config/msp430/msp430.md (split): Don't allow subregs when * config/msp430/msp430.md (split): Don't allow subregs when
......
...@@ -210,6 +210,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -210,6 +210,7 @@ along with GCC; see the file COPYING3. If not see
#include "pass_manager.h" #include "pass_manager.h"
#include "tree-nested.h" #include "tree-nested.h"
#include "gimplify.h" #include "gimplify.h"
#include "dbgcnt.h"
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a /* Queue of cgraph nodes scheduled to be added into cgraph. This is a
secondary queue used during optimization to accommodate passes that secondary queue used during optimization to accommodate passes that
...@@ -886,7 +887,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets, ...@@ -886,7 +887,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
make the edge direct. */ make the edge direct. */
if (final) if (final)
{ {
if (targets.length () <= 1) if (targets.length () <= 1 && dbg_cnt (devirt))
{ {
cgraph_node *target; cgraph_node *target;
if (targets.length () == 1) if (targets.length () == 1)
...@@ -903,6 +904,14 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets, ...@@ -903,6 +904,14 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
edge->call_stmt, 0, edge->call_stmt, 0,
TDF_SLIM); TDF_SLIM);
} }
if (dump_enabled_p ())
{
location_t locus = gimple_location (edge->call_stmt);
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
"devirtualizing call in %s to %s\n",
edge->caller->name (), target->name ());
}
cgraph_make_edge_direct (edge, target); cgraph_make_edge_direct (edge, target);
cgraph_redirect_edge_call_stmt_to_callee (edge); cgraph_redirect_edge_call_stmt_to_callee (edge);
if (cgraph_dump_file) if (cgraph_dump_file)
......
...@@ -150,6 +150,7 @@ DEBUG_COUNTER (dce) ...@@ -150,6 +150,7 @@ DEBUG_COUNTER (dce)
DEBUG_COUNTER (dce_fast) DEBUG_COUNTER (dce_fast)
DEBUG_COUNTER (dce_ud) DEBUG_COUNTER (dce_ud)
DEBUG_COUNTER (delete_trivial_dead) DEBUG_COUNTER (delete_trivial_dead)
DEBUG_COUNTER (devirt)
DEBUG_COUNTER (df_byte_scan) DEBUG_COUNTER (df_byte_scan)
DEBUG_COUNTER (dse) DEBUG_COUNTER (dse)
DEBUG_COUNTER (dse1) DEBUG_COUNTER (dse1)
......
...@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-address.h" #include "tree-ssa-address.h"
#include "langhooks.h" #include "langhooks.h"
#include "gimplify-me.h" #include "gimplify-me.h"
#include "dbgcnt.h"
/* Return true when DECL can be referenced from current unit. /* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from. FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
...@@ -386,13 +387,24 @@ fold_gimple_assign (gimple_stmt_iterator *si) ...@@ -386,13 +387,24 @@ fold_gimple_assign (gimple_stmt_iterator *si)
bool final; bool final;
vec <cgraph_node *>targets vec <cgraph_node *>targets
= possible_polymorphic_call_targets (val, &final); = possible_polymorphic_call_targets (val, &final);
if (final && targets.length () <= 1) if (final && targets.length () <= 1 && dbg_cnt (devirt))
{ {
tree fndecl; tree fndecl;
if (targets.length () == 1) if (targets.length () == 1)
fndecl = targets[0]->decl; fndecl = targets[0]->decl;
else else
fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE); fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
if (dump_enabled_p ())
{
location_t loc = gimple_location (stmt);
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
"resolving virtual function address "
"reference to function %s\n",
targets.length () == 1
? targets[0]->name ()
: "__builtin_unreachable");
}
val = fold_convert (TREE_TYPE (val), fndecl); val = fold_convert (TREE_TYPE (val), fndecl);
STRIP_USELESS_TYPE_CONVERSION (val); STRIP_USELESS_TYPE_CONVERSION (val);
return val; return val;
...@@ -1124,9 +1136,18 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) ...@@ -1124,9 +1136,18 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
bool final; bool final;
vec <cgraph_node *>targets vec <cgraph_node *>targets
= possible_polymorphic_call_targets (callee, &final); = possible_polymorphic_call_targets (callee, &final);
if (final && targets.length () <= 1) if (final && targets.length () <= 1 && dbg_cnt (devirt))
{ {
tree lhs = gimple_call_lhs (stmt); tree lhs = gimple_call_lhs (stmt);
if (dump_enabled_p ())
{
location_t loc = gimple_location (stmt);
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
"folding virtual function call to %s\n",
targets.length () == 1
? targets[0]->name ()
: "__builtin_unreachable");
}
if (targets.length () == 1) if (targets.length () == 1)
{ {
gimple_call_set_fndecl (stmt, targets[0]->decl); gimple_call_set_fndecl (stmt, targets[0]->decl);
......
...@@ -129,6 +129,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -129,6 +129,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h" #include "diagnostic.h"
#include "tree-dfa.h" #include "tree-dfa.h"
#include "demangle.h" #include "demangle.h"
#include "dbgcnt.h"
static bool odr_violation_reported = false; static bool odr_violation_reported = false;
...@@ -2067,14 +2068,17 @@ ipa_devirt (void) ...@@ -2067,14 +2068,17 @@ ipa_devirt (void)
noverwritable++; noverwritable++;
continue; continue;
} }
else else if (dbg_cnt (devirt))
{ {
if (dump_file) if (dump_enabled_p ())
fprintf (dump_file, {
"Speculatively devirtualizing call in %s/%i to %s/%i\n\n", location_t locus = gimple_location (e->call_stmt);
n->name (), n->order, dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
likely_target->name (), "speculatively devirtualizing call in %s/%i to %s/%i\n",
likely_target->order); n->name (), n->order,
likely_target->name (),
likely_target->order);
}
if (!symtab_can_be_discarded (likely_target)) if (!symtab_can_be_discarded (likely_target))
{ {
cgraph_node *alias; cgraph_node *alias;
......
...@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-utils.h" #include "ipa-utils.h"
#include "stringpool.h" #include "stringpool.h"
#include "tree-ssanames.h" #include "tree-ssanames.h"
#include "dbgcnt.h"
/* Intermediate information about a parameter that is only useful during the /* Intermediate information about a parameter that is only useful during the
run of ipa_analyze_node and is not kept afterwards. */ run of ipa_analyze_node and is not kept afterwards. */
...@@ -2490,10 +2491,15 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target) ...@@ -2490,10 +2491,15 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
/* Member pointer call that goes through a VMT lookup. */ /* Member pointer call that goes through a VMT lookup. */
return NULL; return NULL;
if (dump_file) if (dump_enabled_p ())
fprintf (dump_file, "ipa-prop: Discovered direct call to non-function" {
" in %s/%i, making it unreachable.\n", location_t loc = gimple_location (ie->call_stmt);
ie->caller->name (), ie->caller->order); dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
"discovered direct call to non-function in %s/%i, "
"making it __builtin_unreachable\n",
ie->caller->name (),
ie->caller->order);
}
target = builtin_decl_implicit (BUILT_IN_UNREACHABLE); target = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
callee = cgraph_get_create_node (target); callee = cgraph_get_create_node (target);
unreachable = true; unreachable = true;
...@@ -2527,6 +2533,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target) ...@@ -2527,6 +2533,10 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
} }
callee = cgraph_get_create_node (target); callee = cgraph_get_create_node (target);
} }
if (!dbg_cnt (devirt))
return NULL;
ipa_check_create_node_params (); ipa_check_create_node_params ();
/* We can not make edges to inline clones. It is bug that someone removed /* We can not make edges to inline clones. It is bug that someone removed
...@@ -2547,6 +2557,13 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target) ...@@ -2547,6 +2557,13 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
else else
fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid); fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
} }
if (dump_enabled_p ())
{
location_t loc = gimple_location (ie->call_stmt);
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
"converting indirect call in %s to direct call to %s\n",
ie->caller->name (), callee->name ());
}
ie = cgraph_make_edge_direct (ie, callee); ie = cgraph_make_edge_direct (ie, callee);
es = inline_edge_summary (ie); es = inline_edge_summary (ie);
es->call_stmt_size -= (eni_size_weights.indirect_call_cost es->call_stmt_size -= (eni_size_weights.indirect_call_cost
......
...@@ -37,6 +37,10 @@ along with GCC; see the file COPYING3. If not see ...@@ -37,6 +37,10 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h" #include "tree-inline.h"
#include "profile.h" #include "profile.h"
#include "params.h" #include "params.h"
#include "internal-fn.h"
#include "tree-ssa-alias.h"
#include "gimple.h"
#include "dbgcnt.h"
/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */ /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
...@@ -213,7 +217,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets, ...@@ -213,7 +217,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
make the edge direct. */ make the edge direct. */
if (final) if (final)
{ {
if (targets.length () <= 1) if (targets.length () <= 1 && dbg_cnt (devirt))
{ {
cgraph_node *target, *node = edge->caller; cgraph_node *target, *node = edge->caller;
if (targets.length () == 1) if (targets.length () == 1)
...@@ -222,12 +226,15 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets, ...@@ -222,12 +226,15 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
target = cgraph_get_create_node target = cgraph_get_create_node
(builtin_decl_implicit (BUILT_IN_UNREACHABLE)); (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
if (dump_file) if (dump_enabled_p ())
fprintf (dump_file, {
"Devirtualizing call in %s/%i to %s/%i\n", location_t locus = gimple_location (edge->call_stmt);
edge->caller->name (), dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
edge->caller->order, "devirtualizing call in %s/%i to %s/%i\n",
target->name (), target->order); edge->caller->name (), edge->caller->order,
target->name (),
target->order);
}
edge = cgraph_make_edge_direct (edge, target); edge = cgraph_make_edge_direct (edge, target);
if (inline_summary_vec) if (inline_summary_vec)
inline_update_overall_summary (node); inline_update_overall_summary (node);
......
...@@ -4365,18 +4365,19 @@ eliminate_dom_walker::before_dom_children (basic_block b) ...@@ -4365,18 +4365,19 @@ eliminate_dom_walker::before_dom_children (basic_block b)
continue; continue;
if (gimple_call_addr_fndecl (fn) != NULL_TREE if (gimple_call_addr_fndecl (fn) != NULL_TREE
&& useless_type_conversion_p (TREE_TYPE (orig_fn), && useless_type_conversion_p (TREE_TYPE (orig_fn),
TREE_TYPE (fn))) TREE_TYPE (fn))
&& dbg_cnt (devirt))
{ {
bool can_make_abnormal_goto bool can_make_abnormal_goto
= stmt_can_make_abnormal_goto (stmt); = stmt_can_make_abnormal_goto (stmt);
bool was_noreturn = gimple_call_noreturn_p (stmt); bool was_noreturn = gimple_call_noreturn_p (stmt);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_enabled_p ())
{ {
fprintf (dump_file, "Replacing call target with "); location_t loc = gimple_location (stmt);
print_generic_expr (dump_file, fn, 0); dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
fprintf (dump_file, " in "); "converting indirect call to function %s\n",
print_gimple_stmt (dump_file, stmt, 0, 0); cgraph_get_node (gimple_call_addr_fndecl (fn))->name ());
} }
gimple_call_set_fn (stmt, fn); gimple_call_set_fn (stmt, fn);
......
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