Commit 6cbde2e3 by Bernd Edlinger Committed by Bernd Edlinger

re PR ipa/61190 (g++.old-deja/g++.mike/p4736b.C FAILs at -O2/-Os/-O3)

2014-11-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR ipa/61190
        * cgraph.h (symtab_node::call_for_symbol_and_aliases): Fix comment.
        (cgraph_node::function_or_virtual_thunk_symbol): New function.
        (cgraph_node::call_for_symbol_and_aliases): Fix comment.
        (cgraph_node::call_for_symbol_thunks_and_aliases): Adjust comment.
        Add new optional parameter exclude_virtual_thunks.
        * cgraph.c (cgraph_node::call_for_symbol_thunks_and_aliases): Add new
        optional parameter exclude_virtual_thunks.
        (cgraph_node::set_const_flag): Don't propagate to virtual thunks.
        (cgraph_node::set_pure_flag): Likewise.
        (cgraph_node::function_symbol): Simplified.
        (cgraph_node::function_or_virtual_thunk_symbol): New function.
        * ipa-pure-const.c (analyze_function): For virtual thunks set
        pure_const_state to IPA_NEITHER.
        (propagate_pure_const): Use function_or_virtual_thunk_symbol.

testsuite/ChangeLog:
2014-11-26  Bernd Edlinger  <bernd.edlinger@hotmail.de>

        PR ipa/61190
        * g++.old-deja/g++.mike/p4736b.C: Use -O2.

