Configuring out obstacks

Zack Weinberg zack@wolery.cumb.org
Tue Jun 13 19:11:00 GMT 2000


This patch makes configure aware of which front ends still need the
obstack-based RTL and tree allocator.  If none of those front ends are
present in your tree, or you've shut them all off with
--enable-languages, then ggc_p becomes a compile time constant and the
obstack manipulation machinery is elided from tree.c.  The
permanent_obstack still exists, for the benefit of oballoc() and a few
other dark corners.

On x86, a cc1 compiled in this regime is about 17k smaller and 1%
faster than the normal cc1.  The speed gain will be due to avoiding
branches in the allocator fast path.

The patch touches so many files because the obstacks are now declared
in tree.h and rtl.h instead of individual source files.

I have bootstrapped a slight variant of this patch (it used a
different configury scheme and had some unnecessary changes in ch/) on
i386-linux, with and without --enable-languages=c,c++,objc,f77.  There
were no testsuite regressions in the --e-l case versus the normal
build, and no regressions versus the mainline in the C, Fortran, or
ObjC testsuites.  This is the set of failures for C++:

XPASS: g++.brendan/parse4.C referenced below (test for bogus messages, line 15)
FAIL: g++.ext/instantiate1.C not instantiated (test for errors, line 18)
FAIL: g++.ext/instantiate1.C not instantiated (test for errors, line 20)
FAIL: g++.jason/rfg27.C duplicate long (test for errors, line 2)
FAIL: g++.other/inline11.C (test for excess errors)
FAIL: g++.robertl/eb129a.C caused compiler crash

I'm not sure if any of those are regressions vs. mainline.

N.B.: The remaining integrated front ends that use obstacks are Chill
and Java.

zw

	* configure.in: If any config-lang.in sets need_obstacks,
	then define NEED_OBSTACKS in auto-host.h.
	* configure, config.in: Regenerate.

	* tree.c: If NEED_OBSTACKS is not defined, don't define any
	obstack except permanent_obstack, and elide almost all the
	code relating to obstack-based allocation of data.
	gcc_obstack_init, init_obstacks, oballoc, and obfree remain.

	* tree.h:  Declare all obstacks and obstack pointers here.
	If NEED_OBSTACKS is not defined then: Make
	TREE_PERMANENT always 0, TREE_SET_PERMANENT do nothing,
	TYPE_OBSTACK always 0.  Remove the 'obstack' slot from struct
	tree_type.  #define build_parse_node to build_nt.  #define
	build_decl_list and build_expr_list to build_tree_list.
	#define perm_tree_cons, temp_tree_cons, saveable_tree_cons,
	decl_tree_cons, expr_tree_cons to tree_cons.
	#define permalloc, savealloc, expralloc to xmalloc
	and perm_calloc to xcalloc.
	#define push_obstacks_nochange, permanent_allocation,
	push_momentary, clear_momentary, pop_momentary,
	suspend_momentary, resume_momentary, end_temporary_allocation,
	allocation_temporary_p, pop_obstacks, push_obstacks,
	pop_momentary_nofree, saveable_allocation,
	temporary_allocation, resume_temporary_allocation,
	debug_obstack, rtl_in_current_obstack,
	rtl_in_saveable_obstack, print_obstack_statistics, and
	print_obstack_name out of existence.  #define all other
	obstacks to permanent_obstack and all obstack pointers to
	&permanent_obstack.

	* function.h: Elide obstack entries in struct function,
	and #define save_tree_status and restore_tree_status out of
	existence, unless NEED_OBSTACKS.
	* ggc.h: If NEED_OBSTACKS is defined, declare ggc_p.
	Otherwise, #define it to 1.
	* rtl.h: If NEED_OBSTACK is defined, declare rtl_obstack
	here.  Otherwise, #define it to &permanent_obstack, declare
	permanent_obstack here, and #define push_obstacks and
	pop_obstacks out of existence.

	* bb-reorder.c, flow.c: Don't declare function_obstack.
	* emit-rtl.c: Don't declare rtl_obstack.
	* gengenrtl.c (in file generated): Don't declare rtl_obstack.
	* gensupport.h: Don't declare obstack or rtl_obstack.
	* integrate.c: Don't declare function_maybepermanent_obstack.
	* loop.c: Don't declare rtl_obstack.  Don't manipulate
	rtl_obstack unless NEED_OBSTACKS.
	* rtl.c: Don't declare rtl_obstack.
	* varasm.c: Don't declare current_obstack, saveable_obstack,
	rtl_obstack, or permanent_obstack.

	* genattrtab.c: Don't manipulate the rtl_obstack unless
	NEED_OBSTACKS.
	* gensupport.c: Define permanent_obstack not obstack.  Don't
	define rtl_obstack unless NEED_OBSTACKS.

	* c-decl.c: Define ggc_p only if NEED_OBSTACKS.
	* ggc-none.c: Likewise.

cp:
	* class.c, search.c: Don't declare current_obstack.
	* decl.c: Define ggc_p only if NEED_OBSTACKS.
f:
	* com.c: Define ggc_p only if NEED_OBSTACKS.
ch:
	* config-lang.in: Set need_obstacks=t.
java:
	* config-lang.in: Set need_obstacks=t.
	
===================================================================
Index: bb-reorder.c
--- bb-reorder.c	2000/06/11 04:29:46	1.17
+++ bb-reorder.c	2000/06/14 01:43:05
@@ -99,19 +99,9 @@
 #include "expr.h"
 #include "obstack.h"
 
-
 #ifndef HAVE_epilogue
 #define HAVE_epilogue 0
 #endif
-
-
-/* The contents of the current function definition are allocated
-   in this obstack, and all are freed at the end of the function.
-   For top-level functions, this is temporary_obstack.
-   Separate obstacks are made for nested functions.  */
-
-extern struct obstack *function_obstack;
-
 
 /* Structure to hold information about lexical scopes.  */
 typedef struct scope_def
===================================================================
Index: c-decl.c
--- c-decl.c	2000/06/07 22:43:44	1.121
+++ c-decl.c	2000/06/14 01:43:06
@@ -75,7 +75,9 @@ enum decl_context
 #endif
 
 /* Do GC.  */
+#ifdef NEED_OBSTACKS
 int ggc_p = 1;
+#endif
 
 /* Nonzero if we have seen an invalid cross reference
    to a struct, union, or enum, but not yet printed the message.  */
===================================================================
Index: configure.in
--- configure.in	2000/06/13 21:28:30	1.390
+++ configure.in	2000/06/14 01:43:09
@@ -4835,6 +4835,7 @@ all_outputs='Makefile intl/Makefile po/M
 all_lang_makefiles=
 all_headers=
 all_lib2funcs=
+all_need_obstacks=
 
 # Add the language fragments.
 # Languages are added via two mechanisms.  Some information must be
@@ -4859,6 +4860,7 @@ do
 		headers=
 		outputs=
 		lib2funcs=
