Sorry about it. Here is the patch. There is one remaining case where
cgraph_dump_file and dump_enable_p are checked separately --
cgraph_dump_file is set up differently from 'dump_file'.
David
On Mon, May 19, 2014 at 2:21 AM, Richard Biener
<[email protected]> wrote:
> On Fri, May 16, 2014 at 11:19 PM, Xinliang David Li <[email protected]>
> wrote:
>> Modified the patch according to yours and Richard's feedback. PTAL.
>
> ENOPATCH.
>
> Btw, I don't see any issue with leaking node order to opt-report.
>
> Richard.
>
>> thanks,
>>
>> David
>>
>> On Fri, May 16, 2014 at 9:03 AM, Jan Hubicka <[email protected]> wrote:
>>>> Hi, debugging runtime bugs due to devirtualization can be hard for
>>>> very large C++ programs with complicated class hierarchy. This patch
>>>> adds the support to report this high level transformation via
>>>> -fopt-info (not hidden inside dump file) and the ability the do binary
>>>> search with cutoff.
>>>>
>>>> Ok for trunk after build and test?
>>>
>>> Seems resonable to me.
>>>>
>>>> thanks,
>>>>
>>>> David
>>>
>>>> Index: ChangeLog
>>>> ===================================================================
>>>> --- ChangeLog (revision 210479)
>>>> +++ ChangeLog (working copy)
>>>> @@ -1,3 +1,18 @@
>>>> +2014-05-15 Xinliang David Li <[email protected]>
>>>> +
>>>> + * cgraphunit.c (walk_polymorphic_call_targets): Add
>>>> + dbgcnt and fopt-info support.
>>>> + 2014-05-15 Xinliang David Li <[email protected]>
>>>> +
>>>> + * 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.
>>>> + * ipa.c (walk_polymorphic_call_targets): Ditto.
>>>> + * gimple-fold.c (fold_gimple_assign): Ditto.
>>>> + (gimple_fold_call): Ditto.
>>>> + * dbgcnt.def: New counter.
>>>> +
>>>> 2014-05-15 Martin Jambor <[email protected]>
>>>>
>>>> PR ipa/61085
>>>> Index: ipa-prop.c
>>>> ===================================================================
>>>> --- ipa-prop.c (revision 210479)
>>>> +++ ipa-prop.c (working copy)
>>>> @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.
>>>> #include "ipa-utils.h"
>>>> #include "stringpool.h"
>>>> #include "tree-ssanames.h"
>>>> +#include "dbgcnt.h"
>>>>
>>>> /* Intermediate information about a parameter that is only useful during
>>>> the
>>>> run of ipa_analyze_node and is not kept afterwards. */
>>>> @@ -2494,6 +2495,13 @@ ipa_make_edge_direct_to_target (struct c
>>>> fprintf (dump_file, "ipa-prop: Discovered direct call to
>>>> non-function"
>>>> " in %s/%i, making it unreachable.\n",
>>>> ie->caller->name (), ie->caller->order);
>>>> + else if (dump_enabled_p ())
>>>> + {
>>>> + location_t loc = gimple_location (ie->call_stmt);
>>>> + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
>>>> + "Discovered direct call to non-function in
>>>> %s, "
>>>> + "making it unreachable\n", ie->caller->name
>>>> ());
>>>
>>> Perhaps "turning it to __builtin_unreachable call" and similarly in the
>>> other cases
>>> we introduce __builtin_unreachable? I think that could be easier for user
>>> to work
>>> out.
>>>
>>> What king of problems in devirtualizatoin you are seeing?
>>>
>>>
>>> Honza
Index: cgraphunit.c
===================================================================
--- cgraphunit.c (revision 210479)
+++ cgraphunit.c (working copy)
@@ -210,6 +210,7 @@ along with GCC; see the file COPYING3.
#include "pass_manager.h"
#include "tree-nested.h"
#include "gimplify.h"
+#include "dbgcnt.h"
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
secondary queue used during optimization to accommodate passes that
@@ -886,7 +887,7 @@ walk_polymorphic_call_targets (pointer_s
make the edge direct. */
if (final)
{
- if (targets.length () <= 1)
+ if (targets.length () <= 1 && dbg_cnt (devirt))
{
cgraph_node *target;
if (targets.length () == 1)
@@ -903,6 +904,14 @@ walk_polymorphic_call_targets (pointer_s
edge->call_stmt, 0,
TDF_SLIM);
}
+ else 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_redirect_edge_call_stmt_to_callee (edge);
if (cgraph_dump_file)
Index: ipa-prop.c
===================================================================
--- ipa-prop.c (revision 210479)
+++ ipa-prop.c (working copy)
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.
#include "ipa-utils.h"
#include "stringpool.h"
#include "tree-ssanames.h"
+#include "dbgcnt.h"
/* Intermediate information about a parameter that is only useful during the
run of ipa_analyze_node and is not kept afterwards. */
@@ -2490,10 +2491,15 @@ ipa_make_edge_direct_to_target (struct c
/* Member pointer call that goes through a VMT lookup. */
return NULL;
- if (dump_file)
- fprintf (dump_file, "ipa-prop: Discovered direct call to
non-function"
- " in %s/%i, making it unreachable.\n",
- ie->caller->name (), ie->caller->order);
+ if (dump_enabled_p ())
+ {
+ location_t loc = gimple_location (ie->call_stmt);
+ 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);
callee = cgraph_get_create_node (target);
unreachable = true;
@@ -2527,6 +2533,10 @@ ipa_make_edge_direct_to_target (struct c
}
callee = cgraph_get_create_node (target);
}
+
+ if (!dbg_cnt (devirt))
+ return NULL;
+
ipa_check_create_node_params ();
/* 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 c
else
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);
es = inline_edge_summary (ie);
es->call_stmt_size -= (eni_size_weights.indirect_call_cost
Index: ipa.c
===================================================================
--- ipa.c (revision 210479)
+++ ipa.c (working copy)
@@ -37,6 +37,10 @@ along with GCC; see the file COPYING3.
#include "tree-inline.h"
#include "profile.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. */
@@ -213,7 +217,7 @@ walk_polymorphic_call_targets (pointer_s
make the edge direct. */
if (final)
{
- if (targets.length () <= 1)
+ if (targets.length () <= 1 && dbg_cnt (devirt))
{
cgraph_node *target, *node = edge->caller;
if (targets.length () == 1)
@@ -222,12 +226,15 @@ walk_polymorphic_call_targets (pointer_s
target = cgraph_get_create_node
(builtin_decl_implicit (BUILT_IN_UNREACHABLE));
- if (dump_file)
- fprintf (dump_file,
- "Devirtualizing call in %s/%i to %s/%i\n",
- edge->caller->name (),
- edge->caller->order,
- target->name (), target->order);
+ if (dump_enabled_p ())
+ {
+ location_t locus = gimple_location (edge->call_stmt);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
+ "devirtualizing call in %s/%i to %s/%i\n",
+ edge->caller->name (), edge->caller->order,
+ target->name (),
+ target->order);
+ }
edge = cgraph_make_edge_direct (edge, target);
if (inline_summary_vec)
inline_update_overall_summary (node);
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c (revision 210479)
+++ ipa-devirt.c (working copy)
@@ -129,6 +129,7 @@ along with GCC; see the file COPYING3.
#include "diagnostic.h"
#include "tree-dfa.h"
#include "demangle.h"
+#include "dbgcnt.h"
static bool odr_violation_reported = false;
@@ -2067,14 +2068,17 @@ ipa_devirt (void)
noverwritable++;
continue;
}
- else
+ else if (dbg_cnt (devirt))
{
- if (dump_file)
- fprintf (dump_file,
- "Speculatively devirtualizing call in %s/%i to
%s/%i\n\n",
- n->name (), n->order,
- likely_target->name (),
- likely_target->order);
+ if (dump_enabled_p ())
+ {
+ location_t locus = gimple_location (e->call_stmt);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
+ "speculatively devirtualizing call in
%s/%i to %s/%i\n",
+ n->name (), n->order,
+ likely_target->name (),
+ likely_target->order);
+ }
if (!symtab_can_be_discarded (likely_target))
{
cgraph_node *alias;
Index: dbgcnt.def
===================================================================
--- dbgcnt.def (revision 210479)
+++ dbgcnt.def (working copy)
@@ -150,6 +150,7 @@ DEBUG_COUNTER (dce)
DEBUG_COUNTER (dce_fast)
DEBUG_COUNTER (dce_ud)
DEBUG_COUNTER (delete_trivial_dead)
+DEBUG_COUNTER (devirt)
DEBUG_COUNTER (df_byte_scan)
DEBUG_COUNTER (dse)
DEBUG_COUNTER (dse1)
Index: gimple-fold.c
===================================================================
--- gimple-fold.c (revision 210479)
+++ gimple-fold.c (working copy)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.
#include "tree-ssa-address.h"
#include "langhooks.h"
#include "gimplify-me.h"
+#include "dbgcnt.h"
/* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
@@ -386,13 +387,24 @@ fold_gimple_assign (gimple_stmt_iterator
bool final;
vec <cgraph_node *>targets
= possible_polymorphic_call_targets (val, &final);
- if (final && targets.length () <= 1)
+ if (final && targets.length () <= 1 && dbg_cnt (devirt))
{
tree fndecl;
+
if (targets.length () == 1)
fndecl = targets[0]->decl;
else
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);
STRIP_USELESS_TYPE_CONVERSION (val);
return val;
@@ -1124,9 +1136,18 @@ gimple_fold_call (gimple_stmt_iterator *
bool final;
vec <cgraph_node *>targets
= 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);
+ 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)
{
gimple_call_set_fndecl (stmt, targets[0]->decl);
Index: tree-ssa-pre.c
===================================================================
--- tree-ssa-pre.c (revision 210479)
+++ tree-ssa-pre.c (working copy)
@@ -4347,18 +4347,19 @@ eliminate_dom_walker::before_dom_childre
continue;
if (gimple_call_addr_fndecl (fn) != NULL_TREE
&& useless_type_conversion_p (TREE_TYPE (orig_fn),
- TREE_TYPE (fn)))
+ TREE_TYPE (fn))
+ && dbg_cnt (devirt))
{
bool can_make_abnormal_goto
= stmt_can_make_abnormal_goto (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 ");
- print_generic_expr (dump_file, fn, 0);
- fprintf (dump_file, " in ");
- print_gimple_stmt (dump_file, stmt, 0, 0);
+ location_t loc = gimple_location (stmt);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+ "converting indirect call to function %s\n",
+ cgraph_get_node (fn)->name ());
}
gimple_call_set_fn (stmt, fn);
Index: ChangeLog
===================================================================
--- ChangeLog (revision 210479)
+++ ChangeLog (working copy)
@@ -1,3 +1,20 @@
+2014-05-15 Xinliang David Li <[email protected]>
+
+ * cgraphunit.c (walk_polymorphic_call_targets): Add
+ dbgcnt and fopt-info support.
+ 2014-05-15 Xinliang David Li <[email protected]>
+
+ * 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-15 Martin Jambor <[email protected]>
PR ipa/61085