This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

variable pool for unit-at-a-time C/objC


Hi,
this patch implements new variable pool - datastructure with interface
symmetric to cgraph that is used to hold global variables.  At the moment it
just implements the interface and reachability analysis (via checking what
assembly names has been output and what variables are needed by functions
to be expanded in cgraphunit), so it can deal with cyclic references dead
from outside like:

static char *a=(char *)&b;
static char *b=(char *)&a;

That is probably not big deal.  It is mostly usefull to make C++ transition
easier, but I would like to implement some simple optimizations, like
constification of variables never writen to and unification of the same objects
whose address is never taken.

Regtested/bootstrapped i386/mainline together with the previous patch to
cleanup unit-at-a-time.  OK?

Honza

Fri Jun 20 00:32:49 CEST 2003  Jan Hubicka  <jh@suse.cz>
	* Makefile.in (varpool.o): New object file.
	* cgraphunit.c: Include varpool.h
	(record_call_1): Mark needed variables.
	(cgraph_finalize_compilation_unit): Assemble variables.
	* langhooks-def.h (LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE): New macro.
	* langhooks.h (lang_hooks_for_decls): Add prepare_assemble_variable.
	* varasm.c: Include varpool.h
	(assemble_variable): Call the new hook.
	(assemble_name): Mark needed variable.
	* toplev.c: Include varpool.h
	(flag_deffer_variables): New flag.
	(wrapup_global_declarations): Deal with varpool.
	(rest_of_decl_compilation): Varpoolize static and extern variables.
	(process_options): Default flag_deffer_variables with
	flag_unit_at_a_time.
	* varpool.c: New file.
	* varpool.h: Likewise.
diff -Nrc3p gcc.med/cgraphunit.c gcc/cgraphunit.c
*** gcc.med/cgraphunit.c	Fri Jun 20 00:27:08 2003
--- gcc/cgraphunit.c	Thu Jun 19 18:09:10 2003
*************** Software Foundation, 59 Temple Place - S
*** 33,38 ****
--- 33,39 ----
  #include "debug.h"
  #include "target.h"
  #include "cgraph.h"
+ #include "varpool.h"
  #include "diagnostic.h"
  
  static void cgraph_expand_functions PARAMS ((void));
*************** record_call_1 (tp, walk_subtrees, data)
*** 94,99 ****
--- 95,102 ----
       int *walk_subtrees;
       void *data;
  {
+   if (TREE_CODE (*tp) == VAR_DECL && (TREE_STATIC (*tp) || DECL_EXTERNAL (*tp)))
+     varpool_mark_needed_node (varpool_node (*tp));
    /* Record dereferences to the functions.  This makes the functions
       reachable unconditionally.  */
    if (TREE_CODE (*tp) == ADDR_EXPR)
*************** cgraph_finalize_compilation_unit ()
*** 151,159 ****
  {
    struct cgraph_node *node;
    struct cgraph_edge *edge;
!   bool collect = false;
  
!   if (lang_hooks.callgraph.collect_functions)
      collect = (*lang_hooks.callgraph.collect_functions) ();
  
    if (!quiet_flag)
--- 154,163 ----
  {
    struct cgraph_node *node;
    struct cgraph_edge *edge;
!   bool collect = lang_hooks.callgraph.collect_functions;
  
!   varpool_assemble_pending_decls ();
!   while (collect && !cgraph_nodes_queue)
      collect = (*lang_hooks.callgraph.collect_functions) ();
  
    if (!quiet_flag)
*************** cgraph_finalize_compilation_unit ()
*** 200,206 ****
              cgraph_mark_needed_node (edge->callee, 0);
  	}
        node->lowered = true;
!       if (!cgraph_nodes_queue && collect)
  	collect = (*lang_hooks.callgraph.collect_functions) ();
      }
    /* Collect entry points to the unit.  */
--- 204,211 ----
              cgraph_mark_needed_node (edge->callee, 0);
  	}
        node->lowered = true;
!       varpool_assemble_pending_decls ();
!       while (!cgraph_nodes_queue && collect)
  	collect = (*lang_hooks.callgraph.collect_functions) ();
      }
    /* Collect entry points to the unit.  */
