diff options
author | Jan Hubicka <jh@suse.cz> | 2012-05-24 11:44:48 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2012-05-24 09:44:48 +0000 |
commit | 07250f0e288ccfc04002c013a2cbc74c05d13592 (patch) | |
tree | 1304b7028d8d01c6f5272f44c33289a472a88e49 | |
parent | 0f4fb41f6db3fb0e1279cabc3d5b0b2c4c159c48 (diff) | |
download | gcc-07250f0e288ccfc04002c013a2cbc74c05d13592.zip gcc-07250f0e288ccfc04002c013a2cbc74c05d13592.tar.gz gcc-07250f0e288ccfc04002c013a2cbc74c05d13592.tar.bz2 |
tree.h (alias_diag_flags): Remove.
* tree.h (alias_diag_flags): Remove.
(alias_pair): Remove emitted_diags.
(finish_aliases_1, finish_aliases_2, remove_unreachable_alias_pairs,
symbol_alias_set_t, symbol_alias_set_destroy,
symbol_alias_set_contains, propagate_aliases_backward): Remove.
* toplev.c (compile_file): Do not call finish_aliases_2
* cgraphunit.c (cgraph_process_new_functions): Do not call finish_aliases_1.
(handle_alias_pairs): Output diagnostics about aliases to externals.
(assemble_thunks_and_aliases): Use do_assemble_alias.
(output_weakrefs): Likewise.
(finalize_compilation_unit): Do not call finish_aliases_1.
* ipa.c (symtab_remove_unreachable_nodes): De not call remove_unreachable_alias_pairs.
* varasm.c (do_assemble_alias): Export.
(symbol_alias_set_create, symbol_alias_set_destroy, symbol_alias_set_contains,
symbol_alias_set_insert, propagate_aliases_forward, propagate_aliases_backward,
propagate_aliases_backward, trivially_visible_alias, trivially_defined_alias,
remove_unreachable_alias_pairs, finish_aliases_1, finish_aliases_2,
assemble_alias): Remove.
* output.h (do_assemble_alias): Declare.
* varpool.c (varpool_remove_unreferenced_decls): Do not call finish_aliases_1.
From-SVN: r187823
-rw-r--r-- | gcc/ChangeLog | 23 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 34 | ||||
-rw-r--r-- | gcc/ipa.c | 4 | ||||
-rw-r--r-- | gcc/output.h | 1 | ||||
-rw-r--r-- | gcc/toplev.c | 2 | ||||
-rw-r--r-- | gcc/tree.h | 35 | ||||
-rw-r--r-- | gcc/varasm.c | 255 | ||||
-rw-r--r-- | gcc/varpool.c | 3 |
8 files changed, 54 insertions, 303 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70e58ee..c11b87c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2012-05-23 Jan Hubicka <jh@suse.cz> + + * tree.h (alias_diag_flags): Remove. + (alias_pair): Remove emitted_diags. + (finish_aliases_1, finish_aliases_2, remove_unreachable_alias_pairs, + symbol_alias_set_t, symbol_alias_set_destroy, + symbol_alias_set_contains, propagate_aliases_backward): Remove. + * toplev.c (compile_file): Do not call finish_aliases_2 + * cgraphunit.c (cgraph_process_new_functions): Do not call finish_aliases_1. + (handle_alias_pairs): Output diagnostics about aliases to externals. + (assemble_thunks_and_aliases): Use do_assemble_alias. + (output_weakrefs): Likewise. + (finalize_compilation_unit): Do not call finish_aliases_1. + * ipa.c (symtab_remove_unreachable_nodes): De not call remove_unreachable_alias_pairs. + * varasm.c (do_assemble_alias): Export. + (symbol_alias_set_create, symbol_alias_set_destroy, symbol_alias_set_contains, + symbol_alias_set_insert, propagate_aliases_forward, propagate_aliases_backward, + propagate_aliases_backward, trivially_visible_alias, trivially_defined_alias, + remove_unreachable_alias_pairs, finish_aliases_1, finish_aliases_2, + assemble_alias): Remove. + * output.h (do_assemble_alias): Declare. + * varpool.c (varpool_remove_unreferenced_decls): Do not call finish_aliases_1. + 2012-05-23 Martin Jambor <mjambor@suse.cz> * ipa-inline-analysis.c (inline_merge_summary): Free operand_map. diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 2833868..8dd5223 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -285,7 +285,6 @@ cgraph_process_new_functions (void) if (!cgraph_new_nodes) return false; - finish_aliases_1 (); handle_alias_pairs (); /* Note that this queue may grow as its being processed, as the new functions may generate new ones. */ @@ -1068,6 +1067,18 @@ handle_alias_pairs (void) = lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL; + if (DECL_EXTERNAL (target_node->symbol.decl) + /* We use local aliases for C++ thunks to force the tailcall + to bind locally. This is a hack - to keep it working do + the following (which is not strictly correct). */ + && (! TREE_CODE (target_node->symbol.decl) == FUNCTION_DECL + || ! DECL_VIRTUAL_P (target_node->symbol.decl)) + && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) + { + error ("%q+D aliased to external symbol %qE", + p->decl, p->target); + } + if (TREE_CODE (p->decl) == FUNCTION_DECL && target_node && symtab_function_p (target_node)) { @@ -1185,6 +1196,7 @@ mark_functions_to_output (void) end up not removing the body since we no longer have an analyzed node pointing to it. */ && !node->symbol.in_other_partition + && !node->clones && !DECL_EXTERNAL (decl)) { dump_cgraph_node (stderr, node); @@ -1552,8 +1564,8 @@ assemble_thunks_and_aliases (struct cgraph_node *node) /* Force assemble_alias to really output the alias this time instead of buffering it in same alias pairs. */ TREE_ASM_WRITTEN (alias->thunk.alias) = 1; - assemble_alias (alias->symbol.decl, - DECL_ASSEMBLER_NAME (alias->thunk.alias)); + do_assemble_alias (alias->symbol.decl, + DECL_ASSEMBLER_NAME (alias->thunk.alias)); assemble_thunks_and_aliases (alias); TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written; } @@ -1902,16 +1914,16 @@ output_weakrefs (void) if (node->alias && DECL_EXTERNAL (node->symbol.decl) && !TREE_ASM_WRITTEN (node->symbol.decl) && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl))) - assemble_alias (node->symbol.decl, - node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias) - : get_alias_symbol (node->symbol.decl)); + do_assemble_alias (node->symbol.decl, + node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias) + : get_alias_symbol (node->symbol.decl)); FOR_EACH_VARIABLE (vnode) if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl) && !TREE_ASM_WRITTEN (vnode->symbol.decl) && lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl))) - assemble_alias (vnode->symbol.decl, - vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of) - : get_alias_symbol (vnode->symbol.decl)); + do_assemble_alias (vnode->symbol.decl, + vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of) + : get_alias_symbol (vnode->symbol.decl)); } /* Initialize callgraph dump file. */ @@ -1995,7 +2007,6 @@ compile (void) #endif bitmap_obstack_release (NULL); mark_functions_to_output (); - output_weakrefs (); cgraph_state = CGRAPH_STATE_EXPANSION; if (!flag_toplevel_reorder) @@ -2010,6 +2021,7 @@ compile (void) cgraph_process_new_functions (); cgraph_state = CGRAPH_STATE_FINISHED; + output_weakrefs (); if (cgraph_dump_file) { @@ -2058,7 +2070,6 @@ finalize_compilation_unit (void) finalize_size_functions (); /* Mark alias targets necessary and emit diagnostics. */ - finish_aliases_1 (); handle_alias_pairs (); if (!quiet_flag) @@ -2075,7 +2086,6 @@ finalize_compilation_unit (void) cgraph_analyze_functions (); /* Mark alias targets necessary and emit diagnostics. */ - finish_aliases_1 (); handle_alias_pairs (); /* Gimplify and lower thunks. */ @@ -454,10 +454,6 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) FOR_EACH_DEFINED_FUNCTION (node) cgraph_propagate_frequency (node); - /* Reclaim alias pairs for functions that have disappeared from the - call graph. */ - remove_unreachable_alias_pairs (); - return changed; } diff --git a/gcc/output.h b/gcc/output.h index bd83199..31978c5 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -187,6 +187,7 @@ extern int decode_reg_name (const char *); extern int decode_reg_name_and_count (const char *, int *); extern void assemble_alias (tree, tree); +extern void do_assemble_alias (tree, tree); extern void default_assemble_visibility (tree, int); diff --git a/gcc/toplev.c b/gcc/toplev.c index 90b2246..3ac69cd 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -577,8 +577,6 @@ compile_file (void) basically finished. */ if (in_lto_p || !flag_lto || flag_fat_lto_objects) { - finish_aliases_2 (); - /* Likewise for mudflap static object registrations. */ if (flag_mudflap) mudflap_finish_file (); @@ -239,25 +239,14 @@ extern const unsigned char tree_code_length[]; extern const char *const tree_code_name[]; -/* We have to be able to tell cgraph about the needed-ness of the target - of an alias. This requires that the decl have been defined. Aliases - that precede their definition have to be queued for later processing. */ - -/* The deferred processing proceeds in several passes. We memorize the - diagnostics emitted for a pair to prevent repeating messages when the - queue gets re-scanned after possible updates. */ - -typedef enum { - ALIAS_DIAG_NONE = 0x0, - ALIAS_DIAG_TO_UNDEF = 0x1, - ALIAS_DIAG_TO_EXTERN = 0x2 -} alias_diag_flags; - +/* When procesing aliases on symtab level, we need the declaration of target. + For this reason we need to queue aliases and process them after all declarations + has been produced. */ + typedef struct GTY(()) alias_pair { tree decl; tree target; - int emitted_diags; /* alias_diags already emitted for this pair. */ } alias_pair; /* Define gc'd vector type. */ @@ -5691,24 +5680,8 @@ extern void mark_decl_referenced (tree); extern void notice_global_symbol (tree); extern void set_user_assembler_name (tree, const char *); extern void process_pending_assemble_externals (void); -extern void finish_aliases_1 (void); -extern void finish_aliases_2 (void); -extern void remove_unreachable_alias_pairs (void); extern bool decl_replaceable_p (tree); extern bool decl_binds_to_current_def_p (tree); - -/* Derived type for use by compute_visible_aliases and callers. A symbol - alias set is a pointer set into which we enter IDENTIFIER_NODES bearing - the canonicalised assembler-level symbol names corresponding to decls - and their aliases. */ -typedef struct pointer_set_t symbol_alias_set_t; - -extern void symbol_alias_set_destroy (symbol_alias_set_t *); -extern int symbol_alias_set_contains (const symbol_alias_set_t *, tree); -extern symbol_alias_set_t * propagate_aliases_backward (bool (*) - (tree, tree, void *), - void *); - /* In stmt.c */ extern void expand_computed_goto (tree); extern bool parse_output_constraint (const char **, int, int, int, diff --git a/gcc/varasm.c b/gcc/varasm.c index ce9e328..0984215 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -5435,7 +5435,7 @@ VEC(alias_pair,gc) *alias_pairs; or ASM_OUTPUT_DEF_FROM_DECLS. The function defines the symbol whose tree node is DECL to have the value of the tree node TARGET. */ -static void +void do_assemble_alias (tree decl, tree target) { /* Emulated TLS had better not get this var. */ @@ -5535,255 +5535,6 @@ do_assemble_alias (tree decl, tree target) #endif } - -/* Allocate and construct a symbol alias set. */ - -static symbol_alias_set_t * -symbol_alias_set_create (void) -{ - return pointer_set_create (); -} - -/* Destruct and free a symbol alias set. */ - -void -symbol_alias_set_destroy (symbol_alias_set_t *aset) -{ - pointer_set_destroy (aset); -} - -/* Test if a symbol alias set contains a given name. */ - -int -symbol_alias_set_contains (const symbol_alias_set_t *aset, tree t) -{ - /* We accept either a DECL or an IDENTIFIER directly. */ - if (TREE_CODE (t) != IDENTIFIER_NODE) - t = DECL_ASSEMBLER_NAME (t); - t = targetm.asm_out.mangle_assembler_name (IDENTIFIER_POINTER (t)); - return pointer_set_contains (aset, t); -} - -/* Enter a new name into a symbol alias set. */ - -static int -symbol_alias_set_insert (symbol_alias_set_t *aset, tree t) -{ - /* We accept either a DECL or an IDENTIFIER directly. */ - if (TREE_CODE (t) != IDENTIFIER_NODE) - t = DECL_ASSEMBLER_NAME (t); - t = targetm.asm_out.mangle_assembler_name (IDENTIFIER_POINTER (t)); - return pointer_set_insert (aset, t); -} - -/* IN_SET_P is a predicate function assuming to be taken - alias_pair->decl, alias_pair->target and DATA arguments. - - Compute set of aliases by including everything where TRIVIALLY_VISIBLE - predeicate is true and propagate across aliases such that when - alias DECL is included, its TARGET is included too. */ - -static symbol_alias_set_t * -propagate_aliases_forward (bool (*in_set_p) - (tree decl, tree target, void *data), - void *data) -{ - symbol_alias_set_t *set; - unsigned i; - alias_pair *p; - bool changed; - - set = symbol_alias_set_create (); - for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i) - if (in_set_p (p->decl, p->target, data)) - symbol_alias_set_insert (set, p->decl); - do - { - changed = false; - for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i) - if (symbol_alias_set_contains (set, p->decl) - && !symbol_alias_set_insert (set, p->target)) - changed = true; - } - while (changed); - - return set; -} - -/* Like propagate_aliases_forward but do backward propagation. */ - -symbol_alias_set_t * -propagate_aliases_backward (bool (*in_set_p) - (tree decl, tree target, void *data), - void *data) -{ - symbol_alias_set_t *set; - unsigned i; - alias_pair *p; - bool changed; - - /* We have to compute the set of set nodes including aliases - themselves. */ - set = symbol_alias_set_create (); - for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i) - if (in_set_p (p->decl, p->target, data)) - symbol_alias_set_insert (set, p->target); - do - { - changed = false; - for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i) - if (symbol_alias_set_contains (set, p->target) - && !symbol_alias_set_insert (set, p->decl)) - changed = true; - } - while (changed); - - return set; -} -/* See if the alias is trivially visible. This means - 1) alias is expoerted from the unit or - 2) alias is used in the code. - We assume that unused cgraph/varpool nodes has been - removed. - Used as callback for propagate_aliases. */ - -static bool -trivially_visible_alias (tree decl, tree target ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED) -{ - struct cgraph_node *fnode = NULL; - struct varpool_node *vnode = NULL; - - if (!TREE_PUBLIC (decl)) - { - if (TREE_CODE (decl) == FUNCTION_DECL) - fnode = cgraph_get_node (decl); - else - vnode = varpool_get_node (decl); - return vnode || fnode; - } - else - return true; -} - -/* See if the target of alias is defined in this unit. - Used as callback for propagate_aliases. */ - -static bool -trivially_defined_alias (tree decl ATTRIBUTE_UNUSED, - tree target, - void *data ATTRIBUTE_UNUSED) -{ - struct cgraph_node *fnode = NULL; - struct varpool_node *vnode = NULL; - - fnode = cgraph_node_for_asm (target); - vnode = (fnode == NULL) ? varpool_node_for_asm (target) : NULL; - return (fnode && fnode->analyzed) || (vnode && vnode->finalized); -} - -/* Remove the alias pairing for functions that are no longer in the call - graph. */ - -void -remove_unreachable_alias_pairs (void) -{ - symbol_alias_set_t *visible; - unsigned i; - alias_pair *p; - - if (alias_pairs == NULL) - return; - - /* We have to compute the set of visible nodes including aliases - themselves. */ - visible = propagate_aliases_forward (trivially_visible_alias, NULL); - - for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ) - { - if (!DECL_EXTERNAL (p->decl) - && !symbol_alias_set_contains (visible, p->decl)) - { - VEC_unordered_remove (alias_pair, alias_pairs, i); - continue; - } - - i++; - } - - symbol_alias_set_destroy (visible); -} - - -/* First pass of completing pending aliases. Make sure that cgraph knows - which symbols will be required. */ - -void -finish_aliases_1 (void) -{ - symbol_alias_set_t *defined; - unsigned i; - alias_pair *p; - - if (alias_pairs == NULL) - return; - - /* We have to compute the set of defined nodes including aliases - themselves. */ - defined = propagate_aliases_backward (trivially_defined_alias, NULL); - - FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p) - { - tree target_decl; - - target_decl = find_decl (p->target); - if (target_decl == NULL) - { - if (symbol_alias_set_contains (defined, p->target)) - continue; - - if (! (p->emitted_diags & ALIAS_DIAG_TO_UNDEF) - && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) - { - error ("%q+D aliased to undefined symbol %qE", - p->decl, p->target); - p->emitted_diags |= ALIAS_DIAG_TO_UNDEF; - } - } - else if (! (p->emitted_diags & ALIAS_DIAG_TO_EXTERN) - && DECL_EXTERNAL (target_decl) - /* We use local aliases for C++ thunks to force the tailcall - to bind locally. This is a hack - to keep it working do - the following (which is not strictly correct). */ - && (! TREE_CODE (target_decl) == FUNCTION_DECL - || ! DECL_VIRTUAL_P (target_decl)) - && ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl))) - { - error ("%q+D aliased to external symbol %qE", - p->decl, p->target); - p->emitted_diags |= ALIAS_DIAG_TO_EXTERN; - } - } - - symbol_alias_set_destroy (defined); -} - -/* Second pass of completing pending aliases. Emit the actual assembly. - This happens at the end of compilation and thus it is assured that the - target symbol has been emitted. */ - -void -finish_aliases_2 (void) -{ - unsigned i; - alias_pair *p; - - FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p) - do_assemble_alias (p->decl, p->target); - - VEC_truncate (alias_pair, alias_pairs, 0); -} - /* Emit an assembler directive to make the symbol for DECL an alias to the symbol for TARGET. */ @@ -5845,14 +5596,14 @@ assemble_alias (tree decl, tree target) target_decl = find_decl (target); else target_decl= NULL; - if (target_decl && TREE_ASM_WRITTEN (target_decl)) + if ((target_decl && TREE_ASM_WRITTEN (target_decl)) + || cgraph_state >= CGRAPH_STATE_EXPANSION) do_assemble_alias (decl, target); else { alias_pair *p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL); p->decl = decl; p->target = target; - p->emitted_diags = ALIAS_DIAG_NONE; } } diff --git a/gcc/varpool.c b/gcc/varpool.c index ceb16f9..a1a2690 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -270,7 +270,7 @@ assemble_aliases (struct varpool_node *node) if (ref->use == IPA_REF_ALIAS) { struct varpool_node *alias = ipa_ref_referring_varpool_node (ref); - assemble_alias (alias->symbol.decl, + do_assemble_alias (alias->symbol.decl, DECL_ASSEMBLER_NAME (alias->alias_of)); assemble_aliases (alias); } @@ -349,7 +349,6 @@ varpool_remove_unreferenced_decls (void) if (cgraph_dump_file) fprintf (cgraph_dump_file, "Trivially needed variables:"); - finish_aliases_1 (); FOR_EACH_DEFINED_VARIABLE (node) { if (node->analyzed |