diff options
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/cgraph.h | 3 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 41 | ||||
-rw-r--r-- | gcc/ipa.c | 16 | ||||
-rw-r--r-- | gcc/symtab.c | 126 |
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" |