X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fvarpool.c;h=12cdad90e28006ed2d1cff1bb5f70d405b28d961;hb=50cb26651222ea939e524cd25a5bde2b152f8ce2;hp=7791ada4bc37a2560eea442aaead5aab9a0a6f33;hpb=11cc227f55cc657aa83852e7c3592db2a2e2d91b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/varpool.c b/gcc/varpool.c index 7791ada4bc3..12cdad90e28 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -1,12 +1,13 @@ /* Callgraph handling code. - Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. Contributed by Jan Hubicka This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -15,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -33,6 +33,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "debug.h" #include "target.h" #include "output.h" +#include "gimple.h" +#include "tree-flow.h" /* This file contains basic routines manipulating variable pool. @@ -56,10 +58,11 @@ struct varpool_node *varpool_nodes; The queue is maintained via mark_needed_node, linked via node->next_needed pointer. - LAST_NNEDED_NODE points to the end of queue, so it can be maintained in forward - order. QTY is needed to make it friendly to PCH. + LAST_NEEDED_NODE points to the end of queue, so it can be + maintained in forward order. GTY is needed to make it friendly to + PCH. - During unit-at-a-time compilation we construct the queue of needed variables + During compilation we construct the queue of needed variables twice: first time it is during cgraph construction, second time it is at the end of compilation in VARPOOL_REMOVE_UNREFERENCED_DECLS so we can avoid optimized out variables being output. @@ -157,10 +160,18 @@ dump_varpool (FILE *f) struct varpool_node *node; fprintf (f, "variable pool:\n\n"); - for (node = varpool_nodes; node; node = node->next_needed) + for (node = varpool_nodes; node; node = node->next) dump_varpool_node (f, node); } +/* Dump the variable pool to stderr. */ + +void +debug_varpool (void) +{ + dump_varpool (stderr); +} + /* Given an assembler name, lookup node. */ struct varpool_node * varpool_node_for_asm (tree asmname) @@ -212,17 +223,13 @@ varpool_reset_queue (void) /* Determine if variable DECL is needed. That is, visible to something either outside this translation unit, something magic in the system - configury, or (if not doing unit-at-a-time) to something we haven't - seen yet. */ + configury */ bool decide_is_variable_needed (struct varpool_node *node, tree decl) { /* If the user told us it is used, then it must be so. */ if (node->externally_visible || node->force_output) 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 the name later after finalizing the function and the fact is noticed @@ -255,7 +262,7 @@ decide_is_variable_needed (struct varpool_node *node, tree decl) /* When not reordering top level variables, we have to assume that we are going to keep everything. */ - if (flag_unit_at_a_time && flag_toplevel_reorder) + if (flag_toplevel_reorder) return false; /* We want to emit COMDAT variables only when absolutely necessary. */ @@ -278,7 +285,7 @@ varpool_finalize_decl (tree decl) if this function has already run. */ if (node->finalized) { - if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp)) + if (cgraph_global_info_ready) varpool_assemble_pending_decls (); return; } @@ -293,7 +300,7 @@ varpool_finalize_decl (tree decl) there. */ else if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) varpool_mark_needed_node (node); - if (cgraph_global_info_ready || (!flag_unit_at_a_time && !flag_openmp)) + if (cgraph_global_info_ready) varpool_assemble_pending_decls (); } @@ -355,7 +362,13 @@ varpool_assemble_decl (struct varpool_node *node) && (TREE_CODE (decl) != VAR_DECL || !DECL_HAS_VALUE_EXPR_P (decl))) { assemble_variable (decl, 0, 1, 0); - return TREE_ASM_WRITTEN (decl); + if (TREE_ASM_WRITTEN (decl)) + { + node->next_needed = varpool_assembled_nodes_queue; + varpool_assembled_nodes_queue = node; + node->finalized = 1; + return true; + } } return false; @@ -421,12 +434,7 @@ varpool_assemble_pending_decls (void) varpool_nodes_queue = varpool_nodes_queue->next_needed; if (varpool_assemble_decl (node)) - { - changed = true; - node->next_needed = varpool_assembled_nodes_queue; - varpool_assembled_nodes_queue = node; - node->finalized = 1; - } + changed = true; else node->next_needed = NULL; } @@ -436,27 +444,48 @@ varpool_assemble_pending_decls (void) return changed; } -/* Output all variables enqueued to be assembled. */ +/* Remove all elements from the queue so we can re-use it for debug output. */ void -varpool_output_debug_info (void) +varpool_empty_needed_queue (void) +{ + /* EH might mark decls as needed during expansion. This should be safe since + we don't create references to new function, but it should not be used + elsewhere. */ + varpool_analyze_pending_decls (); + + while (varpool_nodes_queue) + { + struct varpool_node *node = varpool_nodes_queue; + varpool_nodes_queue = varpool_nodes_queue->next_needed; + node->next_needed = NULL; + } + /* varpool_nodes_queue is now empty, clear the pointer to the last element + in the queue. */ + varpool_last_needed_node = NULL; +} + +/* Create a new global variable of type TYPE. */ +tree +add_new_static_var (tree type) { - timevar_push (TV_SYMOUT); - if (errorcount == 0 && sorrycount == 0) - while (varpool_assembled_nodes_queue) - { - struct varpool_node *node = varpool_assembled_nodes_queue; - - /* Local static variables are never seen by check_global_declarations - so we need to output debug info by hand. */ - if (DECL_CONTEXT (node->decl) - && (TREE_CODE (DECL_CONTEXT (node->decl)) == BLOCK - || TREE_CODE (DECL_CONTEXT (node->decl)) == FUNCTION_DECL) - && errorcount == 0 && sorrycount == 0) - (*debug_hooks->global_decl) (node->decl); - varpool_assembled_nodes_queue = node->next_needed; - node->next_needed = 0; - } - timevar_pop (TV_SYMOUT); + tree new_decl; + struct varpool_node *new_node; + + new_decl = create_tmp_var (type, NULL); + DECL_NAME (new_decl) = create_tmp_var_name (NULL); + TREE_READONLY (new_decl) = 0; + TREE_STATIC (new_decl) = 1; + TREE_USED (new_decl) = 1; + DECL_CONTEXT (new_decl) = NULL_TREE; + DECL_ABSTRACT (new_decl) = 0; + lang_hooks.dup_lang_specific_decl (new_decl); + create_var_ann (new_decl); + new_node = varpool_node (new_decl); + varpool_mark_needed_node (new_node); + add_referenced_var (new_decl); + varpool_finalize_decl (new_decl); + + return new_node->decl; } #include "gt-varpool.h"