diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-07-24 00:16:16 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-07-24 00:16:16 +0000 |
commit | 05806473a2ed27962584c347e1b87910b3078f29 (patch) | |
tree | 20047ee6f873662157a0d8d8f27ffbacb9260691 /gcc/cgraphunit.c | |
parent | a8916fc15d8375ed837c479c02b0417f553c3065 (diff) | |
download | gcc-05806473a2ed27962584c347e1b87910b3078f29.tar.gz |
PR c/25795
PR c++/27369
* cgraph.c (cgraph_varpool_nodes): Export.
(decide_is_variable_needed): Ignored "used" attribute in
unit-at-a-time mode.
* cgraph.h (cgraph_varpool_nodes): Declare.
* cgraphunit.c (decide_is_function_needed): Ignored "used" attribute in
unit-at-a-time mode.
* gcc.dg/pr25795.c: New test.
* gcc.dg/pr25795-1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115693 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraphunit.c')
-rw-r--r-- | gcc/cgraphunit.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index d02ead5fcff..c0e41495ac9 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -198,8 +198,10 @@ decide_is_function_needed (struct cgraph_node *node, tree decl) } /* If the user told us it is used, then it must be so. */ - if (node->local.externally_visible - || lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + if (node->local.externally_visible) + return true; + + if (!flag_unit_at_a_time && lookup_attribute ("used", DECL_ATTRIBUTES (decl))) return true; /* ??? If the assembler name is set by hand, it is possible to assemble @@ -937,6 +939,71 @@ cgraph_analyze_function (struct cgraph_node *node) current_function_decl = NULL; } +/* Look for externally_visible and used attributes and mark cgraph nodes + accordingly. + + We cannot mark the nodes at the point the attributes are processed (in + handle_*_attribute) because the copy of the declarations available at that + point may not be canonical. For example, in: + + void f(); + void f() __attribute__((used)); + + the declaration we see in handle_used_attribute will be the second + declaration -- but the front end will subsequently merge that declaration + with the original declaration and discard the second declaration. + + Furthermore, we can't mark these nodes in cgraph_finalize_function because: + + void f() {} + void f() __attribute__((externally_visible)); + + is valid. + + So, we walk the nodes at the end of the translation unit, applying the + attributes at that point. */ + +static void +process_function_and_variable_attributes (struct cgraph_node *first, + struct cgraph_varpool_node *first_var) +{ + struct cgraph_node *node; + struct cgraph_varpool_node *vnode; + + for (node = cgraph_nodes; node != first; node = node->next) + { + tree decl = node->decl; + if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + { + mark_decl_referenced (decl); + if (node->local.finalized) + cgraph_mark_needed_node (node); + } + if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) + { + if (node->local.finalized) + cgraph_mark_needed_node (node); + node->externally_visible = true; + } + } + for (vnode = cgraph_varpool_nodes; vnode != first_var; vnode = vnode->next) + { + tree decl = vnode->decl; + if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) + { + mark_decl_referenced (decl); + if (vnode->finalized) + cgraph_varpool_mark_needed_node (vnode); + } + if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) + { + if (vnode->finalized) + cgraph_varpool_mark_needed_node (vnode); + vnode->externally_visible = true; + } + } +} + /* Analyze the whole compilation unit once it is parsed completely. */ void @@ -946,6 +1013,7 @@ cgraph_finalize_compilation_unit (void) /* Keep track of already processed nodes when called multiple times for intermodule optimization. */ static struct cgraph_node *first_analyzed; + static struct cgraph_varpool_node *first_analyzed_var; finish_aliases_1 (); @@ -963,6 +1031,7 @@ cgraph_finalize_compilation_unit (void) } timevar_push (TV_CGRAPH); + process_function_and_variable_attributes (first_analyzed, first_analyzed_var); cgraph_varpool_analyze_pending_decls (); if (cgraph_dump_file) { @@ -1047,6 +1116,7 @@ cgraph_finalize_compilation_unit (void) dump_cgraph (cgraph_dump_file); } first_analyzed = cgraph_nodes; + first_analyzed_var = cgraph_varpool_nodes; ggc_collect (); timevar_pop (TV_CGRAPH); } |