diff -Nrc3p gcc.med/langhooks-def.h gcc/langhooks-def.h
*** gcc.med/langhooks-def.h	Fri Jun 20 00:27:08 2003
--- gcc/langhooks-def.h	Thu Jun 19 22:11:43 2003
*************** int lhd_tree_dump_type_quals			PARAMS ((
*** 226,231 ****
--- 226,232 ----
  #define LANG_HOOKS_GETDECLS	getdecls
  #define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL lhd_warn_unused_global_decl
  #define LANG_HOOKS_WRITE_GLOBALS write_global_declarations
+ #define LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE NULL
  
  #define LANG_HOOKS_DECLS { \
    LANG_HOOKS_PUSHLEVEL, \
*************** int lhd_tree_dump_type_quals			PARAMS ((
*** 236,242 ****
    LANG_HOOKS_PUSHDECL, \
    LANG_HOOKS_GETDECLS, \
    LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
!   LANG_HOOKS_WRITE_GLOBALS \
  }
  
  /* The whole thing.  The structure is defined in langhooks.h.  */
--- 237,244 ----
    LANG_HOOKS_PUSHDECL, \
    LANG_HOOKS_GETDECLS, \
    LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL, \
!   LANG_HOOKS_WRITE_GLOBALS, \
!   LANG_HOOKS_PREPARE_ASSEMBLE_VARIABLE \
  }
  
  /* The whole thing.  The structure is defined in langhooks.h.  */
diff -Nrc3p gcc.med/langhooks.h gcc/langhooks.h
*** gcc.med/langhooks.h	Fri Jun 20 00:27:08 2003
--- gcc/langhooks.h	Thu Jun 19 22:09:16 2003
*************** struct lang_hooks_for_decls
*** 184,189 ****
--- 184,192 ----
    /* Obtain a list of globals and do final output on them at end
       of compilation */
    void (*final_write_globals) PARAMS ((void));
+ 
+   /* Do necessary preparations before assemble_variable can proceed.  */
+   void (*prepare_assemble_variable) PARAMS ((tree));
  };
  
  /* Language-specific hooks.  See langhooks-def.h for defaults.  */
diff -Nrc3p gcc.med/varasm.c gcc/varasm.c
*** gcc.med/varasm.c	Fri Jun 20 00:27:08 2003
--- gcc/varasm.c	Thu Jun 19 22:13:44 2003
*************** Software Foundation, 59 Temple Place - S
*** 49,54 ****
--- 49,55 ----
  #include "debug.h"
  #include "target.h"
  #include "cgraph.h"
+ #include "varpool.h"
  
  #ifdef XCOFF_DEBUGGING_INFO
  #include "xcoffout.h"		/* Needed for external data
*************** assemble_variable (decl, top_level, at_e
*** 1410,1415 ****
--- 1411,1419 ----
    int reloc = 0;
    rtx decl_rtl;
  
+   if (lang_hooks.decls.prepare_assemble_variable)
+     (*lang_hooks.decls.prepare_assemble_variable) (decl);
+ 
    last_assemble_variable_decl = 0;
  
    /* Normally no need to say anything here for external references,
*************** assemble_name (file, name)
*** 1745,1756 ****
    id = maybe_get_identifier (real_name);
    if (id)
      {
!       if (!TREE_SYMBOL_REFERENCED (id)
! 	  && !cgraph_global_info_ready)
  	{
! 	  struct cgraph_node *node = cgraph_node_for_identifier (id);
! 	  if (node)
! 	    cgraph_mark_needed_node (node, 1);
  	}
        TREE_SYMBOL_REFERENCED (id) = 1;
      }
--- 1749,1766 ----
    id = maybe_get_identifier (real_name);
    if (id)
      {
!       if (!TREE_SYMBOL_REFERENCED (id))
  	{
!           struct varpool_node *vnode = varpool_node_for_identifier (id);
! 	  if (vnode)
! 	    varpool_mark_needed_node (vnode);
! 
! 	  if (!cgraph_global_info_ready)
! 	    {
! 	      struct cgraph_node *node = cgraph_node_for_identifier (id);
! 	      if (node)
! 		cgraph_mark_needed_node (node, 1);
! 	    }
  	}
        TREE_SYMBOL_REFERENCED (id) = 1;
      }
*** gcc.med/toplev.c	Fri Jun 20 00:25:42 2003
--- gcc/toplev.c	Fri Jun 20 00:31:35 2003
*************** Software Foundation, 59 Temple Place - S
*** 76,81 ****
--- 76,82 ----
  #include "cfgloop.h"
  #include "hosthooks.h"
  #include "cgraph.h"
+ #include "varpool.h"
  #include "opts.h"
  
  #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
*************** int flag_tracer = 0;
*** 955,960 ****
--- 956,965 ----
  
  int flag_unit_at_a_time = 0;
  
+ /* Nonzero if we should deffer output of variables to the end of
+    compilation.  */
+ int flag_deffer_variables = 0;
+ 
  /* Values of the -falign-* flags: how much to align labels in code.
     0 means `use default', 1 means `don't align'.
     For each variable, there is an _log variant which is the power
*************** wrapup_global_declarations (tree *vec, i
*** 2003,2015 ****
      {
        decl = vec[i];
  
        /* We're not deferring this any longer.  Assignment is
  	 conditional to avoid needlessly dirtying PCH pages.  */
!       if (DECL_DEFER_OUTPUT (decl) != 0)
! 	DECL_DEFER_OUTPUT (decl) = 0;
! 
!       if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0)
! 	(*lang_hooks.finish_incomplete_decl) (decl);
      }
  
    /* Now emit any global variables or functions that we have been
--- 2008,2024 ----
      {
        decl = vec[i];
  
+       if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0)
+         (*lang_hooks.finish_incomplete_decl) (decl);
+ 
        /* We're not deferring this any longer.  Assignment is
  	 conditional to avoid needlessly dirtying PCH pages.  */