+		need_obstacks=
 		. ${srcdir}/$s/config-lang.in
 		if test "x$language" = x
 		then
@@ -4881,8 +4883,18 @@ do
 			oldstyle_subdirs="$oldstyle_subdirs $s"
 		fi
 		all_lib2funcs="$all_lib2funcs $lib2funcs"
+		# This one has no space so it will be empty if no one
+		# sets need_obstacks.
+		all_need_obstacks="$all_need_obstacks$need_obstacks"
 	fi
 done
+
+# If any front end uses obstacks for RTL and trees, the back end must
+# handle both obstacks and GC.
+if test x"$all_need_obstacks" != x
+then	AC_DEFINE(NEED_OBSTACKS, 1,
+[Define if at least one front end uses obstacks to allocate RTL and trees.])
+fi
 
 # Since we can't use `::' targets, we link each language in
 # with a set of hooks, reached indirectly via lang.${target}.
===================================================================
Index: emit-rtl.c
--- emit-rtl.c	2000/06/13 21:47:38	1.136
+++ emit-rtl.c	2000/06/14 01:43:09
@@ -170,9 +170,6 @@ static rtx free_insn;
 #define last_filename (cfun->emit->x_last_filename)
 #define first_label_num (cfun->emit->x_first_label_num)
 
-/* This is where the pointer to the obstack being used for RTL is stored.  */
-extern struct obstack *rtl_obstack;
-
 static rtx make_jump_insn_raw		PARAMS ((rtx));
 static rtx make_call_insn_raw		PARAMS ((rtx));
 static rtx find_line_note		PARAMS ((rtx));
===================================================================
Index: flow.c
--- flow.c	2000/06/13 22:23:49	1.302
+++ flow.c	2000/06/14 01:43:11
@@ -162,13 +162,6 @@ Boston, MA 02111-1307, USA.  */
 #define HAVE_sibcall_epilogue 0
 #endif
 
-/* The contents of the current function definition are allocated
-   in this obstack, and all are freed at the end of the function.
-   For top-level functions, this is temporary_obstack.
-   Separate obstacks are made for nested functions.  */
-
-extern struct obstack *function_obstack;
-
 /* Number of basic blocks in the current function.  */
 
 int n_basic_blocks;
===================================================================
Index: function.h
--- function.h	2000/04/01 00:09:22	1.54
+++ function.h	2000/06/14 01:43:11
@@ -429,6 +429,7 @@ struct function
   struct var_refs_queue *fixup_var_refs_queue;
 
   /* For tree.c.  */
+#ifdef NEED_OBSTACKS
   int all_types_permanent;
   struct momentary_level *momentary_stack;
   char *maybepermanent_firstobj;
@@ -441,7 +442,8 @@ struct function
   struct obstack *expression_obstack;
   struct obstack *saveable_obstack;
   struct obstack *rtl_obstack;
-
+#endif
+  
   /* For integrate.c.  */
   int inlinable;
   /* This is in fact an rtvec.  */
@@ -584,8 +586,13 @@ extern void (*restore_lang_status)	PARAM
 extern void (*free_lang_status)         PARAMS ((struct function *));
 
 /* Save and restore status information for a nested function.  */
+#ifdef NEED_OBSTACKS
 extern void save_tree_status		PARAMS ((struct function *));
 extern void restore_tree_status		PARAMS ((struct function *));
+#else
+#define save_tree_status(x)		do { } while (0)
+#define restore_tree_status(x)		do { } while (0)
+#endif
 extern void restore_emit_status		PARAMS ((struct function *));
 extern void free_after_parsing		PARAMS ((struct function *));
 extern void free_after_compilation	PARAMS ((struct function *));
