From 6cbde2e317bb4be42e88000de6b927e55904f0dc Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 26 Nov 2014 18:10:29 +0000 Subject: [PATCH] re PR ipa/61190 (g++.old-deja/g++.mike/p4736b.C FAILs at -O2/-Os/-O3) 2014-11-26 Bernd Edlinger 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 PR ipa/61190 * g++.old-deja/g++.mike/p4736b.C: Use -O2. From-SVN: r218091 --- gcc/ChangeLog | 18 +++++ gcc/cgraph.c | 77 +++++++++++++------- gcc/cgraph.h | 23 ++++-- gcc/ipa-pure-const.c | 11 ++- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.old-deja/g++.mike/p4736b.C | 1 + 6 files changed, 100 insertions(+), 35 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 79c5411c324..62dcb381af7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2014-11-26 Bernd Edlinger + + 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 PR middle-end/63738 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 5323468b8f5..6aecb14823c 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 a5c5f569d67..04318f58c7a 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 9c016c1d586..13e3a258c9b 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 48e35810079..c3dcfd2cbf4 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-11-26 Bernd Edlinger + + PR ipa/61190 + * g++.old-deja/g++.mike/p4736b.C: Use -O2. + 2014-11-26 Paolo Carlini 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 c2fce17b4b0..e76bd74040c 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 { -- 2.30.2