This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix ipa-devirt-11.C on AIX part 1
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 6 Sep 2013 12:14:49 +0200
- Subject: Fix ipa-devirt-11.C on AIX part 1
- Authentication-results: sourceware.org; auth=none
Hi,
ipa-devirt-11.C (invented by me) checks for series of events that lead
to an ICE. With local alias changes these events are not happening for multiple
reasons. This patch solves first problem: we now redirect call to a function
to call to its alias and that breaks detection of self recursion on several places.
Introducewd by adding recursive_call_p predicate and also symtab logic to try to
prove if two symbols must point to semantically equivalent piece of code (or vtable)
Bootstrapped/regtested x86_64-linux, will commit it shortly.
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.
Index: cgraph.h
===================================================================
--- cgraph.h (revision 202315)
+++ cgraph.h (working copy)
@@ -627,6 +627,7 @@ bool symtab_for_node_and_aliases (symtab
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 *);
Index: tree-tailcall.c
===================================================================
--- tree-tailcall.c (revision 202315)
+++ tree-tailcall.c (working copy)
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.
#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
/* 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;
Index: ipa-pure-const.c
===================================================================
--- ipa-pure-const.c (revision 202315)
+++ ipa-pure-const.c (working copy)
@@ -541,7 +541,8 @@ check_call (funct_state local, gimple ca
}
/* 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)
Index: ipa-utils.c
===================================================================
--- ipa-utils.c (revision 202315)
+++ ipa-utils.c (working copy)
@@ -791,3 +791,14 @@ ipa_merge_profiles (struct cgraph_node *
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);
+}
Index: ipa-utils.h
===================================================================
--- ipa-utils.h (revision 202315)
+++ ipa-utils.h (working copy)
@@ -46,6 +46,7 @@ int ipa_reverse_postorder (struct cgraph
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);
Index: symtab.c
===================================================================
--- symtab.c (revision 202315)
+++ symtab.c (working copy)
@@ -1106,11 +1106,48 @@ symtab_nonoverwritable_alias (symtab_nod
{
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"
Index: Makefile.in
===================================================================
--- Makefile.in (revision 202315)
+++ Makefile.in (working copy)
@@ -2432,7 +2432,7 @@ tree-tailcall.o : tree-tailcall.c $(TREE
$(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 \