!       if (DECL_DEFER_OUTPUT (decl) != 0 && TREE_CODE (decl) == VAR_DECL)
! 	{
! 	  DECL_DEFER_OUTPUT (decl) = 0;
! 	  if (flag_deffer_variables)
! 	    rest_of_decl_compilation (decl, NULL, 1, 1);
! 	}
      }
  
    /* Now emit any global variables or functions that we have been
*************** wrapup_global_declarations (tree *vec, i
*** 2050,2056 ****
  	     to force a constant to be written if and only if it is
  	     defined in a main file, as opposed to an include file.  */
  
! 	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl))
  	    {
  	      bool needed = 1;
  
--- 2059,2066 ----
  	     to force a constant to be written if and only if it is
  	     defined in a main file, as opposed to an include file.  */
  
! 	  if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
! 	      && !flag_deffer_variables)
  	    {
  	      bool needed = 1;
  
*************** wrapup_global_declarations (tree *vec, i
*** 2087,2092 ****
--- 2097,2105 ----
      }
    while (reconsider);
  
+   if (flag_deffer_variables)
+     output_something |= varpool_assemble_pending_decls ();
+ 
    return output_something;
  }
  
*************** rest_of_decl_compilation (tree decl,
*** 2326,2332 ****
        /* Don't output anything when a tentative file-scope definition
  	 is seen.  But at end of compilation, do output code for them.  */
        if (at_end || !DECL_DEFER_OUTPUT (decl))
! 	assemble_variable (decl, top_level, at_end, 0);
  
  #ifdef ASM_FINISH_DECLARE_OBJECT
        if (decl == last_assemble_variable_decl)
--- 2354,2366 ----
        /* Don't output anything when a tentative file-scope definition
  	 is seen.  But at end of compilation, do output code for them.  */
        if (at_end || !DECL_DEFER_OUTPUT (decl))
! 	{
! 	  if (flag_deffer_variables && TREE_CODE (decl) != FUNCTION_DECL
! 	      && top_level)
! 	    varpool_finalize_decl (decl);
! 	  else
! 	    assemble_variable (decl, top_level, at_end, 0);
! 	}
  
  #ifdef ASM_FINISH_DECLARE_OBJECT
        if (decl == last_assemble_variable_decl)
*************** process_options (void)
*** 5459,5464 ****
--- 5493,5501 ----
    if (flag_unit_at_a_time && ! lang_hooks.callgraph.expand_function)
      flag_unit_at_a_time = 0;
  
+   if (flag_unit_at_a_time)
+     flag_deffer_variables = 1;
+ 
    /* Warn about options that are not supported on this machine.  */
  #ifndef INSN_SCHEDULING
    if (flag_schedule_insns || flag_schedule_insns_after_reload)
diff -Nrc3p gcc.med/Makefile.in gcc/Makefile.in
*** gcc.med/Makefile.in	Fri Jun 20 00:26:16 2003
--- gcc/Makefile.in	Thu Jun 19 17:31:16 2003
*************** OBJS = alias.o bb-reorder.o bitmap.o bui
*** 822,828 ****
   stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
   tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
   alloc-pool.o et-forest.o cgraph.o cgraphunit.o cfghooks.o		   \
!  $(GGC) $(out_object_file) $(EXTRA_OBJS) $(host_hook_obj)
  
  BACKEND = main.o libbackend.a
  
--- 822,828 ----
   stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
   tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
   alloc-pool.o et-forest.o cgraph.o cgraphunit.o cfghooks.o		   \
!  varpool.o $(GGC) $(out_object_file) $(EXTRA_OBJS) $(host_hook_obj)
  
  BACKEND = main.o libbackend.a
  
*************** toplev.o : toplev.c $(CONFIG_H) $(SYSTEM
*** 1489,1495 ****
     graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) $(lang_options_files) \
     ssa.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
     langhooks.h insn-flags.h options_.h cfglayout.h real.h cfgloop.h \
!    hosthooks.h $(LANGHOOKS_DEF_H) cgraph.h
  	$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
  	  -DTARGET_NAME=\"$(target_alias)\" \
  	  -c $(srcdir)/toplev.c $(OUTPUT_OPTION)
--- 1489,1495 ----
     graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) $(lang_options_files) \
     ssa.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
     langhooks.h insn-flags.h options_.h cfglayout.h real.h cfgloop.h \