From-SVN: r218091
parent 69d7fa34
2014-11-26 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR ipa/61190
* cgraph.h (symtab_node::call_for_symbol_and_aliases): Fix comment.
(cgraph_node::function_or_virtual_thunk_symbol): New function.
(cgraph_node::call_for_symbol_and_aliases): Fix comment.
(cgraph_node::call_for_symbol_thunks_and_aliases): Adjust comment.
Add new optional parameter exclude_virtual_thunks.
* cgraph.c (cgraph_node::call_for_symbol_thunks_and_aliases): Add new
optional parameter exclude_virtual_thunks.
(cgraph_node::set_const_flag): Don't propagate to virtual thunks.
(cgraph_node::set_pure_flag): Likewise.
(cgraph_node::function_symbol): Simplified.
(cgraph_node::function_or_virtual_thunk_symbol): New function.
* ipa-pure-const.c (analyze_function): For virtual thunks set
pure_const_state to IPA_NEITHER.
(propagate_pure_const): Use function_or_virtual_thunk_symbol.
2014-11-26 Richard Biener <rguenther@suse.de> 2014-11-26 Richard Biener <rguenther@suse.de>
PR middle-end/63738 PR middle-end/63738
...@@ -2193,15 +2193,16 @@ cgraph_node::can_be_local_p (void) ...@@ -2193,15 +2193,16 @@ cgraph_node::can_be_local_p (void)
NULL, true)); NULL, true));
} }
/* Call calback on cgraph_node, thunks and aliases associated to cgraph_node. /* Call callback on cgraph_node, thunks and aliases associated to cgraph_node.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */ skipped. When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
skipped. */
bool bool
cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback) cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
(cgraph_node *, void *), (cgraph_node *, void *),
void *data, void *data,
bool include_overwritable) bool include_overwritable,
bool exclude_virtual_thunks)
{ {
cgraph_edge *e; cgraph_edge *e;
ipa_ref *ref; ipa_ref *ref;
...@@ -2211,9 +2212,12 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback) ...@@ -2211,9 +2212,12 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
for (e = callers; e; e = e->next_caller) for (e = callers; e; e = e->next_caller)
if (e->caller->thunk.thunk_p if (e->caller->thunk.thunk_p
&& (include_overwritable && (include_overwritable
|| e->caller->get_availability () > AVAIL_INTERPOSABLE)) || e->caller->get_availability () > AVAIL_INTERPOSABLE)
&& !(exclude_virtual_thunks
&& e->caller->thunk.virtual_offset_p))
if (e->caller->call_for_symbol_thunks_and_aliases (callback, data, if (e->caller->call_for_symbol_thunks_and_aliases (callback, data,
include_overwritable)) include_overwritable,
exclude_virtual_thunks))
return true; return true;
FOR_EACH_ALIAS (this, ref) FOR_EACH_ALIAS (this, ref)
...@@ -2222,15 +2226,16 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback) ...@@ -2222,15 +2226,16 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
if (include_overwritable if (include_overwritable
|| alias->get_availability () > AVAIL_INTERPOSABLE) || alias->get_availability () > AVAIL_INTERPOSABLE)
if (alias->call_for_symbol_thunks_and_aliases (callback, data, if (alias->call_for_symbol_thunks_and_aliases (callback, data,
include_overwritable)) include_overwritable,
exclude_virtual_thunks))
return true; return true;
} }
return false; return false;
} }
/* Call calback on function and aliases associated to the function. /* Call callback on function and aliases associated to the function.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */ skipped. */
bool bool
cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *, cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
...@@ -2338,7 +2343,7 @@ cgraph_node::set_const_flag (bool readonly, bool looping) ...@@ -2338,7 +2343,7 @@ cgraph_node::set_const_flag (bool readonly, bool looping)
{ {
call_for_symbol_thunks_and_aliases (cgraph_set_const_flag_1, call_for_symbol_thunks_and_aliases (cgraph_set_const_flag_1,
(void *)(size_t)(readonly + (int)looping * 2), (void *)(size_t)(readonly + (int)looping * 2),
false); false, true);
} }
/* Worker to set pure flag. */ /* Worker to set pure flag. */
...@@ -2368,7 +2373,7 @@ cgraph_node::set_pure_flag (bool pure, bool looping) ...@@ -2368,7 +2373,7 @@ cgraph_node::set_pure_flag (bool pure, bool looping)
{ {
call_for_symbol_thunks_and_aliases (cgraph_set_pure_flag_1, call_for_symbol_thunks_and_aliases (cgraph_set_pure_flag_1,
(void *)(size_t)(pure + (int)looping * 2), (void *)(size_t)(pure + (int)looping * 2),
false); false, true);
} }
/* Return true when cgraph_node can not return or throw and thus /* Return true when cgraph_node can not return or throw and thus
...@@ -3118,30 +3123,52 @@ cgraph_node::verify_cgraph_nodes (void) ...@@ -3118,30 +3123,52 @@ cgraph_node::verify_cgraph_nodes (void)
} }
/* Walk the alias chain to return the function cgraph_node is alias of. /* Walk the alias chain to return the function cgraph_node is alias of.
Walk through thunk, too. Walk through thunks, too.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
cgraph_node * cgraph_node *
cgraph_node::function_symbol (enum availability *availability) cgraph_node::function_symbol (enum availability *availability)
{ {
cgraph_node *node = this; cgraph_node *node = ultimate_alias_target (availability);
do while (node->thunk.thunk_p)
{ {
node = node->callees->callee;
if (availability)
{
enum availability a;
a = node->get_availability ();
if (a < *availability)
*availability = a;
}
node = node->ultimate_alias_target (availability); node = node->ultimate_alias_target (availability);
if (node->thunk.thunk_p) }
return node;
}
/* Walk the alias chain to return the function cgraph_node is alias of.
Walk through non virtual thunks, too. Thus we return either a function
or a virtual thunk node.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
cgraph_node *
cgraph_node::function_or_virtual_thunk_symbol
(enum availability *availability)
{
cgraph_node *node = ultimate_alias_target (availability);
while (node->thunk.thunk_p && !node->thunk.virtual_offset_p)
{
node = node->callees->callee;
if (availability)
{ {
node = node->callees->callee; enum availability a;
if (availability) a = node->get_availability ();
{ if (a < *availability)
enum availability a; *availability = a;
a = node->get_availability ();
if (a < *availability)
*availability = a;
}
node = node->ultimate_alias_target (availability);
} }
} while (node && node->thunk.thunk_p); node = node->ultimate_alias_target (availability);
}
return node; return node;
} }
......
...@@ -254,9 +254,9 @@ public: ...@@ -254,9 +254,9 @@ public:
body aliases. */ body aliases. */
void fixup_same_cpp_alias_visibility (symtab_node *target); void fixup_same_cpp_alias_visibility (symtab_node *target);
/* Call calback on symtab node and aliases associated to this node. /* Call callback on symtab node and aliases associated to this node.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */ skipped. */
bool call_for_symbol_and_aliases (bool (*callback) (symtab_node *, void *), bool call_for_symbol_and_aliases (bool (*callback) (symtab_node *, void *),
void *data, void *data,
bool include_overwrite); bool include_overwrite);
...@@ -793,6 +793,13 @@ public: ...@@ -793,6 +793,13 @@ public:
When AVAILABILITY is non-NULL, get minimal availability in the chain. */ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
cgraph_node *function_symbol (enum availability *avail = NULL); cgraph_node *function_symbol (enum availability *avail = NULL);
/* Walk the alias chain to return the function cgraph_node is alias of.
Walk through non virtual thunks, too. Thus we return either a function
or a virtual thunk node.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
cgraph_node *function_or_virtual_thunk_symbol
(enum availability *avail = NULL);
/* Create node representing clone of N executed COUNT times. Decrease /* Create node representing clone of N executed COUNT times. Decrease
the execution counts from original node too. the execution counts from original node too.
The new clone will have decl set to DECL that may or may not be the same The new clone will have decl set to DECL that may or may not be the same
...@@ -1015,7 +1022,7 @@ public: ...@@ -1015,7 +1022,7 @@ public:
if any to PURE. */ if any to PURE. */
void set_pure_flag (bool pure, bool looping); void set_pure_flag (bool pure, bool looping);
/* Call calback on function and aliases associated to the function. /* Call callback on function and aliases associated to the function.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. */ skipped. */
...@@ -1023,13 +1030,15 @@ public: ...@@ -1023,13 +1030,15 @@ public:
void *), void *),
void *data, bool include_overwritable); void *data, bool include_overwritable);
/* Call calback on cgraph_node, thunks and aliases associated to NODE. /* Call callback on cgraph_node, thunks and aliases associated to NODE.
When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
skipped. When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
skipped. */ skipped. */
bool call_for_symbol_thunks_and_aliases (bool (*callback) (cgraph_node *node, bool call_for_symbol_thunks_and_aliases (bool (*callback) (cgraph_node *node,
void *data), void *data),
void *data, void *data,
bool include_overwritable); bool include_overwritable,
bool exclude_virtual_thunks = false);
/* Likewise indicate that a node is needed, i.e. reachable via some /* Likewise indicate that a node is needed, i.e. reachable via some
external means. */ external means. */
......
...@@ -806,6 +806,8 @@ analyze_function (struct cgraph_node *fn, bool ipa) ...@@ -806,6 +806,8 @@ analyze_function (struct cgraph_node *fn, bool ipa)
{ {
/* Thunk gets propagated through, so nothing interesting happens. */ /* Thunk gets propagated through, so nothing interesting happens. */
gcc_assert (ipa); gcc_assert (ipa);
if (fn->thunk.thunk_p && fn->thunk.virtual_offset_p)
l->pure_const_state = IPA_NEITHER;
return l; return l;
} }
...@@ -1247,7 +1249,8 @@ propagate_pure_const (void) ...@@ -1247,7 +1249,8 @@ propagate_pure_const (void)
for (e = w->callees; e; e = e->next_callee) for (e = w->callees; e; e = e->next_callee)
{ {
enum availability avail; enum availability avail;
struct cgraph_node *y = e->callee->function_symbol (&avail); struct cgraph_node *y = e->callee->
function_or_virtual_thunk_symbol (&avail);
enum pure_const_state_e edge_state = IPA_CONST; enum pure_const_state_e edge_state = IPA_CONST;
bool edge_looping = false; bool edge_looping = false;
...@@ -1387,7 +1390,8 @@ propagate_pure_const (void) ...@@ -1387,7 +1390,8 @@ propagate_pure_const (void)
for (e = w->callees; e && !can_free; e = e->next_callee) for (e = w->callees; e && !can_free; e = e->next_callee)
{ {
enum availability avail; enum availability avail;
struct cgraph_node *y = e->callee->function_symbol (&avail); struct cgraph_node *y = e->callee->
function_or_virtual_thunk_symbol (&avail);
if (avail > AVAIL_INTERPOSABLE) if (avail > AVAIL_INTERPOSABLE)
can_free = get_function_state (y)->can_free; can_free = get_function_state (y)->can_free;
...@@ -1517,7 +1521,8 @@ propagate_nothrow (void) ...@@ -1517,7 +1521,8 @@ propagate_nothrow (void)
for (e = w->callees; e && !can_throw; e = e->next_callee) for (e = w->callees; e && !can_throw; e = e->next_callee)
{ {
enum availability avail; enum availability avail;
struct cgraph_node *y = e->callee->function_symbol (&avail); struct cgraph_node *y = e->callee->
function_or_virtual_thunk_symbol (&avail);
if (avail > AVAIL_INTERPOSABLE) if (avail > AVAIL_INTERPOSABLE)
{ {
......
2014-11-26 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR ipa/61190
* g++.old-deja/g++.mike/p4736b.C: Use -O2.
2014-11-26 Paolo Carlini <paolo.carlini@oracle.com> 2014-11-26 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/59114 PR c++/59114
......
// { dg-do run } // { dg-do run }
// { dg-options "-O2" }
// prms-id: 4736 // prms-id: 4736
class Rep { class Rep {
......
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