aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2014-11-26 18:10:29 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2014-11-26 18:10:29 +0000
commit6cbde2e317bb4be42e88000de6b927e55904f0dc (patch)
tree6293fca73098e7b3f8d1ab85fb4e3532798064e4
parent69d7fa342c0ff1932ad451d1ebd5aab53e79dd10 (diff)
downloadgcc-6cbde2e317bb4be42e88000de6b927e55904f0dc.zip
gcc-6cbde2e317bb4be42e88000de6b927e55904f0dc.tar.gz
gcc-6cbde2e317bb4be42e88000de6b927e55904f0dc.tar.bz2
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
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/cgraph.c77
-rw-r--r--gcc/cgraph.h23
-rw-r--r--gcc/ipa-pure-const.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/p4736b.C1
6 files changed, 100 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 79c5411..62dcb38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+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>
PR middle-end/63738
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 5323468..6aecb14 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -2193,15 +2193,16 @@ cgraph_node::can_be_local_p (void)
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
- skipped. */
-
+ skipped. When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
+ skipped. */
bool
cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
(cgraph_node *, void *),
void *data,
- bool include_overwritable)
+ bool include_overwritable,
+ bool exclude_virtual_thunks)
{
cgraph_edge *e;
ipa_ref *ref;
@@ -2211,9 +2212,12 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
for (e = callers; e; e = e->next_caller)
if (e->caller->thunk.thunk_p
&& (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,
- include_overwritable))
+ include_overwritable,
+ exclude_virtual_thunks))
return true;
FOR_EACH_ALIAS (this, ref)
@@ -2222,15 +2226,16 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
if (include_overwritable
|| alias->get_availability () > AVAIL_INTERPOSABLE)
if (alias->call_for_symbol_thunks_and_aliases (callback, data,
- include_overwritable))
+ include_overwritable,
+ exclude_virtual_thunks))
return true;
}
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
- skipped. */
+ skipped. */
bool
cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
@@ -2338,7 +2343,7 @@ cgraph_node::set_const_flag (bool readonly, bool looping)
{
call_for_symbol_thunks_and_aliases (cgraph_set_const_flag_1,
(void *)(size_t)(readonly + (int)looping * 2),
- false);
+ false, true);
}
/* Worker to set pure flag. */
@@ -2368,7 +2373,7 @@ cgraph_node::set_pure_flag (bool pure, bool looping)
{
call_for_symbol_thunks_and_aliases (cgraph_set_pure_flag_1,
(void *)(size_t)(pure + (int)looping * 2),
- false);
+ false, true);
}
/* Return true when cgraph_node can not return or throw and thus
@@ -3118,30 +3123,52 @@ cgraph_node::verify_cgraph_nodes (void)
}
/* 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. */
cgraph_node *
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);
- 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;
- if (availability)
- {
- enum availability a;
- a = node->get_availability ();
- if (a < *availability)
- *availability = a;
- }
- node = node->ultimate_alias_target (availability);
+ enum availability a;
+ a = node->get_availability ();
+ if (a < *availability)
+ *availability = a;
}
- } while (node && node->thunk.thunk_p);
+ node = node->ultimate_alias_target (availability);
+ }
return node;
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a5c5f56..04318f5 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -254,9 +254,9 @@ public:
body aliases. */
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
- skipped. */
+ skipped. */
bool call_for_symbol_and_aliases (bool (*callback) (symtab_node *, void *),
void *data,
bool include_overwrite);
@@ -793,6 +793,13 @@ public:
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
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
the execution counts from original node too.
The new clone will have decl set to DECL that may or may not be the same
@@ -1015,7 +1022,7 @@ public:
if any to PURE. */
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
skipped. */
@@ -1023,13 +1030,15 @@ public:
void *),
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
+ skipped. When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
skipped. */
bool call_for_symbol_thunks_and_aliases (bool (*callback) (cgraph_node *node,
- void *data),
- void *data,
- bool include_overwritable);
+ void *data),
+ void *data,
+ bool include_overwritable,
+ bool exclude_virtual_thunks = false);
/* Likewise indicate that a node is needed, i.e. reachable via some
external means. */
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 9c016c1..13e3a25 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -806,6 +806,8 @@ analyze_function (struct cgraph_node *fn, bool ipa)
{
/* Thunk gets propagated through, so nothing interesting happens. */
gcc_assert (ipa);
+ if (fn->thunk.thunk_p && fn->thunk.virtual_offset_p)
+ l->pure_const_state = IPA_NEITHER;
return l;
}
@@ -1247,7 +1249,8 @@ propagate_pure_const (void)
for (e = w->callees; e; e = e->next_callee)
{
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;
bool edge_looping = false;
@@ -1387,7 +1390,8 @@ propagate_pure_const (void)
for (e = w->callees; e && !can_free; e = e->next_callee)
{
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)
can_free = get_function_state (y)->can_free;
@@ -1517,7 +1521,8 @@ propagate_nothrow (void)
for (e = w->callees; e && !can_throw; e = e->next_callee)
{
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)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 48e3581..c3dcfd2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+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>
PR c++/59114
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C b/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C
index c2fce17..e76bd74 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/p4736b.C
@@ -1,4 +1,5 @@
// { dg-do run }
+// { dg-options "-O2" }
// prms-id: 4736
class Rep {