aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/cgraph.h3
-rw-r--r--gcc/cgraphunit.c41
-rw-r--r--gcc/ipa.c16
-rw-r--r--gcc/symtab.c126
5 files changed, 157 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 019b9181962..ebee8ab22ce 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2012-04-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (verify_symtab, verify_symtab_node, verify_symtab_base):
+ Declare.
+ * cgraphunit.c (verify_cgraph_node): Verify symtab base; do not verify
+ cgraph hash and same comdat groups.
+ (cgraph_optimize); Verify symbol table.
+ * ipa.c (cgraph_remove_unreachable_nodes): Verify symbol table.
+ (dissolve_same_comdat_group_list): Work on symtab nodes.
+ (function_and_variable_visibility): Dissolve variable same comdat group
+ lists, too.
+ * symtab.c: Include timevar.h
+ (verify_symtab_base, verify_symtab_node, verify_symtab): New functions.
+
2012-04-18 Steven Bosscher <steven@gcc.gnu.org>
* tree-switch-conversion.c (info): Remove global pass info.
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a8132ce85a0..1fd42f16581 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -512,6 +512,9 @@ void debug_symtab (void);
void dump_symtab_node (FILE *, symtab_node);
void debug_symtab_node (symtab_node);
void dump_symtab_base (FILE *, symtab_node);
+void verify_symtab (void);
+void verify_symtab_node (symtab_node);
+bool verify_symtab_base (symtab_node);
/* In cgraph.c */
void dump_cgraph (FILE *);
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7d585e6e5f9..9de423396c1 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -577,6 +577,7 @@ verify_cgraph_node (struct cgraph_node *node)
return;
timevar_push (TV_CGRAPH_VERIFY);
+ error_found |= verify_symtab_base ((symtab_node) node);
for (e = node->callees; e; e = e->next_callee)
if (e->aux)
{
@@ -663,12 +664,6 @@ verify_cgraph_node (struct cgraph_node *node)
error_found = true;
}
- if (!cgraph_get_node (node->symbol.decl))
- {
- error ("node not found in cgraph_hash");
- error_found = true;
- }
-
if (node->clone_of)
{
struct cgraph_node *n;
@@ -708,32 +703,6 @@ verify_cgraph_node (struct cgraph_node *node)
error ("double linked list of clones corrupted");
error_found = true;
}
- if (node->symbol.same_comdat_group)
- {
- symtab_node n = node->symbol.same_comdat_group;
-
- if (!DECL_ONE_ONLY (n->symbol.decl))
- {
- error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
- error_found = true;
- }
- if (n == (symtab_node)node)
- {
- error ("node is alone in a comdat group");
- error_found = true;
- }
- do
- {
- if (!n->symbol.same_comdat_group)
- {
- error ("same_comdat_group is not a circular list");
- error_found = true;
- break;
- }
- n = n->symbol.same_comdat_group;
- }
- while (n != (symtab_node)node);
- }
if (node->analyzed && node->alias)
{
@@ -2654,7 +2623,7 @@ cgraph_optimize (void)
return;
#ifdef ENABLE_CHECKING
- verify_cgraph ();
+ verify_symtab ();
#endif
/* Frontend may output common variables after the unit has been finalized.
@@ -2704,7 +2673,7 @@ cgraph_optimize (void)
if (!quiet_flag)
fprintf (stderr, "Assembling functions:\n");
#ifdef ENABLE_CHECKING
- verify_cgraph ();
+ verify_symtab ();
#endif
cgraph_materialize_all_clones ();
@@ -2712,7 +2681,7 @@ cgraph_optimize (void)
execute_ipa_pass_list (all_late_ipa_passes);
cgraph_remove_unreachable_nodes (true, dump_file);
#ifdef ENABLE_CHECKING
- verify_cgraph ();
+ verify_symtab ();
#endif
bitmap_obstack_release (NULL);
cgraph_mark_functions_to_output ();
@@ -2740,7 +2709,7 @@ cgraph_optimize (void)
dump_symtab (cgraph_dump_file);
}
#ifdef ENABLE_CHECKING
- verify_cgraph ();
+ verify_symtab ();
/* Double check that all inline clones are gone and that all
function bodies have been released from memory. */
if (!seen_error ())
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 874156275a8..964b2b980d5 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -176,7 +176,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
bool changed = false;
#ifdef ENABLE_CHECKING
- verify_cgraph ();
+ verify_symtab ();
#endif
if (file)
fprintf (file, "\nReclaiming functions:");
@@ -467,7 +467,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
return changed;
#ifdef ENABLE_CHECKING
- verify_cgraph ();
+ verify_symtab ();
#endif
/* Reclaim alias pairs for functions that have disappeared from the
@@ -730,12 +730,12 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
/* Dissolve the same_comdat_group list in which NODE resides. */
static void
-dissolve_same_comdat_group_list (struct cgraph_node *node)
+dissolve_same_comdat_group_list (symtab_node node)
{
- struct cgraph_node *n = node, *next;
+ symtab_node n = node, next;
do
{
- next = cgraph (n->symbol.same_comdat_group);
+ next = n->symbol.same_comdat_group;
n->symbol.same_comdat_group = NULL;
n = next;
}
@@ -838,7 +838,7 @@ function_and_variable_visibility (bool whole_program)
all of them have to be, otherwise it is a front-end bug. */
gcc_assert (DECL_EXTERNAL (n->symbol.decl));
#endif
- dissolve_same_comdat_group_list (node);
+ dissolve_same_comdat_group_list ((symtab_node) node);
}
gcc_assert ((!DECL_WEAK (node->symbol.decl)
&& !DECL_COMDAT (node->symbol.decl))
@@ -865,7 +865,7 @@ function_and_variable_visibility (bool whole_program)
in the group and they will all be made local. We need to
dissolve the group at once so that the predicate does not
segfault though. */
- dissolve_same_comdat_group_list (node);
+ dissolve_same_comdat_group_list ((symtab_node) node);
}
if (node->thunk.thunk_p
@@ -936,6 +936,8 @@ function_and_variable_visibility (bool whole_program)
{
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
cgraph_make_decl_local (vnode->symbol.decl);
+ if (vnode->symbol.same_comdat_group)
+ dissolve_same_comdat_group_list ((symtab_node) vnode);
vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
}
gcc_assert (TREE_STATIC (vnode->symbol.decl));
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 58e11af0169..d264e8c99dc 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "cgraph.h"
#include "diagnostic.h"
+#include "timevar.h"
/* Hash table used to convert declarations into nodes. */
static GTY((param_is (union symtab_node_def))) htab_t symtab_hash;
@@ -471,4 +472,129 @@ debug_symtab (void)
dump_symtab (stderr);
}
+/* Verify common part of symtab nodes. */
+
+DEBUG_FUNCTION bool
+verify_symtab_base (symtab_node node)
+{
+ bool error_found = false;
+ symtab_node hashed_node;
+
+ if (symtab_function_p (node))
+ {
+ if (TREE_CODE (node->symbol.decl) != FUNCTION_DECL)
+ {
+ error ("function symbol is not function");
+ error_found = true;
+ }
+ }
+ else if (symtab_variable_p (node))
+ {
+ if (TREE_CODE (node->symbol.decl) != VAR_DECL)
+ {
+ error ("variable symbol is not variable");
+ error_found = true;
+ }
+ }
+ else
+ {
+ error ("node has unknown type");
+ error_found = true;
+ }
+
+ hashed_node = symtab_get_node (node->symbol.decl);
+ if (!hashed_node)
+ {
+ error ("node not found in symtab decl hashtable");
+ error_found = true;
+ }
+ if (assembler_name_hash)
+ {
+ hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->symbol.decl));
+ if (hashed_node && hashed_node->symbol.previous_sharing_asm_name)
+ {
+ error ("assembler name hash list corrupted");
+ error_found = true;
+ }
+ while (hashed_node)
+ {
+ if (hashed_node == node)
+ break;
+ hashed_node = hashed_node->symbol.next_sharing_asm_name;
+ }
+ if (!hashed_node)
+ {
+ error ("node not found in symtab assembler name hash");
+ error_found = true;
+ }
+ }
+ if (node->symbol.previous_sharing_asm_name
+ && node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name != node)
+ {
+ error ("double linked list of assembler names corrupted");
+ }
+ if (node->symbol.same_comdat_group)
+ {
+ symtab_node n = node->symbol.same_comdat_group;
+
+ if (!DECL_ONE_ONLY (n->symbol.decl))
+ {
+ error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
+ error_found = true;
+ }
+ if (n->symbol.type != node->symbol.type)
+ {
+ error ("mixing different types of symbol in same comdat groups is not supported");
+ error_found = true;
+ }
+ if (n == node)
+ {
+ error ("node is alone in a comdat group");
+ error_found = true;
+ }
+ do
+ {
+ if (!n->symbol.same_comdat_group)
+ {
+ error ("same_comdat_group is not a circular list");
+ error_found = true;
+ break;
+ }
+ n = n->symbol.same_comdat_group;
+ }
+ while (n != node);
+ }
+ return error_found;
+}
+
+/* Verify consistency of NODE. */
+
+DEBUG_FUNCTION void
+verify_symtab_node (symtab_node node)
+{
+ if (seen_error ())
+ return;
+
+ timevar_push (TV_CGRAPH_VERIFY);
+ if (symtab_function_p (node))
+ verify_cgraph_node (cgraph (node));
+ else
+ if (verify_symtab_base (node))
+ {
+ dump_symtab_node (stderr, node);
+ internal_error ("verify_symtab_node failed");
+ }
+ timevar_pop (TV_CGRAPH_VERIFY);
+}
+
+/* Verify symbol table for internal consistency. */
+
+DEBUG_FUNCTION void
+verify_symtab (void)
+{
+ symtab_node node;
+ FOR_EACH_SYMBOL (node)
+ verify_symtab_node (node);
+}
+
#include "gt-symtab.h"