summaryrefslogtreecommitdiff
path: root/gcc/cgraph.c
diff options
context:
space:
mode:
authoredlinger <edlinger@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-26 18:10:29 +0000
committeredlinger <edlinger@138bc75d-0d04-0410-961f-82ee72b054a4>2014-11-26 18:10:29 +0000
commitcfd85d030314bcc2ff30b0f28dfc240af433a1fd (patch)
tree6293fca73098e7b3f8d1ab85fb4e3532798064e4 /gcc/cgraph.c
parent90acc3c9005d639e85a1fe7a24027f7936b8deed (diff)
downloadgcc-cfd85d030314bcc2ff30b0f28dfc240af433a1fd.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@218091 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r--gcc/cgraph.c77
1 files changed, 52 insertions, 25 deletions
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;
}