===================================================================
Index: genattrtab.c
--- genattrtab.c	2000/05/18 22:05:14	1.77
+++ genattrtab.c	2000/06/14 01:43:12
@@ -547,8 +547,10 @@ attr_rtx VPARAMS ((enum rtx_code code, .
   register rtx rt_val = NULL_RTX;/* RTX to return to caller...		*/
   int hashcode;
   register struct attr_hash *h;
+#ifdef NEED_OBSTACKS
   struct obstack *old_obstack = rtl_obstack;
-
+#endif
+  
   VA_START (p, code);
 
 #ifndef ANSI_PROTOTYPES
@@ -581,7 +583,9 @@ attr_rtx VPARAMS ((enum rtx_code code, .
 
       if (h == 0)
 	{
+#ifdef NEED_OBSTACKS
 	  rtl_obstack = hash_obstack;
+#endif
 	  rt_val = rtx_alloc (code);
 	  XEXP (rt_val, 0) = arg0;
 	}
@@ -613,7 +617,9 @@ attr_rtx VPARAMS ((enum rtx_code code, .
 
       if (h == 0)
 	{
+#ifdef NEED_OBSTACKS
 	  rtl_obstack = hash_obstack;
+#endif
 	  rt_val = rtx_alloc (code);
 	  XEXP (rt_val, 0) = arg0;
 	  XEXP (rt_val, 1) = arg1;
@@ -636,7 +642,9 @@ attr_rtx VPARAMS ((enum rtx_code code, .
 
       if (h == 0)
 	{
+#ifdef NEED_OBSTACKS
 	  rtl_obstack = hash_obstack;
+#endif
 	  rt_val = rtx_alloc (code);
 	  XSTR (rt_val, 0) = arg0;
 	}
@@ -658,7 +666,9 @@ attr_rtx VPARAMS ((enum rtx_code code, .
 
       if (h == 0)
 	{
+#ifdef NEED_OBSTACKS
 	  rtl_obstack = hash_obstack;
+#endif
 	  rt_val = rtx_alloc (code);
 	  XSTR (rt_val, 0) = arg0;
 	  XSTR (rt_val, 1) = arg1;
@@ -721,7 +731,9 @@ attr_rtx VPARAMS ((enum rtx_code code, .
       return rt_val;
     }
 
+#ifdef NEED_OBSTACKS
   rtl_obstack = old_obstack;
+#endif
   va_end (p);
   attr_hash_add_rtx (hashcode, rt_val);
   RTX_INTEGRATED_P (rt_val) = 1;
@@ -3501,7 +3513,9 @@ optimize_attrs ()
 	  something_changed = 0;
 	  for (iv = insn_code_values[i]; iv; iv = iv->next)
 	    {
+#ifdef NEED_OBSTACKS
 	      struct obstack *old = rtl_obstack;
+#endif
 	      char *spacer = (char *) obstack_finish (temp_obstack);
 
 	      attr = iv->attr;
@@ -3510,7 +3524,9 @@ optimize_attrs ()
 	      if (GET_CODE (av->value) != COND)
 		continue;
 
+#ifdef NEED_OBSTACKS
 	      rtl_obstack = temp_obstack;
+#endif
 #if 0 /* This was intended as a speed up, but it was slower.  */
 	      if (insn_n_alternatives[ie->insn_code] > 6
 		  && count_sub_rtxs (av->value, 200) >= 200)
@@ -3521,7 +3537,9 @@ optimize_attrs ()
 		newexp = simplify_cond (av->value, ie->insn_code,
 					ie->insn_index);
 
+#ifdef NEED_OBSTACKS
 	      rtl_obstack = old;
+#endif
 	      if (newexp != av->value)
 		{
 		  newexp = attr_copy_rtx (newexp);
===================================================================
Index: gengenrtl.c
--- gengenrtl.c	2000/06/12 22:45:46	1.36
+++ gengenrtl.c	2000/06/14 01:43:12
@@ -358,7 +358,6 @@ gencode ()
   puts ("#include \"obstack.h\"");
   puts ("#include \"rtl.h\"");
   puts ("#include \"ggc.h\"\n");
-  puts ("extern struct obstack *rtl_obstack;\n");
   puts ("#define obstack_alloc_rtx(n)					\\");
   puts ("    ((rtx) obstack_alloc (rtl_obstack,				\\");
   puts ("			  sizeof (struct rtx_def)		\\");
===================================================================
Index: gensupport.c
--- gensupport.c	2000/05/27 20:03:31	1.9
+++ gensupport.c	2000/06/14 01:43:12
@@ -25,9 +25,10 @@
 #include "errors.h"
 #include "gensupport.h"
 
-
-static struct obstack obstack;
-struct obstack *rtl_obstack = &obstack;
+struct obstack permanent_obstack;
+#ifdef NEED_OBSTACKS
+struct obstack *rtl_obstack = &permanent_obstack;
+#endif
 
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
===================================================================
Index: gensupport.h
--- gensupport.h	2000/05/06 22:30:13	1.2
+++ gensupport.h	2000/06/14 01:43:12
@@ -18,9 +18,6 @@ along with GNU CC; see the file COPYING.
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-struct obstack;
-extern struct obstack *rtl_obstack;
-
 extern int init_md_reader	PARAMS ((const char *));
 extern rtx read_md_rtx		PARAMS ((int *, int *));
 
===================================================================
Index: ggc-none.c
--- ggc-none.c	2000/06/09 21:47:38	1.8
+++ ggc-none.c	2000/06/14 01:53:25
@@ -33,7 +33,9 @@
 #include "ggc.h"
 
 /* For now, keep using the old obstack scheme in the gen* programs.  */
+#ifdef NEED_OBSTACKS
 int ggc_p = 0;
+#endif
 
 void *
 ggc_alloc (size)
===================================================================
Index: ggc.h
--- ggc.h	2000/06/09 21:47:38	1.28
+++ ggc.h	2000/06/14 01:43:12
@@ -26,7 +26,11 @@ Software Foundation, 59 Temple Place - S
 
 /* Language-specific code defines this variable to be either one (if
    it wants garbage collection), or zero (if it does not).  */
+#ifdef NEED_OBSTACKS
 extern int ggc_p;
+#else
+#define ggc_p 1
+#endif
 
 /* These structures are defined in various headers throughout the
    compiler.  However, rather than force everyone who includes this
===================================================================
Index: integrate.c
--- integrate.c	2000/06/03 01:57:45	1.109
+++ integrate.c	2000/06/14 01:43:13
@@ -46,8 +46,6 @@ Boston, MA 02111-1307, USA.  */
 #define	obstack_chunk_alloc	xmalloc
 #define	obstack_chunk_free	free
 
-extern struct obstack *function_maybepermanent_obstack;
-
 /* Similar, but round to the next highest integer that meets the
    alignment.  */
 #define CEIL_ROUND(VALUE,ALIGN)	(((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
===================================================================
Index: loop.c
--- loop.c	2000/05/28 20:01:28	1.255
+++ loop.c	2000/06/14 01:43:15
@@ -172,12 +172,12 @@ static int loop_max_reg;
    If we used the same obstack that it did, we would be deallocating
    that array.  */
 
+#ifdef NEED_OBSTACKS
 static struct obstack temp_obstack;
+#endif
 
 /* This is where the pointer to the obstack being used for RTL is stored.  */
 
-extern struct obstack *rtl_obstack;
-
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
@@ -378,8 +378,10 @@ init_loop ()
   /* Free the objects we just allocated.  */
   obfree (free_point);
 
+#ifdef NEED_OBSTACKS
   /* Initialize the obstack used for rtl in product_cheap_p.  */
   gcc_obstack_init (&temp_obstack);
+#endif
 }
 
 /* Compute the mapping from uids to luids.
@@ -7674,8 +7676,10 @@ product_cheap_p (a, b)
 {
   int i;
   rtx tmp;
+#ifdef NEED_OBSTACKS
   struct obstack *old_rtl_obstack = rtl_obstack;
   char *storage = (char *) obstack_alloc (&temp_obstack, 0);
+#endif
   int win = 1;
 
   /* If only one is constant, make it B.  */
@@ -7694,7 +7698,9 @@ product_cheap_p (a, b)
      code for the multiply and see if a call or multiply, or long sequence
      of insns is generated.  */
 
+#ifdef NEED_OBSTACKS
   rtl_obstack = &temp_obstack;
+#endif
   start_sequence ();
   expand_mult (GET_MODE (a), a, b, NULL_RTX, 0);
   tmp = gen_sequence ();
@@ -7731,11 +7737,13 @@ product_cheap_p (a, b)
 	   && GET_CODE (SET_SRC (XVECEXP (tmp, 0, 0))) == MULT)
     win = 0;
 
+#ifdef NEED_OBSTACKS
   /* Free any storage we obtained in generating this multiply and restore rtl
      allocation to its normal obstack.  */
   obstack_free (&temp_obstack, storage);
   rtl_obstack = old_rtl_obstack;
-
+#endif
+  
   return win;
 }
 
===================================================================
Index: rtl.c
--- rtl.c	2000/06/09 21:47:38	1.70
+++ rtl.c	2000/06/14 01:43:16
@@ -32,13 +32,6 @@ Boston, MA 02111-1307, USA.  */
 #define	obstack_chunk_alloc	xmalloc
 #define	obstack_chunk_free	free
 
-/* Obstack used for allocating RTL objects.
-   Between functions, this is the permanent_obstack.
-   While parsing and expanding a function, this is maybepermanent_obstack
-   so we can save it if it is an inline function.
-   During optimization and output, this is function_obstack.  */
-
-extern struct obstack *rtl_obstack;
 
 /* Calculate the format for CONST_DOUBLE.  This depends on the relative
    widths of HOST_WIDE_INT and REAL_VALUE_TYPE.
===================================================================
Index: rtl.h
--- rtl.h	2000/05/31 18:36:05	1.208
+++ rtl.h	2000/06/14 01:43:16
@@ -1498,9 +1498,28 @@ extern int rtx_to_tree_code	PARAMS ((enu
 extern void obfree			PARAMS ((char *));
 struct obstack;
 extern void gcc_obstack_init		PARAMS ((struct obstack *));
+#ifdef NEED_OBSTACKS
 extern void pop_obstacks		PARAMS ((void));
 extern void push_obstacks		PARAMS ((struct obstack *,
 						struct obstack *));
+#else
+#define pop_obstacks()			do { } while (0)
+#define push_obstacks(a,b) 		do { } while (0)
+#endif
+
+/* Obstack used for allocating RTL objects.
+   Between functions, this is the permanent_obstack.
+   While parsing and expanding a function, this is maybepermanent_obstack
+   so we can save it if it is an inline function.
+   During optimization and output, this is function_obstack.  */
+
+#ifdef NEED_OBSTACKS
+extern struct obstack *rtl_obstack;
+#else
+extern struct obstack permanent_obstack;
+#define rtl_obstack &permanent_obstack
+#endif
+
 /* In cse.c */
 struct cse_basic_block_data;
 extern int rtx_cost			PARAMS ((rtx, enum rtx_code));
===================================================================
Index: tree.c
--- tree.c	2000/06/09 21:47:38	1.149
+++ tree.c	2000/06/14 01:43:17
@@ -53,12 +53,14 @@ extern int _obstack_allocated_p PARAMS (
 
 static void unsave_expr_now_r PARAMS ((tree));
 
+
 /* Tree nodes of permanent duration are allocated in this obstack.
    They are the identifier nodes, and everything outside of
    the bodies and parameters of function definitions.  */
 
 struct obstack permanent_obstack;
 
+#ifdef NEED_OBSTACKS
 /* The initial RTL, and all ..._TYPE nodes, in a function
    are allocated in this obstack.  Usually they are freed at the
    end of the function, but if the function is inline they are saved.
@@ -124,7 +126,7 @@ struct obstack_stack
   struct obstack *rtl;
 };
 
-struct obstack_stack *obstack_stack;
+static struct obstack_stack *obstack_stack;
 
 /* Obstack for allocating struct obstack_stack entries.  */
 
@@ -158,6 +160,7 @@ struct momentary_level
 };
 
 struct momentary_level *momentary_stack;
+#endif
 
 /* Table indexed by tree code giving a string containing a character
    classifying the tree code.  Possibilities are
@@ -303,8 +306,9 @@ tree integer_types[itk_none];
 void
 init_obstacks ()
 {
-  gcc_obstack_init (&obstack_stack_obstack);
   gcc_obstack_init (&permanent_obstack);
+#ifdef NEED_OBSTACKS
+  gcc_obstack_init (&obstack_stack_obstack);
 
   gcc_obstack_init (&temporary_obstack);
   temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0);
@@ -322,6 +326,7 @@ init_obstacks ()
   current_obstack = &permanent_obstack;
   expression_obstack = &permanent_obstack;
   rtl_obstack = saveable_obstack = &permanent_obstack;
+#endif
 
   /* Init the hash table of identifiers.  */
   bzero ((char *) hash_table, sizeof hash_table);
@@ -355,6 +360,7 @@ gcc_obstack_init (obstack)
 		  (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
 }
 
+#ifdef NEED_OBSTACKS
 /* Save all variables describing the current status into the structure
    *P.  This function is called whenever we start compiling one
    function in the midst of compiling another.  For example, when
@@ -635,6 +641,7 @@ rtl_in_saveable_obstack ()
 {
   rtl_obstack = saveable_obstack;
 }
+#endif
 
 /* Allocate SIZE bytes in the current obstack
    and return a pointer to them.
@@ -658,6 +665,7 @@ obfree (ptr)
   obstack_free (current_obstack, ptr);
 }
 
+#ifdef NEED_OBSTACKS
 /* Allocate SIZE bytes in the permanent obstack
    and return a pointer to them.  */
 
@@ -880,6 +888,7 @@ resume_momentary (yes)
   if (yes)
     expression_obstack = &momentary_obstack;
 }
+#endif
 
 /* Init the tables indexed by tree code.
    Note that languages can add to these tables to define their own codes.  */
@@ -908,7 +917,9 @@ make_node (code)
   register tree t;
   register int type = TREE_CODE_CLASS (code);
   register int length = 0;
+#ifdef NEED_OBSTACKS
   register struct obstack *obstack = current_obstack;
+#endif
 #ifdef GATHER_STATISTICS
   register tree_node_kind kind;
 #endif
@@ -920,10 +931,10 @@ make_node (code)
       kind = d_kind;
 #endif
       length = sizeof (struct tree_decl);
+#ifdef NEED_OBSTACKS
       /* All decls in an inline function need to be saved.  */
       if (obstack != &permanent_obstack)
 	obstack = saveable_obstack;
-
       /* PARM_DECLs go on the context of the parent. If this is a nested
 	 function, then we must allocate the PARM_DECL on the parent's
 	 obstack, so that they will live to the end of the parent's
@@ -947,6 +958,7 @@ make_node (code)
 	    obstack
 	      = find_function_data (context)->function_maybepermanent_obstack;
 	}
+#endif
       break;
 
     case 't':  /* a type node */
@@ -954,9 +966,11 @@ make_node (code)
       kind = t_kind;
 #endif
       length = sizeof (struct tree_type);
+#ifdef NEED_OBSTACKS
       /* All data types are put where we can preserve them if nec.  */
       if (obstack != &permanent_obstack)
 	obstack = all_types_permanent ? &permanent_obstack : saveable_obstack;
+#endif
       break;
 
     case 'b':  /* a lexical block */
@@ -964,9 +978,11 @@ make_node (code)
       kind = b_kind;
 #endif
       length = sizeof (struct tree_block);
+#ifdef NEED_OBSTACKS
       /* All BLOCK nodes are put where we can preserve them if nec.  */
       if (obstack != &permanent_obstack)
 	obstack = saveable_obstack;
+#endif
       break;
 
     case 's':  /* an expression with side effects */
@@ -987,10 +1003,12 @@ make_node (code)
       kind = e_kind;
     usual_kind:
 #endif
+#ifdef NEED_OBSTACKS
       obstack = expression_obstack;
       /* All BIND_EXPR nodes are put where we can preserve them if nec.  */
       if (code == BIND_EXPR && obstack != &permanent_obstack)
 	obstack = saveable_obstack;
+#endif
       length = sizeof (struct tree_exp)
 	+ (TREE_CODE_LENGTH (code) - 1) * sizeof (char *);
       break;
@@ -999,8 +1017,10 @@ make_node (code)
 #ifdef GATHER_STATISTICS
       kind = c_kind;
 #endif
+#ifdef NEED_OBSTACKS
       obstack = expression_obstack;
-
+#endif
+      
       /* We can't use TREE_CODE_LENGTH for INTEGER_CST, since the number of
 	 words is machine-dependent due to varying length of HOST_WIDE_INT,
 	 which might be wider than a pointer (e.g., long long).  Similarly
@@ -1029,9 +1049,11 @@ make_node (code)
 #endif
       length = sizeof (struct tree_common)
 	+ TREE_CODE_LENGTH (code) * sizeof (char *);
+#ifdef NEED_OBSTACKS
       /* Identifier nodes are always permanent since they are
 	 unique in a compiler run.  */
       if (code == IDENTIFIER_NODE) obstack = &permanent_obstack;
+#endif
       break;
 
     default:
@@ -1040,9 +1062,11 @@ make_node (code)
 
   if (ggc_p)
     t = ggc_alloc_tree (length);
+#ifdef NEED_OBSTACKS
   else
     t = (tree) obstack_alloc (obstack, length);
-
+#endif
+  
   memset ((PTR) t, 0, length);
 
 #ifdef GATHER_STATISTICS
@@ -1077,7 +1101,9 @@ make_node (code)
       TYPE_UID (t) = next_type_uid++;
       TYPE_ALIGN (t) = 1;
       TYPE_MAIN_VARIANT (t) = t;
+#ifdef NEED_OBSTACKS
       TYPE_OBSTACK (t) = obstack;
+#endif
       TYPE_ATTRIBUTES (t) = NULL_TREE;
 #ifdef SET_DEFAULT_TYPE_ATTRIBUTES
       SET_DEFAULT_TYPE_ATTRIBUTES (t);
@@ -1193,8 +1219,10 @@ copy_node (node)
 
   if (ggc_p)
     t = ggc_alloc_tree (length);
+#ifdef NEED_OBSTACKS
   else
     t = (tree) obstack_alloc (current_obstack, length);
+#endif
   memcpy (t, node, length);
 
   TREE_CHAIN (t) = 0;
@@ -1205,8 +1233,10 @@ copy_node (node)
   else if (TREE_CODE_CLASS (code) == 't')
     {
       TYPE_UID (t) = next_type_uid++;
+#ifdef NEED_OBSTACKS
       TYPE_OBSTACK (t) = current_obstack;
-
+#endif
+      
       /* The following is so that the debug code for
 	 the copy is different from the original type.
 	 The two statements usually duplicate each other
@@ -1305,9 +1335,11 @@ get_identifier (text)
 
   if (ggc_p)
     IDENTIFIER_POINTER (idp) = ggc_alloc_string (text, len);
+#ifdef NEED_OBSTACKS
   else
     IDENTIFIER_POINTER (idp) = obstack_copy0 (&permanent_obstack, text, len);
-
+#endif
+  
   TREE_CHAIN (idp) = hash_table[hi];
   hash_table[hi] = idp;
   return idp;			/* <-- return if created */
@@ -1558,9 +1590,11 @@ build_string (len, str)
   TREE_STRING_LENGTH (s) = len;
   if (ggc_p)
     TREE_STRING_POINTER (s) = ggc_alloc_string (str, len);
+#ifdef NEED_OBSTACKS
   else
     TREE_STRING_POINTER (s) = obstack_copy0 (saveable_obstack, str, len);
-
+#endif
+  
   return s;
 }
 
@@ -1593,7 +1627,6 @@ make_tree_vec (len)
 {
   register tree t;
   register int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec);
-  register struct obstack *obstack = current_obstack;
 
 #ifdef GATHER_STATISTICS
   tree_node_counts[(int)vec_kind]++;
@@ -1602,9 +1635,11 @@ make_tree_vec (len)
 
   if (ggc_p)
     t = ggc_alloc_tree (length);
+#ifdef NEED_OBSTACKS
   else
-    t = (tree) obstack_alloc (obstack, length);
-
+    t = (tree) obstack_alloc (current_obstack, length);
+#endif
+  
   memset ((PTR) t, 0, length);
   TREE_SET_CODE (t, TREE_VEC);
   TREE_VEC_LENGTH (t) = len;
@@ -2118,8 +2153,8 @@ build_tree_list (parm, value)
   return t;
 }
 
+#ifdef NEED_OBSTACKS
 /* Similar, but build on the temp_decl_obstack.  */
-
 tree
 build_decl_list (parm, value)
      tree parm, value;
@@ -2147,6 +2182,7 @@ build_expr_list (parm, value)
   current_obstack = ambient_obstack;
   return node;
 }
+#endif
 
 /* Return a newly created TREE_LIST node whose
    purpose and value fields are PARM and VALUE
@@ -2160,9 +2196,11 @@ tree_cons (purpose, value, chain)
 
   if (ggc_p)
     node = ggc_alloc_tree (sizeof (struct tree_list));
+#ifdef NEED_OBSTACKS
   else
     node = (tree) obstack_alloc (current_obstack, sizeof (struct tree_list));
-
+#endif
+  
   memset (node, 0, sizeof (struct tree_common));
 
 #ifdef GATHER_STATISTICS
@@ -2179,6 +2217,7 @@ tree_cons (purpose, value, chain)
   return node;
 }
 
+#ifdef NEED_OBSTACKS
 /* Similar, but build on the temp_decl_obstack.  */
 
 tree
@@ -2253,6 +2292,7 @@ saveable_tree_cons (purpose, value, chai
   current_obstack = ambient_obstack;
   return node;
 }
+#endif
 
 /* Return the size nominally occupied by an object of type TYPE
    when it resides in memory.  The value is measured in units of bytes,
@@ -3361,7 +3401,9 @@ build1 (code, type, node)
      tree type;
      tree node;
 {
+#ifdef NEED_OBSTACKS
   register struct obstack *obstack = expression_obstack;
+#endif
   register int length;
 #ifdef GATHER_STATISTICS
   register tree_node_kind kind;
@@ -3379,9 +3421,11 @@ build1 (code, type, node)
 
   if (ggc_p)
     t = ggc_alloc_tree (length);
+#ifdef NEED_OBSTACKS
   else
     t = (tree) obstack_alloc (obstack, length);
-
+#endif
+  
   memset ((PTR) t, 0, sizeof (struct tree_common));
 
 #ifdef GATHER_STATISTICS
@@ -3452,6 +3496,7 @@ build_nt VPARAMS ((enum tree_code code, 
   return t;
 }
 
+#ifdef NEED_OBSTACKS
 /* Similar to `build_nt', except we build
    on the temp_decl_obstack, regardless.  */
 
@@ -3485,6 +3530,7 @@ build_parse_node VPARAMS ((enum tree_cod
   expression_obstack = ambient_obstack;
   return t;
 }
+#endif
 
 #if 0
 /* Commented out because this wants to be done very
@@ -3607,7 +3653,9 @@ build_type_attribute_variant (ttype, att
       unsigned int hashcode;
       tree ntype;
 
+#ifdef NEED_OBSTACKS
       push_obstacks (TYPE_OBSTACK (ttype), TYPE_OBSTACK (ttype));
+#endif
       ntype = copy_node (ttype);
 
       TYPE_POINTER_TO (ntype) = 0;
@@ -3643,7 +3691,9 @@ build_type_attribute_variant (ttype, att
 
       ntype = type_hash_canon (hashcode, ntype);
       ttype = build_qualified_type (ntype, TYPE_QUALS (ttype));
+#ifdef NEED_OBSTACKS
       pop_obstacks ();
+#endif
     }
 
   return ttype;
@@ -3958,12 +4008,16 @@ build_type_copy (type)
      tree type;
 {
   register tree t, m = TYPE_MAIN_VARIANT (type);
+#ifdef NEED_OBSTACKS
   register struct obstack *ambient_obstack = current_obstack;
 
   current_obstack = TYPE_OBSTACK (type);
   t = copy_node (type);
   current_obstack = ambient_obstack;
-
+#else
+  t = copy_node (type);
+#endif
+  
   TYPE_POINTER_TO (t) = 0;
   TYPE_REFERENCE_TO (t) = 0;
 
@@ -4105,9 +4159,11 @@ type_hash_canon (hashcode, type)
   t1 = type_hash_lookup (hashcode, type);
   if (t1 != 0)
     {
+#ifdef NEED_OBSTACKS
       if (!ggc_p)
 	obstack_free (TYPE_OBSTACK (type), type);
-
+#endif
+      
 #ifdef GATHER_STATISTICS
       tree_node_counts[(int) t_kind]--;
       tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type);
@@ -5281,7 +5337,7 @@ get_callee_fndecl (call)
 }
 
 /* Print debugging information about the obstack O, named STR.  */
-
+#ifdef NEED_OBSTACKS
 void
 print_obstack_statistics (str, o)
      const char *str;
@@ -5302,6 +5358,7 @@ print_obstack_statistics (str, o)
   fprintf (stderr, "obstack %s: %u bytes, %d chunks\n",
 	   str, n_alloc, n_chunks);
 }
+#endif
 
 /* Print debugging information about tree nodes generated during the compile,
    and any language-specific information.  */
@@ -5333,11 +5390,13 @@ dump_tree_statistics ()
 #else
   fprintf (stderr, "(No per-node statistics)\n");
 #endif
+#ifdef NEED_OBSTACKS
   print_obstack_statistics ("permanent_obstack", &permanent_obstack);
   print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
   print_obstack_statistics ("temporary_obstack", &temporary_obstack);
   print_obstack_statistics ("momentary_obstack", &momentary_obstack);
   print_obstack_statistics ("temp_decl_obstack", &temp_decl_obstack);
+#endif
   print_type_hash_statistics ();
   print_lang_statistics ();
 }
===================================================================
Index: tree.h
--- tree.h	2000/06/09 21:47:39	1.179
+++ tree.h	2000/06/14 01:43:18
@@ -572,11 +572,16 @@ extern void tree_class_check_failed PARA
    Otherwise it will be recycled at the end of the function.
    This flag is always zero if garbage collection is in use.
    Try not to use this.  Only set it with TREE_SET_PERMANENT.  */
+#ifdef NEED_OBSTACKS
 #define TREE_PERMANENT(NODE) ((NODE)->common.permanent_flag)
 #define TREE_SET_PERMANENT(NODE) do { \
   if (!ggc_p && current_obstack == &permanent_obstack) \
     TREE_PERMANENT(NODE) = 1; \
-} while (0) 
+} while (0)
+#else
+#define TREE_PERMANENT(NODE) 0
+#define TREE_SET_PERMANENT(NODE) do { } while (0)
+#endif
 
 /* In INTEGER_TYPE or ENUMERAL_TYPE nodes, means an unsigned type.
    In FIELD_DECL nodes, means an unsigned bit field.
@@ -883,7 +888,11 @@ struct tree_block
 #define TYPE_MAIN_VARIANT(NODE) (TYPE_CHECK (NODE)->type.main_variant)
 #define TYPE_NONCOPIED_PARTS(NODE) (TYPE_CHECK (NODE)->type.noncopied_parts)
 #define TYPE_CONTEXT(NODE) (TYPE_CHECK (NODE)->type.context)
+#ifdef NEED_OBSTACKS
 #define TYPE_OBSTACK(NODE) (TYPE_CHECK (NODE)->type.obstack)
+#else
+#define TYPE_OBSTACK(NODE) 0
+#endif
 #define TYPE_LANG_SPECIFIC(NODE) (TYPE_CHECK (NODE)->type.lang_specific)
 
 /* Indirect types present difficulties because they may be represented
@@ -1086,6 +1095,8 @@ struct tree_block
 #define MAX_POINTER_DEPTH 2
 #define VA_LIST_POINTER_DEPTH 3
 
+struct obstack;
+
 struct tree_type
 {
   struct tree_common common;
@@ -1126,7 +1137,9 @@ struct tree_type
   union tree_node *binfo;
   union tree_node *noncopied_parts;
   union tree_node *context;
+#ifdef NEED_OBSTACKS
   struct obstack *obstack;
+#endif
   HOST_WIDE_INT alias_set;
   /* Points to a structure whose details depend on the language in use.  */
   struct lang_type *lang_specific;
@@ -1805,11 +1818,6 @@ extern tree integer_types[itk_none];
 extern int exact_log2_wide             PARAMS ((unsigned HOST_WIDE_INT));
 extern int floor_log2_wide             PARAMS ((unsigned HOST_WIDE_INT));
 
-extern char *oballoc			PARAMS ((int));
-extern char *permalloc			PARAMS ((int));
-extern char *savealloc			PARAMS ((int));
-extern char *expralloc			PARAMS ((int));
-
 /* Lowest level primitive for allocating a node.
    The TREE_CODE is the only argument.  Contents are initialized
    to zero except for a few of the common fields.  */
@@ -1850,8 +1858,11 @@ extern tree maybe_get_identifier	PARAMS 
 
 extern tree build			PARAMS ((enum tree_code, tree, ...));
 extern tree build_nt			PARAMS ((enum tree_code, ...));
+#ifdef NEED_OBSTACKS
 extern tree build_parse_node		PARAMS ((enum tree_code, ...));
-
+#else
+#define build_parse_node build_nt	/* can't use fn-like 'cos of varargs */
+#endif
 extern tree build_int_2_wide		PARAMS ((unsigned HOST_WIDE_INT, HOST_WIDE_INT));
 extern tree build_real			PARAMS ((tree, REAL_VALUE_TYPE));
 extern tree build_real_from_int_cst 	PARAMS ((tree, tree));
@@ -1859,8 +1870,13 @@ extern tree build_complex		PARAMS ((tree
 extern tree build_string		PARAMS ((int, const char *));
 extern tree build1			PARAMS ((enum tree_code, tree, tree));
 extern tree build_tree_list		PARAMS ((tree, tree));
+#ifdef NEED_OBSTACKS
 extern tree build_decl_list		PARAMS ((tree, tree));
 extern tree build_expr_list		PARAMS ((tree, tree));
+#else
+#define build_decl_list(x, y)		build_tree_list(x, y)
+#define build_expr_list(x, y)		build_tree_list(x, y)
+#endif
 extern tree build_decl			PARAMS ((enum tree_code, tree, tree));
 extern tree build_block			PARAMS ((tree, tree, tree, tree, tree));
 extern tree build_expr_wfl              PARAMS ((tree, const char *, int, int));
@@ -2117,11 +2133,19 @@ extern tree chainon			PARAMS ((tree, tre
 /* Make a new TREE_LIST node from specified PURPOSE, VALUE and CHAIN.  */
 
 extern tree tree_cons			PARAMS ((tree, tree, tree));
+#ifdef NEED_OBSTACKS
 extern tree perm_tree_cons		PARAMS ((tree, tree, tree));
 extern tree temp_tree_cons		PARAMS ((tree, tree, tree));
 extern tree saveable_tree_cons		PARAMS ((tree, tree, tree));
 extern tree decl_tree_cons		PARAMS ((tree, tree, tree));
 extern tree expr_tree_cons		PARAMS ((tree, tree, tree));
+#else
+#define perm_tree_cons(a, b, c)		tree_cons(a, b, c)
+#define temp_tree_cons(a, b, c)		tree_cons(a, b, c)
+#define saveable_tree_cons(a, b, c)	tree_cons(a, b, c)
+#define decl_tree_cons(a, b, c)		tree_cons(a, b, c)
+#define expr_tree_cons(a, b, c)		tree_cons(a, b, c)
+#endif
 
 /* Return the last tree node in a chain.  */
 
@@ -2388,7 +2412,6 @@ extern tree builtin_function			PARAMS ((
 						       const char *));
 
 /* In tree.c */
-extern char *perm_calloc			PARAMS ((int, long));
 extern tree get_file_function_name		PARAMS ((int));
 extern tree get_file_function_name_long 	PARAMS ((const char *));
 extern tree get_set_constructor_bits		PARAMS ((tree, char *, int));
@@ -2604,54 +2627,130 @@ extern tree gettags				PARAMS ((void));
 
 extern tree build_range_type PARAMS ((tree, tree, tree));
 
-/* Call when starting to parse a declaration:
-   make expressions in the declaration last the length of the function.
-   Returns an argument that should be passed to resume_momentary later.  */
-extern int suspend_momentary PARAMS ((void));
-
-extern int allocation_temporary_p PARAMS ((void));
-
-/* Call when finished parsing a declaration:
-   restore the treatment of node-allocation that was
-   in effect before the suspension.
-   YES should be the value previously returned by suspend_momentary.  */
-extern void resume_momentary PARAMS ((int));
-
 /* Called after finishing a record, union or enumeral type.  */
 extern void rest_of_type_compilation PARAMS ((tree, int));
 
-/* Save the current set of obstacks, but don't change them.  */
-extern void push_obstacks_nochange PARAMS ((void));
+/* Obstack manipulation routines.  If no front end needs them, most of
+   them can be #defined out of existence.  */
+extern void init_obstacks		PARAMS ((void));
+extern void gcc_obstack_init		PARAMS ((struct obstack *));
+extern void obfree			PARAMS ((char *));
+extern char *oballoc			PARAMS ((int));
 
-extern void permanent_allocation PARAMS ((int));
-extern void push_momentary PARAMS ((void));
-extern void clear_momentary PARAMS ((void));
-extern void pop_momentary PARAMS ((void));
-extern void end_temporary_allocation PARAMS ((void));
+#ifdef NEED_OBSTACKS
+extern void push_obstacks_nochange	PARAMS ((void));
+extern void permanent_allocation	PARAMS ((int));
+extern void push_momentary		PARAMS ((void));
+extern void clear_momentary		PARAMS ((void));
+extern void pop_momentary		PARAMS ((void));
+extern int suspend_momentary		PARAMS ((void));
+extern void resume_momentary		PARAMS ((int));
+extern void end_temporary_allocation	PARAMS ((void));
+extern int allocation_temporary_p	PARAMS ((void));
+extern void pop_obstacks		PARAMS ((void));
+extern void push_obstacks		PARAMS ((struct obstack *,
+						 struct obstack *));
+extern void pop_momentary_nofree	PARAMS ((void));
+extern void preserve_momentary		PARAMS ((void));
+extern void saveable_allocation		PARAMS ((void));
+extern void temporary_allocation	PARAMS ((void));
+extern void resume_temporary_allocation	PARAMS ((void));
+extern void debug_obstack		PARAMS ((char *));
+extern void rtl_in_current_obstack	PARAMS ((void));
+extern void rtl_in_saveable_obstack	PARAMS ((void));
+extern void print_obstack_statistics	PARAMS ((const char *,
+						struct obstack *));
+#ifdef BUFSIZ
+extern void print_obstack_name		PARAMS ((char *, FILE *,
+						 const char *));
+#endif
+extern char *permalloc			PARAMS ((int));
+extern char *perm_calloc		PARAMS ((int, long));
+extern char *savealloc			PARAMS ((int));
+extern char *expralloc			PARAMS ((int));
 
-/* Pop the obstack selection stack.  */
-extern void pop_obstacks PARAMS ((void));
+extern void preserve_initializer	PARAMS ((void));
+extern void preserve_data		PARAMS ((void));
+extern int object_permanent_p		PARAMS ((tree));
+
+#else
+
+#define push_obstacks_nochange()	do { } while (0)
+#define permanent_allocation(x)		do { } while (0)
+#define push_momentary()		do { } while (0)
+#define clear_momentary()		do { } while (0)
+#define pop_momentary()			do { } while (0)
+#define suspend_momentary()		0
+#define resume_momentary(x)		do { } while (0)
+#define end_temporary_allocation()	do { } while (0)
+#define allocation_temporary_p()	0
+#define pop_obstacks()			do { } while (0)
+#define push_obstacks(a, b)		do { } while (0)
+#define pop_momentary_nofree()		do { } while (0)
+#define preserve_momentary()		do { } while (0)
+#define saveable_allocation()		do { } while (0)
+#define temporary_allocation()		do { } while (0)
+#define resume_temporary_allocation()	do { } while (0)
+#define debug_obstack(x)		do { } while (0)
+#define rtl_in_current_obstack()	do { } while (0)
+#define rtl_in_saveable_obstack()	do { } while (0)
+#define print_obstack_statistics(a, b)	do { } while (0)
+#define print_obstack_name(a, b, c)	do { } while (0)
+
+#define permalloc(x)			xmalloc(x)
+#define perm_calloc(x,y)		xcalloc(x,y)
+#define savealloc(x)			xmalloc(x)
+#define expralloc(x)			xmalloc(x)
+
+#define preserve_initializer()		do { } while (0)
+#define preserve_data()			do { } while (0)
+#define object_permanent_p(x)		0
+
+#endif
+
+/* Global obstacks.  Again, if we don't need obstack allocation of trees
+   and RTL, then most of them can be elided.  */
+
+extern struct obstack permanent_obstack;
 
+#ifdef NEED_OBSTACKS
+extern struct obstack maybepermanent_obstack;
+extern struct obstack temporary_obstack;
+extern struct obstack momentary_obstack;
+extern struct obstack temp_decl_obstack;
+
+extern struct obstack *function_maybepermanent_obstack;
+extern struct obstack *function_obstack;
+extern struct obstack *current_obstack;
+extern struct obstack *saveable_obstack;
+extern struct obstack *rtl_obstack;
+extern struct obstack *expression_obstack;
+#else
+#define maybepermanent_obstack	permanent_obstack
+#define temporary_obstack	permanent_obstack
+#define momentary_obstack	permanent_obstack
+#define temp_decl_obstack	permanent_obstack
+
+#define function_maybepermanent_obstack	&permanent_obstack
+#define function_obstack	&permanent_obstack
+#define current_obstack		&permanent_obstack
+#define saveable_obstack	&permanent_obstack
+#define rtl_obstack		&permanent_obstack
+#define expression_obstack	&permanent_obstack
+#endif
+
+
+
 /* In alias.c */
 void record_component_aliases		PARAMS ((tree));
 
 /* In tree.c */
 extern int really_constant_p		PARAMS ((tree));
-extern void push_obstacks		PARAMS ((struct obstack *,
-						struct obstack *));
-extern void pop_momentary_nofree	PARAMS ((void));
-extern void preserve_momentary		PARAMS ((void));
-extern void saveable_allocation		PARAMS ((void));
-extern void temporary_allocation	PARAMS ((void));
-extern void resume_temporary_allocation	PARAMS ((void));
 extern tree get_file_function_name	PARAMS ((int));
 extern void set_identifier_size		PARAMS ((int));
 extern int int_fits_type_p		PARAMS ((tree, tree));
 extern int tree_log2			PARAMS ((tree));
 extern int tree_floor_log2		PARAMS ((tree));
-extern void preserve_initializer	PARAMS ((void));
-extern void preserve_data		PARAMS ((void));
-extern int object_permanent_p		PARAMS ((tree));
 extern int type_precision		PARAMS ((tree));
 extern int simple_cst_equal		PARAMS ((tree, tree));
 extern int compare_tree_int		PARAMS ((tree, unsigned int));
@@ -2664,26 +2763,14 @@ extern tree type_hash_lookup		PARAMS ((u
 extern void type_hash_add		PARAMS ((unsigned int, tree));
 extern unsigned int type_hash_list	PARAMS ((tree));
 extern int simple_cst_list_equal	PARAMS ((tree, tree));
-extern void debug_obstack		PARAMS ((char *));
-extern void rtl_in_current_obstack	PARAMS ((void));
-extern void rtl_in_saveable_obstack	PARAMS ((void));
 extern void init_tree_codes		PARAMS ((void));
 extern void dump_tree_statistics	PARAMS ((void));
-extern void print_obstack_statistics	PARAMS ((const char *,
-						struct obstack *));
-#ifdef BUFSIZ
-extern void print_obstack_name		PARAMS ((char *, FILE *,
-						 const char *));
-#endif
 extern void expand_function_end		PARAMS ((const char *, int, int));
 extern void expand_function_start	PARAMS ((tree, int));
 
 extern int real_onep			PARAMS ((tree));
 extern int real_twop			PARAMS ((tree));
 extern void start_identifier_warnings	PARAMS ((void));
-extern void gcc_obstack_init		PARAMS ((struct obstack *));
-extern void init_obstacks		PARAMS ((void));
-extern void obfree			PARAMS ((char *));
 extern void build_common_tree_nodes	PARAMS ((int));
 extern void build_common_tree_nodes_2	PARAMS ((int));
 
===================================================================
Index: varasm.c
--- varasm.c	2000/06/09 21:47:39	1.124
+++ varasm.c	2000/06/14 01:43:19
@@ -80,10 +80,6 @@ extern FILE *asm_out_file;
 const char *first_global_object_name;
 const char *weak_global_object_name;
 
-extern struct obstack *current_obstack;
-extern struct obstack *saveable_obstack;
-extern struct obstack *rtl_obstack;
-extern struct obstack permanent_obstack;
 #define obstack_chunk_alloc xmalloc
 
 struct addr_const;
===================================================================
Index: ch/config-lang.in
--- ch/config-lang.in	2000/06/06 07:23:41	1.5
+++ ch/config-lang.in	2000/06/14 01:43:19
@@ -36,3 +36,5 @@ diff_excludes="-x -x ch/chill.info*"
 
 outputs=ch/Makefile
 
+# Chill has not been updated to GC yet.
+need_obstacks=t
===================================================================
Index: cp/class.c
--- cp/class.c	2000/06/12 20:46:28	1.318
+++ cp/class.c	2000/06/14 01:43:22
@@ -1151,8 +1151,6 @@ add_virtual_function (new_virtuals_p, ov
       *overridden_virtuals_p = new_virtual;
     }
 }
-
-extern struct obstack *current_obstack;
 
 /* Add method METHOD to class TYPE.
 
===================================================================
Index: cp/decl.c
--- cp/decl.c	2000/06/11 04:08:31	1.635
+++ cp/decl.c	2000/06/14 01:43:25
@@ -55,8 +55,9 @@ extern tree global_namespace;
 extern int (*valid_lang_attribute) PARAMS ((tree, tree, tree, tree));
 
 /* Use garbage collection.  */
-
+#ifdef NEED_OBSTACKS
 int ggc_p = 1;
+#endif
 
 #ifndef WCHAR_UNSIGNED
 #define WCHAR_UNSIGNED 0
===================================================================
Index: cp/search.c
--- cp/search.c	2000/06/06 00:12:40	1.182
+++ cp/search.c	2000/06/14 01:43:25
@@ -36,8 +36,6 @@ Boston, MA 02111-1307, USA.  */
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
 
-extern struct obstack *current_obstack;
-
 #include "stack.h"
 
 /* Obstack used for remembering decision points of breadth-first.  */
===================================================================
Index: f/com.c
--- f/com.c	2000/06/11 04:29:48	1.87
+++ f/com.c	2000/06/14 01:43:29
@@ -15752,8 +15752,9 @@ unsigned_type (type)
 }
 
 /* Callback routines for garbage collection.  */
-
+#ifdef NEED_OBSTACKS
 int ggc_p = 1;
+#endif
 
 void 
 lang_mark_tree (t)
===================================================================
Index: java/config-lang.in
--- java/config-lang.in	1998/12/16 21:19:55	1.3
+++ java/config-lang.in	2000/06/14 01:43:29
@@ -38,3 +38,6 @@ compilers="jc1\$(exeext) jvgenmain\$(exe
 stagestuff="jc1\$(exeext) gcj\$(exeext) jvgenmain\$(exeext) gcjh\$(exeext) jv-scan\$(exeext) jcf-dump\$(exeext)"
 
 outputs=java/Makefile
+
+# Chill has not been updated to GC yet.
+need_obstacks=t


More information about the Gcc-patches mailing list