diff options
author | Jan Hubicka <jh@suse.cz> | 2013-09-06 12:13:37 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2013-09-06 10:13:37 +0000 |
commit | fc11f321bbffb92287ee4f25aa70eab40f66a163 (patch) | |
tree | e167b438c335f3bc2a8367366839e99f406f78e4 /gcc | |
parent | 9a6af4504b8bc9b03020b1e96a3bad56d9929916 (diff) | |
download | gcc-fc11f321bbffb92287ee4f25aa70eab40f66a163.zip gcc-fc11f321bbffb92287ee4f25aa70eab40f66a163.tar.gz gcc-fc11f321bbffb92287ee4f25aa70eab40f66a163.tar.bz2 |
re PR middle-end/58094 (IPA devirt testsuite errors)
PR middle-end/58094
* cgraph.h (symtab_semantically_equivalent_p): Declare.
* tree-tailcall.c: Include ipa-utils.h.
(find_tail_calls): Use it.
* ipa-pure-const.c (check_call): Likewise.
* ipa-utils.c (recursive_call_p): New function.
* ipa-utils.h (recursive_call_p): Dclare.
* symtab.c (symtab_nonoverwritable_alias): Fix formatting.
(symtab_semantically_equivalent_p): New function.
* Makefile.in (tree-tailcall.o): Update dependencies.
From-SVN: r202316
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/Makefile.in | 2 | ||||
-rw-r--r-- | gcc/cgraph.h | 1 | ||||
-rw-r--r-- | gcc/ipa-pure-const.c | 8 | ||||
-rw-r--r-- | gcc/ipa-utils.c | 11 | ||||
-rw-r--r-- | gcc/ipa-utils.h | 1 | ||||
-rw-r--r-- | gcc/symtab.c | 41 | ||||
-rw-r--r-- | gcc/tree-tailcall.c | 3 |
8 files changed, 73 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e5b74ed..a2a6822 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2013-09-06 Jan Hubicka <jh@suse.cz> + + PR middle-end/58094 + * cgraph.h (symtab_semantically_equivalent_p): Declare. + * tree-tailcall.c: Include ipa-utils.h. + (find_tail_calls): Use it. + * ipa-pure-const.c (check_call): Likewise. + * ipa-utils.c (recursive_call_p): New function. + * ipa-utils.h (recursive_call_p): Dclare. + * symtab.c (symtab_nonoverwritable_alias): Fix formatting. + (symtab_semantically_equivalent_p): New function. + * Makefile.in (tree-tailcall.o): Update dependencies. + 2013-09-06 Eric Botcazou <ebotcazou@adacore.com> * ipa-split.c (split_function): Set DECL_NO_INLINE_WARNING_P on the diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 4fdf5cb..8430300 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2432,7 +2432,7 @@ tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \ $(EXCEPT_H) $(TREE_PASS_H) $(FLAGS_H) langhooks.h \ $(BASIC_BLOCK_H) $(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) $(TARGET_H) \ - $(COMMON_TARGET_H) $(CFGLOOP_H) + $(COMMON_TARGET_H) $(CFGLOOP_H) ipa-utils.h tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \ $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \ $(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) alloc-pool.h \ diff --git a/gcc/cgraph.h b/gcc/cgraph.h index ea8a04d..5a7a949 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -627,6 +627,7 @@ bool symtab_for_node_and_aliases (symtab_node, bool); symtab_node symtab_nonoverwritable_alias (symtab_node); enum availability symtab_node_availability (symtab_node); +bool symtab_semantically_equivalent_p (symtab_node, symtab_node); /* In cgraph.c */ void dump_cgraph (FILE *); diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index 7a29365..ed4deae 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -541,7 +541,8 @@ check_call (funct_state local, gimple call, bool ipa) } /* When not in IPA mode, we can still handle self recursion. */ - if (!ipa && callee_t == current_function_decl) + if (!ipa && callee_t + && recursive_call_p (current_function_decl, callee_t)) { if (dump_file) fprintf (dump_file, " Recursive call can loop.\n"); @@ -1079,8 +1080,9 @@ ignore_edge (struct cgraph_edge *e) } /* Return true if NODE is self recursive function. - ??? self recursive and indirectly recursive funcions should - be the same, so this function seems unnecessary. */ + Indirectly recursive functions appears as non-trivial strongly + connected components, so we need to care about self recursion + only. */ static bool self_recursive_p (struct cgraph_node *node) diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index 0ea02ea..e2e1690 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -791,3 +791,14 @@ ipa_merge_profiles (struct cgraph_node *dst, src->symbol.decl = oldsrcdecl; } +/* Return true if call to DEST is known to be self-recusive call withing FUNC. */ + +bool +recursive_call_p (tree func, tree dest) +{ + struct cgraph_node *dest_node = cgraph_get_create_node (dest); + struct cgraph_node *cnode = cgraph_get_create_node (func); + + return symtab_semantically_equivalent_p ((symtab_node)dest_node, + (symtab_node)cnode); +} diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h index 5619b5d..d6f390d 100644 --- a/gcc/ipa-utils.h +++ b/gcc/ipa-utils.h @@ -46,6 +46,7 @@ int ipa_reverse_postorder (struct cgraph_node **); tree get_base_var (tree); void ipa_merge_profiles (struct cgraph_node *dst, struct cgraph_node *src); +bool recursive_call_p (tree, tree); /* In ipa-profile.c */ bool ipa_propagate_frequency (struct cgraph_node *node); diff --git a/gcc/symtab.c b/gcc/symtab.c index 253ba98..8dc61d0 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -1106,11 +1106,48 @@ symtab_nonoverwritable_alias (symtab_node node) { DECL_STATIC_CONSTRUCTOR (new_decl) = 0; DECL_STATIC_DESTRUCTOR (new_decl) = 0; - new_node = (symtab_node) cgraph_create_function_alias (new_decl, node->symbol.decl); + new_node = (symtab_node) cgraph_create_function_alias + (new_decl, node->symbol.decl); } else - new_node = (symtab_node) varpool_create_variable_alias (new_decl, node->symbol.decl); + new_node = (symtab_node) varpool_create_variable_alias (new_decl, + node->symbol.decl); symtab_resolve_alias (new_node, node); + gcc_assert (decl_binds_to_current_def_p (new_decl)); return new_node; } + +/* Return true if A and B represents semantically equivalent symbols. */ + +bool +symtab_semantically_equivalent_p (symtab_node a, + symtab_node b) +{ + enum availability avail; + symtab_node ba, bb; + + /* Equivalent functions are equivalent. */ + if (a->symbol.decl == b->symbol.decl) + return true; + + /* If symbol is not overwritable by different implementation, + walk to the base object it defines. */ + ba = symtab_alias_ultimate_target (a, &avail); + if (avail >= AVAIL_AVAILABLE) + { + if (ba == b) + return true; + } + else + ba = a; + bb = symtab_alias_ultimate_target (b, &avail); + if (avail >= AVAIL_AVAILABLE) + { + if (a == bb) + return true; + } + else + bb = b; + return bb == ba; +} #include "gt-symtab.h" diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 9694046..289b75a 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cfgloop.h" #include "common/common-target.h" +#include "ipa-utils.h" /* The file implements the tail recursion elimination. It is also used to analyze the tail calls in general, passing the results to the rtl level @@ -445,7 +446,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) /* We found the call, check whether it is suitable. */ tail_recursion = false; func = gimple_call_fndecl (call); - if (func == current_function_decl) + if (func && recursive_call_p (current_function_decl, func)) { tree arg; |