!    hosthooks.h $(LANGHOOKS_DEF_H) cgraph.h varpool.h
  	$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
  	  -DTARGET_NAME=\"$(target_alias)\" \
  	  -c $(srcdir)/toplev.c $(OUTPUT_OPTION)
*************** simplify-rtx.o : simplify-rtx.c $(CONFIG
*** 1595,1600 ****
--- 1595,1602 ----
     output.h function.h $(GGC_H) $(OBSTACK_H) $(TM_P_H) $(TREE_H) $(TARGET_H)
  cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     langhooks.h tree-inline.h toplev.h flags.h ggc.h  $(TARGET_H) cgraph.h gt-cgraph.h
+ varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+    langhooks.h tree-inline.h toplev.h flags.h ggc.h  $(TARGET_H) varpool.h gt-varpool.h
  cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     langhooks.h tree-inline.h toplev.h flags.h ggc.h  $(TARGET_H) cgraph.h
  coverage.o : coverage.c gcov-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
*************** GTFILES = $(srcdir)/input.h $(srcdir)/co
*** 1997,2003 ****
    $(srcdir)/profile.c $(srcdir)/ra-build.c $(srcdir)/regclass.c \
    $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c \
    $(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
!   $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
    $(out_file) \
    @all_gtfiles@
  
--- 1999,2005 ----
    $(srcdir)/profile.c $(srcdir)/ra-build.c $(srcdir)/regclass.c \
    $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c \
    $(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
!   $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c $(srcdir)/varpool.c \
    $(out_file) \
    @all_gtfiles@
  
*************** gt-expr.h gt-sdbout.h gt-optabs.h gt-bit
*** 2014,2020 ****
  gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \
  gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
  gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-input.h gt-cfglayout.h \
! gt-stringpool.h : s-gtype ; @true
  
  gtyp-gen.h: Makefile
  	echo "/* This file is machine generated.  Do not edit.  */" > tmp-gtyp.h
--- 2016,2022 ----
  gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \
  gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \
  gt-c-pragma.h gt-c-objc-common.h gtype-c.h gt-input.h gt-cfglayout.h \
! gt-stringpool.h gt-varpool.h : s-gtype ; @true
  
  gtyp-gen.h: Makefile
  	echo "/* This file is machine generated.  Do not edit.  */" > tmp-gtyp.h
*** a	Fri Jun 20 00:34:09 2003
--- gcc/varpool.c	Thu Jun 19 21:53:26 2003
***************
*** 0 ****
--- 1,211 ----
+ /* Variable management code.
+    Copyright (C) 2003 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
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ 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, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "tree.h"
+ #include "tree-inline.h"
+ #include "langhooks.h"
+ #include "hashtab.h"
+ #include "toplev.h"
+ #include "flags.h"
+ #include "ggc.h"
+ #include "debug.h"
+ #include "target.h"
+ #include "varpool.h"
+ #include "varray.h"
+ #include "output.h"
+ 
+ /* The known declarations must not get garbage collected.  Value graph
+    datastructures should not get saved via PCH code since this would
+    make it difficult to extend into intra-module optimizer later.  So
+    we store only the references into the array to prevent gabrage
+    collector from deleting live data.  */
+ static GTY(()) varray_type known_decls;
+ 
+ /* Hash table used to convert declarations into nodes.  */
+ static htab_t varpool_hash = 0;
+ 
+ /* The linked list of cgraph nodes.  */
+ struct varpool_node *varpool_nodes;
+ 
+ /* Queue of cgraph nodes scheduled to be lowered and output.  */
+ struct varpool_node *varpool_nodes_queue;
+ 
+ /* Number of nodes in existence.  */
+ int varpool_n_nodes;
+ 
+ /* Returns a hash code for P.  */
+ 
+ static hashval_t
+ varpool_hash_node (const PTR p)
+ {
+   return (hashval_t)
+     htab_hash_pointer (DECL_ASSEMBLER_NAME
+ 		       (((struct varpool_node *) p)->decl));
+ }
+ 
+ /* Returns non-zero if P1 and P2 are equal.  */
+ 
+ static int
+ eq_varpool_node (const PTR p1, const PTR p2)
+ {
+   return ((DECL_ASSEMBLER_NAME (((struct varpool_node *) p1)->decl)) ==
+ 	  (tree) p2);
+ }
+ 
+ /* Return varpool node assigned to DECL.  Create new one when needed.  */
+ struct varpool_node *
+ varpool_node (tree decl)
+ {
+   struct varpool_node *node;
+   struct varpool_node **slot;
+ 
+   if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
+     abort ();
+ 
+   if (!varpool_hash)
+     {
+       varpool_hash = htab_create (10, varpool_hash_node, eq_varpool_node, NULL);
+       VARRAY_TREE_INIT (known_decls, 32, "known_decls");
+     }
+ 
+   slot =
+     (struct varpool_node **) htab_find_slot_with_hash (varpool_hash,
+ 						      DECL_ASSEMBLER_NAME (decl),
+ 						      htab_hash_pointer
+ 						      (DECL_ASSEMBLER_NAME
+ 						       (decl)), 1);
+   if (*slot)
+     return *slot;
+   node = xcalloc (sizeof (*node), 1);
+   node->decl = decl;
+   node->next = varpool_nodes;
+   if (varpool_nodes)
+     varpool_nodes->previous = node;
+   node->previous = NULL;
+   varpool_nodes = node;
+   varpool_n_nodes++;
+   *slot = node;
+   VARRAY_PUSH_TREE (known_decls, decl);
+   return node;
+ }
+ 
+ /* Try to find existing function for identifier ID.  */
+ struct varpool_node *
+ varpool_node_for_identifier (tree id)
+ {
+   struct varpool_node **slot;
+ 
+   if (TREE_CODE (id) != IDENTIFIER_NODE)
+     abort ();
+ 
+   if (!varpool_hash)
+     {
+       varpool_hash = htab_create (10, varpool_hash_node, eq_varpool_node, NULL);
+       VARRAY_TREE_INIT (known_decls, 32, "known_decls");
+     }
+ 
+   slot =
+     (struct varpool_node **) htab_find_slot_with_hash (varpool_hash, id,
+ 						      htab_hash_pointer (id), 0);
+   if (!slot)
+     return NULL;
+   return *slot;
+ }
+ 
+ /* Notify finalize_compilation_unit that given node is reachable
+    or needed.  */
+ void
+ varpool_mark_needed_node (struct varpool_node *node)
+ {
+   if (!node->needed && node->finalized)
+     {
+       node->needed = 1;
+       node->aux = varpool_nodes_queue;
+       varpool_nodes_queue = node;
+     }
+ }
+ 
+ void
+ varpool_finalize_decl (tree decl)
+ {
+   struct varpool_node *node = varpool_node (decl);
+ 
+   node->finalized = true;
+ 
+   if (/* Externally visible variables must be output.  The exception are
+ 	 COMDAT functions that must be output only when they are needed.
+ 	 Similarly are handled defered functions and
+ 	 external functions (GCC extension "extern inline") */
+       (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)
+        && !DECL_DEFER_OUTPUT (decl))
+       /* Function whose name is output to the assembler file must be produced.
+ 	 It is possible to assemble the name later after finalizing the function
+ 	 and the fact is noticed in assemble_name then.  */
+       || (DECL_ASSEMBLER_NAME_SET_P (decl)
+ 	  && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
+     {
+       varpool_mark_needed_node (node);
+     }
+ }
+ 
+ bool
+ varpool_assemble_pending_decls ()
+ {
+   bool changed = false;
+ 
+   while (varpool_nodes_queue)
+     {
+       tree decl = varpool_nodes_queue->decl;
+       struct varpool_node *node = varpool_nodes_queue;
+ 
+       varpool_nodes_queue = varpool_nodes_queue->aux;
+       if (!TREE_ASM_WRITTEN (decl) && !DECL_DEFER_OUTPUT (decl))
+ 	{
+ 	  assemble_variable (decl, 0, 1, 0);
+ 	  changed = true;
+ 	}
+       node->aux = NULL;
+     }
+   return changed;
+ }
+ 
+ /* Dump the callgraph.  */
+ 
+ void
+ dump_varpool (FILE *f)
+ {
+   struct varpool_node *node;
+ 
+   fprintf (f, "\nKnown values:\n\n");
+   for (node = varpool_nodes; node; node = node->next)
+     {
+       fprintf (f, "%s", IDENTIFIER_POINTER (DECL_NAME (node->decl)));
+       if (node->needed)
+ 	fprintf (f, " needed");
+       fprintf (f, "\n");
+     }
+ }
+ 
+ #include "gt-varpool.h"
*** a	Fri Jun 20 00:34:09 2003
--- gcc/varpool.h	Thu Jun 19 19:29:13 2003
***************
*** 0 ****
--- 1,57 ----
+ /* Variable management code.
+    Copyright (C) 2003 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
+ version.
+ 
+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ 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, 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.  */
+ 
+ #ifndef GCC_VGRAPH_H
+ #define GCC_VGRAPH_H
+ 
+ /* The varpool data strutcture.
+    Each function decl has assigned varpool_node listing calees and callers.  */
+ 
+ struct varpool_node
+ {
+   tree decl;
+   struct varpool_node *next, *previous;
+   void *aux;
+ 
+   /* Set when function must be output - it is externally visible
+      or it's address is taken.  */
+   bool needed;
+   /* Set once it has been finalized so we consider it to be output.  */
+   bool finalized;
+   /* Set when function is scheduled to be assembled.  */
+   bool output;
+ };
+ 
+ extern struct varpool_node *varpool_nodes;
+ extern int varpool_n_nodes;
+ extern bool varpool_global_info_ready;
+ extern struct varpool_node *varpool_nodes_queue;
+ 
+ /* In varpool.c  */
+ void dump_varpool (FILE *);
+ void varpool_remove_node (struct varpool_node *);
+ struct varpool_node *varpool_node (tree decl);
+ struct varpool_node *varpool_node_for_identifier (tree id);
+ void varpool_mark_needed_node (struct varpool_node *);
+ void varpool_finalize_decl (tree);
+ bool varpool_assemble_pending_decls (void);
+ 
+ #endif  /* GCC_VGRAPH_H  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]