diff mbox

[gc-improv,committed] Allocate RTL in obstacks, first cut

Message ID 4D415299.9030008@gmail.com
State New
Headers show

Commit Message

Laurynas Biveinis Jan. 27, 2011, 11:10 a.m. UTC
This patch moves RTL allocation from GC to obstacks. To do this, there are many things
going on here at once:

- New allocation API (might change):
-- init_rtl for setting up allocators;
-- allocate_in_rtl_mem allocates an object (not necessarily an rtx) in the current RTL
memory area. Probably a type-safe macro ala XNEW is warranted here too.
-- allocate_in_rtl_function_mem same but in the current function RTL memory area
-- copy_rtx_to_permanent_mem -- strdup_to_permanent_mem (now I'm thinking a better name is
strdup_to_rtl_permanent_mem)

- struct function gets a new vector of tree pointers debug_decls so that GC-allocated
trees pointed to from RTL are not collected.
- used_rtx_array in dwarf2out.c is obsoleted by the permanent RTL area.
- emit-rtl.c gets vector of tree pointers mem_attr_exprs to keep GC collections away. I am
not sure if it is possible to stash memory attribute tree expressions in some other tree
vector (i.e. debug_decls above).
- Likewise saved_constant_decls in varasm.c, used by build_constant_desc.
- Many GTY markers were removed.
- Removed a lot of RTL support code from gengtype.c
- A few source files do not include ggc.h and are not processed by gengtype anymore.
- All rtl_zone mentions removed from GC.
- regno_reg_rtx is moved to struct emit_status. Was not strictly necessary to do this now,
but oh well.
- free_sequence_stack in emit-rtl.c likewise. I will probably get rid of it later.

This patch does not try to limit lifetimes in any way, i.e. currently all RTL objects live
forever. Also, some auxiliary data structures are allocated on heap and never freed.

With this patch, stage1 compiler is able to build all runtime libs without crashing on
x86_64-unknown-linux-gnu. Next target testsuite, then full bootstrap.

Committed to gc-improv.
diff mbox

Patch

Index: gcc/ira-conflicts.c
===================================================================
--- gcc/ira-conflicts.c	(revision 169049)
+++ gcc/ira-conflicts.c	(working copy)
@@ -879,7 +879,8 @@ 
       for (i = 0; i < n; i++)
 	{
 	  ira_object_t obj = ALLOCNO_OBJECT (a, i);
-	  reg_attrs *attrs = REG_ATTRS (regno_reg_rtx [ALLOCNO_REGNO (a)]);
+	  reg_attrs *attrs
+	    = REG_ATTRS (crtl->emit.regno_reg_rtx [ALLOCNO_REGNO (a)]);
 	  tree decl;
 
 	  if ((! flag_caller_saves && ALLOCNO_CALLS_CROSSED_NUM (a) != 0)
Index: gcc/gengtype.c
===================================================================
--- gcc/gengtype.c	(revision 169049)
+++ gcc/gengtype.c	(working copy)
@@ -89,8 +89,6 @@ 
 /* Nonzero iff an error has occurred.  */
 bool hit_error = false;
 
-static void gen_rtx_next (void);
-static void write_rtx_next (void);
 static void open_base_files (void);
 static void close_output_files (void);
 
@@ -482,7 +480,6 @@ 
 
 static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
 static type_p adjust_field_tree_exp (type_p t, options_p opt);
-static type_p adjust_field_rtx_def (type_p t, options_p opt);
 
 /* Define S as a typedef to T at POS.  */
 
@@ -820,39 +817,6 @@ 
 #define create_field(next,type,name) \
     create_field_all(next,type,name, 0, this_file, __LINE__)
 
-/* Like create_field, but the field is only valid when condition COND
-   is true.  */
-
-static pair_p
-create_optional_field_ (pair_p next, type_p type, const char *name,
-			const char *cond, int line)
-{
-  static int id = 1;
-  pair_p union_fields;
-  type_p union_type;
-
-  /* Create a fake union type with a single nameless field of type TYPE.
-     The field has a tag of "1".  This allows us to make the presence
-     of a field of type TYPE depend on some boolean "desc" being true.  */
-  union_fields = create_field (NULL, type, "");
-  union_fields->opt = 
-    create_string_option (union_fields->opt, "dot", "");
-  union_fields->opt = 
-    create_string_option (union_fields->opt, "tag", "1");
-  union_type = 
-    new_structure (xasprintf ("%s_%d", "fake_union", id++), 1,
-                   &lexer_line, union_fields, NULL);
-
-  /* Create the field and give it the new fake union type.  Add a "desc"
-     tag that specifies the condition under which the field is valid.  */
-  return create_field_all (next, union_type, name,
-			   create_string_option (0, "desc", cond), 
-			   this_file, line);
-}
-
-#define create_optional_field(next,type,name,cond)	\
-       create_optional_field_(next,type,name,cond,__LINE__)
-
 /* Reverse a linked list of 'struct pair's in place.  */
 pair_p
 nreverse_pairs (pair_p list)
@@ -873,28 +837,6 @@ 
 /* We don't want to see codes that are only for generator files.  */
 #undef GENERATOR_FILE
 
-enum rtx_code
-{
-#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM ,
-#include "rtl.def"
-#undef DEF_RTL_EXPR
-  NUM_RTX_CODE
-};
-
-static const char *const rtx_name[NUM_RTX_CODE] = {
-#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
-#include "rtl.def"
-#undef DEF_RTL_EXPR
-};
-
-static const char *const rtx_format[NUM_RTX_CODE] = {
-#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
-#include "rtl.def"
-#undef DEF_RTL_EXPR
-};
-
-static int rtx_next_new[NUM_RTX_CODE];
-
 /* We also need codes and names for insn notes (not register notes).
    Note that we do *not* bias the note values here.  */
 enum insn_note
@@ -917,277 +859,6 @@ 
 #undef CONST_DOUBLE_FORMAT
 #define GENERATOR_FILE
 
-/* Generate the contents of the rtx_next array.  This really doesn't belong
-   in gengtype at all, but it's needed for adjust_field_rtx_def.  */
-
-static void
-gen_rtx_next (void)
-{
-  int i;
-  for (i = 0; i < NUM_RTX_CODE; i++)
-    {
-      int k;
-
-      rtx_next_new[i] = -1;
-      if (strncmp (rtx_format[i], "iuu", 3) == 0)
-	rtx_next_new[i] = 2;
-      else if (i == COND_EXEC || i == SET || i == EXPR_LIST || i == INSN_LIST)
-	rtx_next_new[i] = 1;
-      else
-	for (k = strlen (rtx_format[i]) - 1; k >= 0; k--)
-	  if (rtx_format[i][k] == 'e' || rtx_format[i][k] == 'u')
-	    rtx_next_new[i] = k;
-    }
-}
-
-/* Write out the contents of the rtx_next array.  */
-static void
-write_rtx_next (void)
-{
-  outf_p f = get_output_file_with_visibility (NULL);
-  int i;
-  if (!f)
-    return;
-
-  oprintf (f, "\n/* Used to implement the RTX_NEXT macro.  */\n");
-  oprintf (f, "EXPORTED_CONST unsigned char rtx_next[NUM_RTX_CODE] = {\n");
-  for (i = 0; i < NUM_RTX_CODE; i++)
-    if (rtx_next_new[i] == -1)
-      oprintf (f, "  0,\n");
-    else
-      oprintf (f,
-	       "  RTX_HDR_SIZE + %d * sizeof (rtunion),\n", rtx_next_new[i]);
-  oprintf (f, "};\n");
-}
-
-/* Handle `special("rtx_def")'.  This is a special case for field
-   `fld' of struct rtx_def, which is an array of unions whose values
-   are based in a complex way on the type of RTL.  */
-
-static type_p
-adjust_field_rtx_def (type_p t, options_p ARG_UNUSED (opt))
-{
-  pair_p flds = NULL;
-  options_p nodot;
-  int i;
-  type_p rtx_tp, rtvec_tp, tree_tp, mem_attrs_tp, note_union_tp, scalar_tp;
-  type_p basic_block_tp, reg_attrs_tp, constant_tp, symbol_union_tp;
-
-  if (t->kind != TYPE_UNION)
-    {
-      error_at_line (&lexer_line,
-		     "special `rtx_def' must be applied to a union");
-      return &string_type;
-    }
-
-  nodot = create_string_option (NULL, "dot", "");
-
-  rtx_tp = create_pointer (find_structure ("rtx_def", 0));
-  rtvec_tp = create_pointer (find_structure ("rtvec_def", 0));
-  tree_tp = create_pointer (find_structure ("tree_node", 1));
-  mem_attrs_tp = create_pointer (find_structure ("mem_attrs", 0));
-  reg_attrs_tp = 
-    create_pointer (find_structure ("reg_attrs", 0));
-  basic_block_tp = 
-    create_pointer (find_structure ("basic_block_def", 0));
-  constant_tp =
-    create_pointer (find_structure ("constant_descriptor_rtx", 0));
-  scalar_tp = &scalar_nonchar;	/* rtunion int */
-
-  {
-    pair_p note_flds = NULL;
-    int c;
-
-    for (c = 0; c <= NOTE_INSN_MAX; c++)
-      {
-	switch (c)
-	  {
-	  case NOTE_INSN_MAX:
-	  case NOTE_INSN_DELETED_LABEL:
-	    note_flds = create_field (note_flds, &string_type, "rt_str");
-	    break;
-
-	  case NOTE_INSN_BLOCK_BEG:
-	  case NOTE_INSN_BLOCK_END:
-	    note_flds = create_field (note_flds, tree_tp, "rt_tree");
-	    break;
-
-	  case NOTE_INSN_VAR_LOCATION:
-	    note_flds = create_field (note_flds, rtx_tp, "rt_rtx");
-	    break;
-
-	  default:
-	    note_flds = create_field (note_flds, scalar_tp, "rt_int");
-	    break;
-	  }
-	/* NOTE_INSN_MAX is used as the default field for line
-	   number notes.  */
-	if (c == NOTE_INSN_MAX)
-	  note_flds->opt = 
-	    create_string_option (nodot, "default", "");
-	else
-	  note_flds->opt = 
-	    create_string_option (nodot, "tag", note_insn_name[c]);
-      }
-    note_union_tp = new_structure ("rtx_def_note_subunion", 1,
-				   &lexer_line, note_flds, NULL);
-  }
-  /* Create a type to represent the various forms of SYMBOL_REF_DATA.  */
-  {
-    pair_p sym_flds;
-    sym_flds = create_field (NULL, tree_tp, "rt_tree");
-    sym_flds->opt = create_string_option (nodot, "default", "");
-    sym_flds = create_field (sym_flds, constant_tp, "rt_constant");
-    sym_flds->opt = create_string_option (nodot, "tag", "1");
-    symbol_union_tp = new_structure ("rtx_def_symbol_subunion", 1,
-				     &lexer_line, sym_flds, NULL);
-  }
-  for (i = 0; i < NUM_RTX_CODE; i++)
-    {
-      pair_p subfields = NULL;
-      size_t aindex, nmindex;
-      const char *sname;
-      type_p substruct;
-      char *ftag;
-
-      for (aindex = 0; aindex < strlen (rtx_format[i]); aindex++)
-	{
-	  type_p t;
-	  const char *subname;
-
-	  switch (rtx_format[i][aindex])
-	    {
-	    case '*':
-	    case 'i':
-	    case 'n':
-	    case 'w':
-	      t = scalar_tp;
-	      subname = "rt_int";
-	      break;
-
-	    case '0':
-	      if (i == MEM && aindex == 1)
-		t = mem_attrs_tp, subname = "rt_mem";
-	      else if (i == JUMP_INSN && aindex == 8)
-		t = rtx_tp, subname = "rt_rtx";
-	      else if (i == CODE_LABEL && aindex == 5)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == CODE_LABEL && aindex == 4)
-		t = rtx_tp, subname = "rt_rtx";
-	      else if (i == LABEL_REF && (aindex == 1 || aindex == 2))
-		t = rtx_tp, subname = "rt_rtx";
-	      else if (i == NOTE && aindex == 4)
-		t = note_union_tp, subname = "";
-	      else if (i == NOTE && aindex == 5)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == NOTE && aindex >= 7)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == ADDR_DIFF_VEC && aindex == 4)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == VALUE && aindex == 0)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == DEBUG_EXPR && aindex == 0)
-		t = tree_tp, subname = "rt_tree";
-	      else if (i == REG && aindex == 1)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == REG && aindex == 2)
-		t = reg_attrs_tp, subname = "rt_reg";
-	      else if (i == SCRATCH && aindex == 0)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == SYMBOL_REF && aindex == 1)
-		t = scalar_tp, subname = "rt_int";
-	      else if (i == SYMBOL_REF && aindex == 2)
-		t = symbol_union_tp, subname = "";
-	      else if (i == BARRIER && aindex >= 3)
-		t = scalar_tp, subname = "rt_int";
-	      else
-		{
-		  error_at_line 
-		    (&lexer_line,
-		     "rtx type `%s' has `0' in position %lu, can't handle",
-		     rtx_name[i], (unsigned long) aindex);
-		  t = &string_type;
-		  subname = "rt_int";
-		}
-	      break;
-
-	    case 's':
-	    case 'S':
-	    case 'T':
-	      t = &string_type;
-	      subname = "rt_str";
-	      break;
-
-	    case 'e':
-	    case 'u':
-	      t = rtx_tp;
-	      subname = "rt_rtx";
-	      break;
-
-	    case 'E':
-	    case 'V':
-	      t = rtvec_tp;
-	      subname = "rt_rtvec";
-	      break;
-
-	    case 't':
-	      t = tree_tp;
-	      subname = "rt_tree";
-	      break;
-
-	    case 'B':
-	      t = basic_block_tp;
-	      subname = "rt_bb";
-	      break;
-
-	    default:
-	      error_at_line
-		(&lexer_line,
-		 "rtx type `%s' has `%c' in position %lu, can't handle",
-		 rtx_name[i], rtx_format[i][aindex],
-		 (unsigned long) aindex);
-	      t = &string_type;
-	      subname = "rt_int";
-	      break;
-	    }
-
-	  subfields = create_field (subfields, t,
-				    xasprintf (".fld[%lu].%s",
-					       (unsigned long) aindex,
-					       subname));
-	  subfields->opt = nodot;
-	  if (t == note_union_tp)
-	    subfields->opt =
-	      create_string_option (subfields->opt, "desc",
-				    "NOTE_KIND (&%0)");
-	  if (t == symbol_union_tp)
-	    subfields->opt = 
-	      create_string_option (subfields->opt, "desc",
-				    "CONSTANT_POOL_ADDRESS_P (&%0)");
-	}
-
-      if (i == SYMBOL_REF)
-	{
-	  /* Add the "block_sym" field if SYMBOL_REF_HAS_BLOCK_INFO_P
-	     holds.  */
-	  type_p field_tp = find_structure ("block_symbol", 0);
-	  subfields
-	    = create_optional_field (subfields, field_tp, "block_sym",
-				     "SYMBOL_REF_HAS_BLOCK_INFO_P (&%0)");
-	}
-
-      sname = xasprintf ("rtx_def_%s", rtx_name[i]);
-      substruct = new_structure (sname, 0, &lexer_line, subfields, NULL);
-
-      ftag = xstrdup (rtx_name[i]);
-      for (nmindex = 0; nmindex < strlen (ftag); nmindex++)
-	ftag[nmindex] = TOUPPER (ftag[nmindex]);
-      flds = create_field (flds, substruct, "");
-      flds->opt = create_string_option (nodot, "tag", ftag);
-    }
-  return new_structure ("rtx_def_subunion", 1, &lexer_line, flds, nodot);
-}
-
 /* Handle `special("tree_exp")'.  This is a special case for
    field `operands' of struct tree_exp, which although it claims to contain
    pointers to trees, actually sometimes contains pointers to RTL too.
@@ -1273,8 +944,6 @@ 
 	const char *special_name = opt->info.string;
 	if (strcmp (special_name, "tree_exp") == 0)
 	  t = adjust_field_tree_exp (t, opt);
-	else if (strcmp (special_name, "rtx_def") == 0)
-	  t = adjust_field_rtx_def (t, opt);
 	else
 	  error_at_line (&lexer_line, "unknown special `%s'", special_name);
       }
@@ -4936,8 +4605,6 @@ 
   if (hit_error)
     return 1;
 
-  gen_rtx_next ();
-
   /* The call to set_gc_used may indirectly call find_param_structure
      hence enlarge the param_structs list of types.  */
   set_gc_used (variables);
@@ -4991,7 +4658,6 @@ 
     }
   write_splay_tree_allocators (param_structs);
   write_roots (variables, plugin_files == NULL);
-  write_rtx_next ();
   close_output_files ();
 
   if (do_dump)
Index: gcc/cgraph.h
===================================================================
--- gcc/cgraph.h	(revision 169049)
+++ gcc/cgraph.h	(working copy)
@@ -872,7 +872,7 @@ 
 
 struct GTY(()) constant_descriptor_tree {
   /* A MEM for the constant.  */
-  rtx rtl;
+  rtx GTY((skip)) rtl;
 
   /* The value of the constant.  */
   tree value;
Index: gcc/libfuncs.h
===================================================================
--- gcc/libfuncs.h	(revision 169049)
+++ gcc/libfuncs.h	(working copy)
@@ -53,14 +53,14 @@ 
 struct GTY(()) libfunc_entry {
   size_t optab;
   enum machine_mode mode1, mode2;
-  rtx libfunc;
+  rtx GTY((skip)) libfunc;
 };
 
 /* Target-dependent globals.  */
 struct GTY(()) target_libfuncs {
   /* SYMBOL_REF rtx's for the library functions that are called
      implicitly and not via optabs.  */
-  rtx x_libfunc_table[LTI_MAX];
+  rtx GTY((skip)) x_libfunc_table[LTI_MAX];
 
   /* Hash table used to convert declarations into nodes.  */
   htab_t GTY((param_is (struct libfunc_entry))) x_libfunc_hash;
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 169049)
+++ gcc/tree.h	(working copy)
@@ -2858,7 +2858,7 @@ 
 
 struct GTY(()) tree_decl_with_rtl {
   struct tree_decl_common common;
-  rtx rtl;
+  rtx GTY((skip)) rtl;
 };
 
 /* In a FIELD_DECL, this is the field position, counting in bytes, of the
@@ -2977,7 +2977,7 @@ 
 
 struct GTY(()) tree_parm_decl {
   struct tree_decl_with_rtl common;
-  rtx incoming_rtl;
+  rtx GTY((skip)) incoming_rtl;
   struct var_ann_d *ann;
 };
 
Index: gcc/reload.h
===================================================================
--- gcc/reload.h	(revision 169049)
+++ gcc/reload.h	(working copy)
@@ -204,7 +204,7 @@ 
 #define caller_save_initialized_p \
   (this_target_reload->x_caller_save_initialized_p)
 
-extern GTY (()) VEC(rtx,gc) *reg_equiv_memory_loc_vec;
+extern VEC(rtx,heap) *reg_equiv_memory_loc_vec;
 extern rtx *reg_equiv_constant;
 extern rtx *reg_equiv_invariant;
 extern rtx *reg_equiv_memory_loc;
@@ -214,10 +214,10 @@ 
 
 /* Element N is the list of insns that initialized reg N from its equivalent
    constant or memory slot.  */
-extern GTY((length("reg_equiv_init_size"))) rtx *reg_equiv_init;
+extern rtx *reg_equiv_init;
 
-/* The size of the previous array, for GC purposes.  */
-extern GTY(()) int reg_equiv_init_size;
+/* The size of the previous array.  */
+extern int reg_equiv_init_size;
 
 /* All the "earlyclobber" operands of the current insn
    are recorded here.  */
Index: gcc/lists.c
===================================================================
--- gcc/lists.c	(revision 169049)
+++ gcc/lists.c	(working copy)
@@ -25,17 +25,16 @@ 
 #include "tm.h"
 #include "diagnostic-core.h"
 #include "rtl.h"
-#include "ggc.h"
 
 static void free_list (rtx *, rtx *);
 
 /* Functions for maintaining cache-able lists of EXPR_LIST and INSN_LISTs.  */
 
 /* An INSN_LIST containing all INSN_LISTs allocated but currently unused.  */
-static GTY ((deletable)) rtx unused_insn_list;
+static rtx unused_insn_list;
 
 /* An EXPR_LIST containing all EXPR_LISTs allocated but currently unused.  */
-static GTY ((deletable)) rtx unused_expr_list;
+static rtx unused_expr_list;
 
 /* This function will free an entire list of either EXPR_LIST, INSN_LIST
    or DEPS_LIST nodes.  This is to be used only on lists that consist
@@ -214,5 +213,3 @@ 
 
   return elem;
 }
-
-#include "gt-lists.h"
Index: gcc/gensupport.c
===================================================================
--- gcc/gensupport.c	(revision 169049)
+++ gcc/gensupport.c	(working copy)
@@ -35,9 +35,6 @@ 
 
 int insn_elision = 1;
 
-static struct obstack obstack;
-struct obstack *rtl_obstack = &obstack;
-
 static int sequence_num;
 
 static int predicable_default;
@@ -1003,10 +1000,10 @@ 
 init_rtx_reader_args_cb (int argc, char **argv,
 			 bool (*parse_opt) (const char *))
 {
+  init_rtl ();
   /* Prepare to read input.  */
   condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
   init_predicate_table ();
-  obstack_init (rtl_obstack);
   sequence_num = 0;
 
   read_md_files (argc, argv, parse_opt, rtx_handle_directive);
Index: gcc/cfg.c
===================================================================
--- gcc/cfg.c	(revision 169049)
+++ gcc/cfg.c	(working copy)
@@ -614,7 +614,8 @@ 
       else if (df)
 	fprintf (file, "; set %d time%s", DF_REG_DEF_COUNT (i),
 		 (DF_REG_DEF_COUNT (i) == 1) ? "" : "s");
-      if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i]))
+      if (crtl->emit.regno_reg_rtx[i] != NULL
+          && REG_USERVAR_P (crtl->emit.regno_reg_rtx[i]))
 	fputs ("; user var", file);
       if (REG_N_DEATHS (i) != 1)
 	fprintf (file, "; dies in %d places", REG_N_DEATHS (i));
@@ -624,7 +625,7 @@ 
 	fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
       if (REG_FREQ_CALLS_CROSSED (i))
 	fprintf (file, "; crosses call with %d frequency", REG_FREQ_CALLS_CROSSED (i));
-      if (regno_reg_rtx[i] != NULL
+      if (crtl->emit.regno_reg_rtx[i] != NULL
 	  && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
 	fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
 
@@ -642,7 +643,8 @@ 
 		     reg_class_names[(int) altclass]);
 	}
 
-      if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i]))
+      if (crtl->emit.regno_reg_rtx[i] != NULL
+          && REG_POINTER (crtl->emit.regno_reg_rtx[i]))
 	fputs ("; pointer", file);
       fputs (".\n", file);
     }
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 169049)
+++ gcc/toplev.c	(working copy)
@@ -1648,6 +1648,7 @@ 
 static void
 backend_init (void)
 {
+  init_rtl ();
   init_emit_once ();
 
   init_rtlanal ();
Index: gcc/regs.h
===================================================================
--- gcc/regs.h	(revision 169049)
+++ gcc/regs.h	(working copy)
@@ -163,7 +163,7 @@ 
 
 /* Get the machine mode of pseudo-reg N.  */
 
-#define PSEUDO_REGNO_MODE(N) GET_MODE (regno_reg_rtx[N])
+#define PSEUDO_REGNO_MODE(N) GET_MODE (crtl->emit.regno_reg_rtx[N])
 
 /* Indexed by N, gives number of CALL_INSNS across which (REG n) is live.  */
 
Index: gcc/df-scan.c
===================================================================
--- gcc/df-scan.c	(revision 169049)
+++ gcc/df-scan.c	(working copy)
@@ -2020,7 +2020,7 @@ 
 	  unsigned int count = 0;
 
 	  DF_REF_REGNO (the_ref) = new_regno;
-	  DF_REF_REG (the_ref) = regno_reg_rtx[new_regno];
+	  DF_REF_REG (the_ref) = crtl->emit.regno_reg_rtx[new_regno];
 
 	  /* Pull the_ref out of the old regno chain.  */
 	  if (prev_ref)
@@ -2884,8 +2884,9 @@ 
 
       for (i = regno; i < endregno; i++)
 	{
-	  ref = df_ref_create_structure (cl, collection_rec, regno_reg_rtx[i], loc,
-					 bb, insn_info, ref_type, ref_flags);
+	  ref = df_ref_create_structure (cl, collection_rec,
+					 crtl->emit.regno_reg_rtx[i], loc, bb,
+					 insn_info, ref_type, ref_flags);
 
           gcc_assert (ORIGINAL_REGNO (DF_REF_REG (ref)) == i);
 	}
@@ -3356,7 +3357,8 @@ 
     }
 
   /* The stack ptr is used (honorarily) by a CALL insn.  */
-  df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[STACK_POINTER_REGNUM],
+  df_ref_record (DF_REF_BASE, collection_rec,
+                 crtl->emit.regno_reg_rtx[STACK_POINTER_REGNUM],
 		 NULL, bb, insn_info, DF_REF_REG_USE,
 		 DF_REF_CALL_STACK_USAGE | flags);
 
@@ -3365,10 +3367,12 @@ 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (global_regs[i])
       {
-	df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
-		       NULL, bb, insn_info, DF_REF_REG_USE, flags);
-	df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
-		       NULL, bb, insn_info, DF_REF_REG_DEF, flags);
+	df_ref_record (DF_REF_BASE, collection_rec,
+		       crtl->emit.regno_reg_rtx[i], NULL, bb, insn_info,
+		       DF_REF_REG_USE, flags);
+	df_ref_record (DF_REF_BASE, collection_rec,
+		       crtl->emit.regno_reg_rtx[i], NULL, bb, insn_info,
+		       DF_REF_REG_DEF, flags);
       }
 
   is_sibling_call = SIBLING_CALL_P (insn_info->insn);
@@ -3380,9 +3384,9 @@ 
 	      || !bitmap_bit_p (df->exit_block_uses, ui)
 	      || refers_to_regno_p (ui, ui+1,
 				    crtl->return_rtx, NULL)))
-        df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[ui],
-		       NULL, bb, insn_info, DF_REF_REG_DEF,
-		       DF_REF_MAY_CLOBBER | flags);
+	df_ref_record (DF_REF_BASE, collection_rec,
+		       crtl->emit.regno_reg_rtx[ui], NULL, bb, insn_info,
+		       DF_REF_REG_DEF, DF_REF_MAY_CLOBBER | flags);
     }
 
   bitmap_clear (&defs_generated);
@@ -3425,12 +3429,12 @@ 
         case REG_NON_LOCAL_GOTO:
           /* The frame ptr is used by a non-local goto.  */
           df_ref_record (DF_REF_BASE, collection_rec,
-                         regno_reg_rtx[FRAME_POINTER_REGNUM],
+                         crtl->emit.regno_reg_rtx[FRAME_POINTER_REGNUM],
                          NULL, bb, insn_info,
                          DF_REF_REG_USE, 0);
 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
           df_ref_record (DF_REF_BASE, collection_rec,
-                         regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
+                         crtl->emit.regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
                          NULL, bb, insn_info,
                          DF_REF_REG_USE, 0);
 #endif
@@ -3516,8 +3520,9 @@ 
 	  unsigned regno = EH_RETURN_DATA_REGNO (i);
 	  if (regno == INVALID_REGNUM)
 	    break;
-	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL,
-			 bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP);
+	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec,
+			 crtl->emit.regno_reg_rtx[regno], NULL, bb, NULL,
+			 DF_REF_REG_DEF, DF_REF_AT_TOP);
 	}
     }
 #endif
@@ -3539,8 +3544,9 @@ 
 
       EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi)
 	{
-	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL,
-			 bb, NULL, DF_REF_REG_USE, 0);
+	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec,
+			 crtl->emit.regno_reg_rtx[regno], NULL, bb, NULL,
+			 DF_REF_REG_USE, 0);
 	}
     }
 
@@ -3815,8 +3821,9 @@ 
 
   EXECUTE_IF_SET_IN_BITMAP (entry_block_defs, 0, i, bi)
     {
-      df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
-		     ENTRY_BLOCK_PTR, NULL, DF_REF_REG_DEF, 0);
+      df_ref_record (DF_REF_ARTIFICIAL, collection_rec,
+		     crtl->emit.regno_reg_rtx[i], NULL, ENTRY_BLOCK_PTR, NULL,
+		     DF_REF_REG_DEF, 0);
     }
 
   df_canonize_collection_rec (collection_rec);
@@ -3977,8 +3984,9 @@ 
   bitmap_iterator bi;
 
   EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi)
-    df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
-		   EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0);
+    df_ref_record (DF_REF_ARTIFICIAL, collection_rec,
+		   crtl->emit.regno_reg_rtx[i], NULL, EXIT_BLOCK_PTR, NULL,
+		   DF_REF_REG_USE, 0);
 
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
   /* It is deliberate that this is not put in the exit block uses but
@@ -3987,7 +3995,8 @@ 
       && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM)
       && bb_has_eh_pred (EXIT_BLOCK_PTR)
       && fixed_regs[ARG_POINTER_REGNUM])
-    df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
+    df_ref_record (DF_REF_ARTIFICIAL, collection_rec,
+		   crtl->emit.regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
 		   EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0);
 #endif
 
Index: gcc/dojump.c
===================================================================
--- gcc/dojump.c	(revision 169049)
+++ gcc/dojump.c	(working copy)
@@ -33,7 +33,6 @@ 
 #include "expr.h"
 #include "optabs.h"
 #include "langhooks.h"
-#include "ggc.h"
 #include "basic-block.h"
 #include "output.h"
 
@@ -132,9 +131,9 @@ 
 
 /* Used internally by prefer_and_bit_test.  */
 
-static GTY(()) rtx and_reg;
-static GTY(()) rtx and_test;
-static GTY(()) rtx shift_test;
+static rtx and_reg;
+static rtx and_test;
+static rtx shift_test;
 
 /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1",
    where X is an arbitrary register of mode MODE.  Return true if the former
@@ -1185,5 +1184,3 @@ 
                             ? expr_size (treeop0) : NULL_RTX),
 			   if_false_label, if_true_label, prob);
 }
-
-#include "gt-dojump.h"
Index: gcc/caller-save.c
===================================================================
--- gcc/caller-save.c	(revision 169049)
+++ gcc/caller-save.c	(working copy)
@@ -38,7 +38,6 @@ 
 #include "tm_p.h"
 #include "addresses.h"
 #include "output.h"
-#include "ggc.h"
 
 #define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD)
 
@@ -100,12 +99,12 @@ 
 
 
 
-static GTY(()) rtx savepat;
-static GTY(()) rtx restpat;
-static GTY(()) rtx test_reg;
-static GTY(()) rtx test_mem;
-static GTY(()) rtx saveinsn;
-static GTY(()) rtx restinsn;
+static rtx savepat;
+static rtx restpat;
+static rtx test_reg;
+static rtx test_mem;
+static rtx saveinsn;
+static rtx restinsn;
 
 /* Return the INSN_CODE used to save register REG in mode MODE.  */
 static int
@@ -431,7 +430,7 @@ 
       {
 	unsigned int regno = reg_renumber[i];
 	unsigned int endregno
-	  = end_hard_regno (GET_MODE (regno_reg_rtx[i]), regno);
+	  = end_hard_regno (GET_MODE (crtl->emit.regno_reg_rtx[i]), regno);
 	for (r = regno; r < endregno; r++)
 	  if (call_used_regs[r])
 	    SET_HARD_REG_BIT (hard_regs_used, r);
@@ -1422,4 +1421,3 @@ 
   INSN_CODE (new_chain->insn) = code;
   return new_chain;
 }
-#include "gt-caller-save.h"
Index: gcc/cse.c
===================================================================
--- gcc/cse.c	(revision 169049)
+++ gcc/cse.c	(working copy)
@@ -2915,9 +2915,11 @@ 
 	q = REG_QTY (REGNO (x));
 	ent = &qty_table[q];
 	first = ent->first_reg;
-	return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
-		: REGNO_REG_CLASS (first) == NO_REGS ? x
-		: gen_rtx_REG (ent->mode, first));
+	return (first >= FIRST_PSEUDO_REGISTER
+		? crtl->emit.regno_reg_rtx[first]
+		: REGNO_REG_CLASS (first) == NO_REGS
+		  ? x
+		  : gen_rtx_REG (ent->mode, first));
       }
 
     default:
@@ -5213,7 +5215,8 @@ 
 	      int first = src_ent->first_reg;
 	      rtx new_src
 		= (first >= FIRST_PSEUDO_REGISTER
-		   ? regno_reg_rtx[first] : gen_rtx_REG (GET_MODE (src), first));
+		   ? crtl->emit.regno_reg_rtx[first]
+		   : gen_rtx_REG (GET_MODE (src), first));
 
 	      /* We must use validate-change even for this, because this
 		 might be a special no-op instruction, suitable only to
Index: gcc/vecir.h
===================================================================
--- gcc/vecir.h	(revision 169049)
+++ gcc/vecir.h	(working copy)
@@ -47,6 +47,5 @@ 
 /* A varray of RTX objects.  */
 DEF_VEC_P(rtx);
 DEF_VEC_ALLOC_P(rtx,heap);
-DEF_VEC_ALLOC_P(rtx,gc);
 
 #endif /* GCC_VECIR_H */
Index: gcc/ira-color.c
===================================================================
--- gcc/ira-color.c	(revision 169049)
+++ gcc/ira-color.c	(working copy)
@@ -2750,7 +2750,7 @@ 
     {
       if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
 	fprintf (ira_dump_file, ": reassign to %d\n", reg_renumber[regno]);
-      SET_REGNO (regno_reg_rtx[regno], reg_renumber[regno]);
+      SET_REGNO (crtl->emit.regno_reg_rtx[regno], reg_renumber[regno]);
       mark_home_live (regno);
     }
   else if (internal_flag_ira_verbose > 3 && ira_dump_file != NULL)
Index: gcc/sel-sched.c
===================================================================
--- gcc/sel-sched.c	(revision 169049)
+++ gcc/sel-sched.c	(working copy)
@@ -5321,7 +5321,7 @@ 
   /* First, reflect that something is scheduled on this fence.  */
   asm_p = advance_state_on_fence (fence, insn);
   FENCE_LAST_SCHEDULED_INSN (fence) = insn;
-  VEC_safe_push (rtx, gc, FENCE_EXECUTING_INSNS (fence), insn);
+  VEC_safe_push (rtx, heap, FENCE_EXECUTING_INSNS (fence), insn);
   if (SCHED_GROUP_P (insn))
     {
       FENCE_SCHED_NEXT (fence) = INSN_SCHED_NEXT (insn);
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 169049)
+++ gcc/dwarf2out.c	(working copy)
@@ -201,10 +201,6 @@ 
 #define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
 #endif
 
-/* Array of RTXes referenced by the debugging information, which therefore
-   must be kept around forever.  */
-static GTY(()) VEC(rtx,gc) *used_rtx_array;
-
 /* A pointer to the base of a list of incomplete types which might be
    completed at some later time.  incomplete_types_list needs to be a
    VEC(tree,gc) because we want to tell the garbage collector about
@@ -235,7 +231,7 @@ 
 
 /* Personality decl of current unit.  Used only when assembler does not support
    personality CFI.  */
-static GTY(()) rtx current_unit_personality;
+static rtx current_unit_personality;
 
 /* How to start an assembler comment.  */
 #ifndef ASM_COMMENT_START
@@ -1744,17 +1740,17 @@ 
    of the prologue or (b) the register is clobbered.  This clusters
    register saves so that there are fewer pc advances.  */
 
-struct GTY(()) queued_reg_save {
+struct queued_reg_save {
   struct queued_reg_save *next;
   rtx reg;
   HOST_WIDE_INT cfa_offset;
   rtx saved_reg;
 };
 
-static GTY(()) struct queued_reg_save *queued_reg_saves;
+static struct queued_reg_save *queued_reg_saves;
 
 /* The caller's ORIG_REG is saved in SAVED_IN_REG.  */
-struct GTY(()) reg_saved_in_data {
+struct reg_saved_in_data {
   rtx orig_reg;
   rtx saved_in_reg;
 };
@@ -1763,8 +1759,8 @@ 
    The list intentionally has a small maximum capacity of 4; if your
    port needs more than that, you might consider implementing a
    more efficient data structure.  */
-static GTY(()) struct reg_saved_in_data regs_saved_in_regs[4];
-static GTY(()) size_t num_regs_saved_in_regs;
+static struct reg_saved_in_data regs_saved_in_regs[4];
+static size_t num_regs_saved_in_regs;
 
 static const char *last_reg_save_label;
 
@@ -1785,7 +1781,7 @@ 
 
   if (q == NULL)
     {
-      q = ggc_alloc_queued_reg_save ();
+      q = XNEW (struct queued_reg_save);
       q->next = queued_reg_saves;
       queued_reg_saves = q;
     }
@@ -1803,12 +1799,15 @@ 
 dwarf2out_flush_queued_reg_saves (void)
 {
   struct queued_reg_save *q;
+  struct queued_reg_save *next;
 
-  for (q = queued_reg_saves; q; q = q->next)
+  for (q = queued_reg_saves; q; q = next)
     {
       size_t i;
       unsigned int reg, sreg;
 
+      next = q->next;
+
       for (i = 0; i < num_regs_saved_in_regs; i++)
 	if (REGNO (regs_saved_in_regs[i].orig_reg) == REGNO (q->reg))
 	  break;
@@ -1829,6 +1828,7 @@ 
       else
 	sreg = INVALID_REGNUM;
       reg_save (last_reg_save_label, reg, sreg, q->cfa_offset);
+      free (q);
     }
 
   queued_reg_saves = NULL;
@@ -4407,7 +4407,7 @@ 
   enum dw_val_class val_class;
   union dw_val_struct_union
     {
-      rtx GTY ((tag ("dw_val_class_addr"))) val_addr;
+      rtx GTY ((tag ("dw_val_class_addr"),skip)) val_addr;
       unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset"))) val_offset;
       dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list"))) val_loc_list;
       dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc;
@@ -6017,7 +6017,7 @@ 
      mode is 0 and first operand is a CONCAT with bitsize
      as first CONCAT operand and NOTE_INSN_VAR_LOCATION resp.
      NULL as second operand.  */
-  rtx GTY (()) loc;
+  rtx GTY ((skip)) loc;
   const char * GTY (()) label;
   struct var_loc_node * GTY (()) next;
 };
@@ -13876,8 +13876,8 @@ 
     symref:
       mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
       mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
-      mem_loc_result->dw_loc_oprnd1.v.val_addr = rtl;
-      VEC_safe_push (rtx, gc, used_rtx_array, rtl);
+      mem_loc_result->dw_loc_oprnd1.v.val_addr
+	= copy_rtx_to_permanent_mem (rtl);
       break;
 
     case CONCAT:
@@ -14739,9 +14739,9 @@ 
 	{
 	  loc_result = new_loc_descr (DW_OP_addr, 0, 0);
 	  loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
-	  loc_result->dw_loc_oprnd1.v.val_addr = rtl;
+	  loc_result->dw_loc_oprnd1.v.val_addr
+	    = copy_rtx_to_permanent_mem (rtl);
 	  add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
-	  VEC_safe_push (rtx, gc, used_rtx_array, rtl);
 	}
       break;
 
@@ -16432,10 +16432,10 @@ 
 	rtl_addr:
 	  loc_result = new_loc_descr (DW_OP_addr, 0, 0);
 	  loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
-	  loc_result->dw_loc_oprnd1.v.val_addr = rtl;
+	  loc_result->dw_loc_oprnd1.v.val_addr
+	    = copy_rtx_to_permanent_mem (rtl);
 	  add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
 	  add_AT_loc (die, DW_AT_location, loc_result);
-	  VEC_safe_push (rtx, gc, used_rtx_array, rtl);
 	  return true;
 	}
       return false;
@@ -22162,8 +22162,6 @@ 
 
   incomplete_types = VEC_alloc (tree, gc, 64);
 
-  used_rtx_array = VEC_alloc (rtx, gc, 32);
-
   debug_info_section = get_section (DEBUG_INFO_SECTION,
 				    SECTION_DEBUG, NULL);
   debug_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
@@ -22719,8 +22717,7 @@ 
       if (!rtl || !MEM_P (rtl))
 	return 1;
       rtl = XEXP (rtl, 0);
-      VEC_safe_push (rtx, gc, used_rtx_array, rtl);
-      *addr = rtl;
+      *addr = copy_rtx_to_permanent_mem (rtl);
       return 0;
     }
 
Index: gcc/expr.c
===================================================================
--- gcc/expr.c	(revision 169049)
+++ gcc/expr.c	(working copy)
@@ -2204,7 +2204,7 @@ 
   gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
 
   for (i = 0; i < nregs; i++)
-    use_reg (call_fusage, regno_reg_rtx[regno + i]);
+    use_reg (call_fusage, crtl->emit.regno_reg_rtx[regno + i]);
 }
 
 /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
Index: gcc/tree-ssa-address.c
===================================================================
--- gcc/tree-ssa-address.c	(revision 169049)
+++ gcc/tree-ssa-address.c	(working copy)
@@ -43,7 +43,6 @@ 
 #include "rtl.h"
 #include "recog.h"
 #include "expr.h"
-#include "ggc.h"
 #include "target.h"
 
 /* TODO -- handling of symbols (according to Richard Hendersons
@@ -73,22 +72,22 @@ 
 /* A "template" for memory address, used to determine whether the address is
    valid for mode.  */
 
-typedef struct GTY (()) mem_addr_template {
+typedef struct mem_addr_template {
   rtx ref;			/* The template.  */
-  rtx * GTY ((skip)) step_p;	/* The point in template where the step should be
+  rtx * step_p;	/* The point in template where the step should be
 				   filled in.  */
-  rtx * GTY ((skip)) off_p;	/* The point in template where the offset should
+  rtx * off_p;	/* The point in template where the offset should
 				   be filled in.  */
 } mem_addr_template;
 
 DEF_VEC_O (mem_addr_template);
-DEF_VEC_ALLOC_O (mem_addr_template, gc);
+DEF_VEC_ALLOC_O (mem_addr_template, heap);
 
 /* The templates.  Each of the low five bits of the index corresponds to one
    component of TARGET_MEM_REF being present, while the high bits identify
    the address space.  See TEMPL_IDX.  */
 
-static GTY(()) VEC (mem_addr_template, gc) *mem_addr_template_list;
+static VEC (mem_addr_template, heap) *mem_addr_template_list;
 
 #define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \
   (((int) (AS) << 5) \
@@ -212,7 +211,7 @@ 
 
       if (templ_index
 	  >= VEC_length (mem_addr_template, mem_addr_template_list))
-	VEC_safe_grow_cleared (mem_addr_template, gc, mem_addr_template_list,
+	VEC_safe_grow_cleared (mem_addr_template, heap, mem_addr_template_list,
 			       templ_index + 1);
 
       /* Reuse the templates for addresses, so that we do not waste memory.  */
@@ -948,5 +947,3 @@ 
       fprintf (file, "\n");
     }
 }
-
-#include "gt-tree-ssa-address.h"
Index: gcc/sel-sched-ir.c
===================================================================
--- gcc/sel-sched-ir.c	(revision 169049)
+++ gcc/sel-sched-ir.c	(working copy)
@@ -262,7 +262,7 @@ 
 /* Add new fence consisting of INSN and STATE to the list pointed to by LP.  */
 static void
 flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc,
-           insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns,
+           insn_t last_scheduled_insn, VEC(rtx,heap) *executing_insns,
            int *ready_ticks, int ready_ticks_size, insn_t sched_next,
            int cycle, int cycle_issued_insns, int issue_more,
            bool starts_cycle_p, bool after_stall_p)
@@ -588,7 +588,7 @@ 
 
   if (tc != NULL)
     delete_target_context (tc);
-  VEC_free (rtx, gc, FENCE_EXECUTING_INSNS (f));
+  VEC_free (rtx, heap, FENCE_EXECUTING_INSNS (f));
   free (FENCE_READY_TICKS (f));
   FENCE_READY_TICKS (f) = NULL;
 }
@@ -638,7 +638,7 @@ 
 static void
 merge_fences (fence_t f, insn_t insn,
 	      state_t state, deps_t dc, void *tc,
-              rtx last_scheduled_insn, VEC(rtx, gc) *executing_insns,
+              rtx last_scheduled_insn, VEC(rtx, heap) *executing_insns,
               int *ready_ticks, int ready_ticks_size,
 	      rtx sched_next, int cycle, int issue_more, bool after_stall_p)
 {
@@ -671,7 +671,7 @@ 
 
       FENCE_LAST_SCHEDULED_INSN (f) = NULL;
       FENCE_ISSUE_MORE (f) = issue_rate;
-      VEC_free (rtx, gc, executing_insns);
+      VEC_free (rtx, heap, executing_insns);
       free (ready_ticks);
       if (FENCE_EXECUTING_INSNS (f))
         VEC_block_remove (rtx, FENCE_EXECUTING_INSNS (f), 0,
@@ -759,7 +759,7 @@ 
           {
             reset_deps_context (FENCE_DC (f));
             delete_deps_context (dc);
-            VEC_free (rtx, gc, executing_insns);
+            VEC_free (rtx, heap, executing_insns);
             free (ready_ticks);
 
             FENCE_CYCLE (f) = MAX (FENCE_CYCLE (f), cycle);
@@ -774,7 +774,7 @@ 
             {
               delete_deps_context (FENCE_DC (f));
               FENCE_DC (f) = dc;
-              VEC_free (rtx, gc, FENCE_EXECUTING_INSNS (f));
+              VEC_free (rtx, heap, FENCE_EXECUTING_INSNS (f));
               FENCE_EXECUTING_INSNS (f) = executing_insns;
               free (FENCE_READY_TICKS (f));
               FENCE_READY_TICKS (f) = ready_ticks;
@@ -785,7 +785,7 @@ 
             {
               /* Leave DC and CYCLE untouched.  */
               delete_deps_context (dc);
-              VEC_free (rtx, gc, executing_insns);
+              VEC_free (rtx, heap, executing_insns);
               free (ready_ticks);
             }
     }
@@ -804,7 +804,7 @@ 
 static void
 add_to_fences (flist_tail_t new_fences, insn_t insn,
                state_t state, deps_t dc, void *tc, rtx last_scheduled_insn,
-               VEC(rtx, gc) *executing_insns, int *ready_ticks,
+               VEC(rtx, heap) *executing_insns, int *ready_ticks,
                int ready_ticks_size, rtx sched_next, int cycle,
                int cycle_issued_insns, int issue_rate,
 	       bool starts_cycle_p, bool after_stall_p)
@@ -888,7 +888,7 @@ 
                  create_copy_of_deps_context (FENCE_DC (fence)),
                  create_copy_of_target_context (FENCE_TC (fence)),
                  FENCE_LAST_SCHEDULED_INSN (fence),
-                 VEC_copy (rtx, gc, FENCE_EXECUTING_INSNS (fence)),
+                 VEC_copy (rtx, heap, FENCE_EXECUTING_INSNS (fence)),
                  new_ready_ticks,
                  FENCE_READY_TICKS_SIZE (fence),
                  FENCE_SCHED_NEXT (fence),
Index: gcc/sel-sched-ir.h
===================================================================
--- gcc/sel-sched-ir.h	(revision 169049)
+++ gcc/sel-sched-ir.h	(working copy)
@@ -284,7 +284,7 @@ 
   tc_t tc;
 
   /* A vector of insns that are scheduled but not yet completed.  */
-  VEC (rtx,gc) *executing_insns;
+  VEC (rtx,heap) *executing_insns;
 
   /* A vector indexed by UIDs that caches the earliest cycle on which
      an insn can be scheduled on this fence.  */
Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 169049)
+++ gcc/function.c	(working copy)
@@ -124,10 +124,8 @@ 
 struct function *cfun = 0;
 
 /* These hashes record the prologue and epilogue insns.  */
-static GTY((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
-  htab_t prologue_insn_hash;
-static GTY((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
-  htab_t epilogue_insn_hash;
+static htab_t prologue_insn_hash;
+static htab_t epilogue_insn_hash;
 
 
 htab_t types_used_by_vars_hash = NULL;
@@ -208,18 +206,25 @@ 
 void
 free_after_compilation (struct function *f)
 {
+  if (prologue_insn_hash)
+    htab_delete (prologue_insn_hash);
   prologue_insn_hash = NULL;
+  if (epilogue_insn_hash)
+    htab_delete (epilogue_insn_hash);
   epilogue_insn_hash = NULL;
 
   if (crtl->emit.regno_pointer_align)
     free (crtl->emit.regno_pointer_align);
 
+  if (crtl->emit.regno_reg_rtx)
+    free (crtl->emit.regno_reg_rtx);
+  crtl->emit.regno_reg_rtx = NULL;
+
   memset (crtl, 0, sizeof (struct rtl_data));
   f->eh = NULL;
   f->machine = NULL;
   f->cfg = NULL;
 
-  regno_reg_rtx = NULL;
   insn_locators_free ();
 }
 
@@ -339,7 +344,8 @@ 
 static void
 add_frame_space (HOST_WIDE_INT start, HOST_WIDE_INT end)
 {
-  struct frame_space *space = ggc_alloc_frame_space ();
+  struct frame_space *space
+    = (struct frame_space *) allocate_in_rtl_mem (sizeof (struct frame_space));
   space->next = crtl->frame_space_list;
   crtl->frame_space_list = space;
   space->start = start;
@@ -535,7 +541,7 @@ 
    level where they are defined.  They are marked a "kept" so that
    free_temp_slots will not free them.  */
 
-struct GTY(()) temp_slot {
+struct temp_slot {
   /* Points to next temporary slot.  */
   struct temp_slot *next;
   /* Points to previous temporary slot.  */
@@ -569,10 +575,10 @@ 
 
 /* A table of addresses that represent a stack slot.  The table is a mapping
    from address RTXen to a temp slot.  */
-static GTY((param_is(struct temp_slot_address_entry))) htab_t temp_slot_address_table;
+static htab_t temp_slot_address_table;
 
 /* Entry for the above hash table.  */
-struct GTY(()) temp_slot_address_entry {
+struct temp_slot_address_entry {
   hashval_t hash;
   rtx address;
   struct temp_slot *temp_slot;
@@ -611,7 +617,7 @@ 
 temp_slots_at_level (int level)
 {
   if (level >= (int) VEC_length (temp_slot_p, used_temp_slots))
-    VEC_safe_grow_cleared (temp_slot_p, gc, used_temp_slots, level + 1);
+    VEC_safe_grow_cleared (temp_slot_p, heap, used_temp_slots, level + 1);
 
   return &(VEC_address (temp_slot_p, used_temp_slots)[level]);
 }
@@ -682,7 +688,9 @@ 
 insert_temp_slot_address (rtx address, struct temp_slot *temp_slot)
 {
   void **slot;
-  struct temp_slot_address_entry *t = ggc_alloc_temp_slot_address_entry ();
+  struct temp_slot_address_entry *t
+      = (struct temp_slot_address_entry *)
+      allocate_in_rtl_mem (sizeof (struct temp_slot_address_entry));
   t->address = address;
   t->temp_slot = temp_slot;
   t->hash = temp_slot_address_compute_hash (t);
@@ -834,7 +842,8 @@ 
 
 	  if (best_p->size - rounded_size >= alignment)
 	    {
-	      p = ggc_alloc_temp_slot ();
+              p = (struct temp_slot *)
+                  allocate_in_rtl_mem (sizeof (struct temp_slot));
 	      p->in_use = p->addr_taken = 0;
 	      p->size = best_p->size - rounded_size;
 	      p->base_offset = best_p->base_offset + rounded_size;
@@ -858,7 +867,7 @@ 
     {
       HOST_WIDE_INT frame_offset_old = frame_offset;
 
-      p = ggc_alloc_temp_slot ();
+      p = (struct temp_slot *) allocate_in_rtl_mem (sizeof (struct temp_slot));
 
       /* We are passing an explicit alignment request to assign_stack_local.
 	 One side effect of that is assign_stack_local will not round SIZE
@@ -1311,10 +1320,8 @@ 
 
   /* Set up the table to map addresses to temp slots.  */
   if (! temp_slot_address_table)
-    temp_slot_address_table = htab_create_ggc (32,
-					       temp_slot_address_hash,
-					       temp_slot_address_eq,
-					       NULL);
+    temp_slot_address_table = htab_create (32, temp_slot_address_hash,
+                                           temp_slot_address_eq, NULL);
   else
     htab_empty (temp_slot_address_table);
 }
@@ -3152,9 +3159,9 @@ 
 	      if (set == 0)
 		continue;
 
-	      if (SET_DEST (set) == regno_reg_rtx [regnoi])
+	      if (SET_DEST (set) == crtl->emit.regno_reg_rtx [regnoi])
 		set_unique_reg_note (sinsn, REG_EQUIV, stacki);
-	      else if (SET_DEST (set) == regno_reg_rtx [regnor])
+	      else if (SET_DEST (set) == crtl->emit.regno_reg_rtx [regnor])
 		set_unique_reg_note (sinsn, REG_EQUIV, stackr);
 	    }
 	}
@@ -4872,8 +4879,6 @@ 
       warning (OPT_Wunused_parameter, "unused parameter %q+D", decl);
 }
 
-static GTY(()) rtx initial_trampoline;
-
 /* Generate RTL for the end of the current function.  */
 
 void
@@ -5165,7 +5170,7 @@ 
 
   if (hash == NULL)
     *hashp = hash
-      = htab_create_ggc (17, htab_hash_pointer, htab_eq_pointer, NULL);
+      = htab_create (17, htab_hash_pointer, htab_eq_pointer, NULL);
 
   for (tmp = insns; tmp != end; tmp = NEXT_INSN (tmp))
     {
Index: gcc/function.h
===================================================================
--- gcc/function.h	(revision 169049)
+++ gcc/function.h	(working copy)
@@ -33,14 +33,14 @@ 
    The main insn-chain is saved in the last element of the chain,
    unless the chain is empty.  */
 
-struct GTY(()) sequence_stack {
+struct sequence_stack {
   /* First and last insns in the chain of the saved sequence.  */
   rtx first;
   rtx last;
   struct sequence_stack *next;
 };
 
-struct GTY(()) emit_status {
+struct emit_status {
   /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function.
      After rtl generation, it is 1 plus the largest register number used.  */
   int x_reg_rtx_no;
@@ -62,6 +62,9 @@ 
      unless the chain is empty.  */
   struct sequence_stack *sequence_stack;
 
+  /* Space for free sequence stack entries.  */
+  struct sequence_stack *free_sequence_stack;
+
   /* INSN_UID for next insn emitted.
      Reset to 1 for each function compiled.  */
   int x_cur_insn_uid;
@@ -83,24 +86,20 @@ 
   /* Indexed by pseudo register number, if nonzero gives the known alignment
      for that pseudo (if REG_POINTER is set in x_regno_reg_rtx).
      Allocated in parallel with x_regno_reg_rtx.  */
-  unsigned char * GTY((skip)) regno_pointer_align;
+  unsigned char *regno_pointer_align;
+
+  /* Indexed by pseudo register number, gives the rtx for that pseudo.
+     Allocated in parallel with regno_pointer_align.  */
+  rtx *regno_reg_rtx;
 };
 
-
-/* Indexed by pseudo register number, gives the rtx for that pseudo.
-   Allocated in parallel with regno_pointer_align.
-   FIXME: We could put it into emit_status struct, but gengtype is not able to deal
-   with length attribute nested in top level structures.  */
-
-extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx;
-
 /* For backward compatibility... eventually these should all go away.  */
 #define reg_rtx_no (crtl->emit.x_reg_rtx_no)
 #define seq_stack (crtl->emit.sequence_stack)
 
 #define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
 
-struct GTY(()) expr_status {
+struct expr_status {
   /* Number of units that we should eventually pop off the stack.
      These are the arguments to function calls that have already returned.  */
   int x_pending_stack_adjust;
@@ -142,10 +141,10 @@ 
 
 typedef struct call_site_record_d *call_site_record;
 DEF_VEC_P(call_site_record);
-DEF_VEC_ALLOC_P(call_site_record, gc);
+DEF_VEC_ALLOC_P(call_site_record, heap);
 
 /* RTL representation of exception handling.  */
-struct GTY(()) rtl_eh {
+struct rtl_eh {
   rtx ehr_stackadj;
   rtx ehr_handler;
   rtx ehr_label;
@@ -153,9 +152,9 @@ 
   rtx sjlj_fc;
   rtx sjlj_exit_after;
 
-  VEC(uchar,gc) *action_record_data;
+  VEC(uchar,heap) *action_record_data;
 
-  VEC(call_site_record,gc) *call_site_record[2];
+  VEC(call_site_record,heap) *call_site_record[2];
 };
 
 #define pending_stack_adjust (crtl->expr.x_pending_stack_adjust)
@@ -171,14 +170,14 @@ 
 struct call_site_record_d;
 
 DEF_VEC_P(temp_slot_p);
-DEF_VEC_ALLOC_P(temp_slot_p,gc);
+DEF_VEC_ALLOC_P(temp_slot_p,heap);
 struct ipa_opt_pass_d;
 typedef struct ipa_opt_pass_d *ipa_opt_pass;
 
 DEF_VEC_P(ipa_opt_pass);
 DEF_VEC_ALLOC_P(ipa_opt_pass,heap);
 
-struct GTY(()) varasm_status {
+struct varasm_status {
   /* If we're using a per-function constant pool, this is it.  */
   struct rtx_constant_pool *pool;
 
@@ -188,7 +187,7 @@ 
 };
 
 /* Information mainlined about RTL representation of incoming arguments.  */
-struct GTY(()) incoming_args {
+struct incoming_args {
   /* Number of bytes of args popped by function being compiled on its return.
      Zero if no bytes are to be popped.
      May affect compilation of return insn or of function epilogue.  */
@@ -231,7 +230,7 @@ 
 /* Describe an empty area of space in the stack frame.  These can be chained
    into a list; this is used to keep track of space wasted for alignment
    reasons.  */
-struct GTY(()) frame_space
+struct frame_space
 {
   struct frame_space *next;
 
@@ -240,7 +239,7 @@ 
 };
 
 /* Datastructures maintained for currently processed function in RTL form.  */
-struct GTY(()) rtl_data {
+struct rtl_data {
   struct expr_status expr;
   struct emit_status emit;
   struct varasm_status varasm;
@@ -310,7 +309,7 @@ 
   rtx x_parm_birth_insn;
 
   /* List of all used temporaries allocated, by level.  */
-  VEC(temp_slot_p,gc) *x_used_temp_slots;
+  VEC(temp_slot_p,heap) *x_used_temp_slots;
 
   /* List of available temp slots.  */
   struct temp_slot *x_avail_temp_slots;
@@ -456,7 +455,7 @@ 
 #define stack_realign_fp (crtl->stack_realign_needed && !crtl->need_drap)
 #define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap)
 
-extern GTY(()) struct rtl_data x_rtl;
+extern struct rtl_data x_rtl;
 
 /* Accessor to RTL datastructures.  We keep them statically allocated now since
    we never keep multiple functions.  For threaded compiler we might however
@@ -535,10 +534,13 @@ 
   /* Vector of function local variables, functions, types and constants.  */
   VEC(tree,gc) *local_decls;
 
+  /* Vector of various tree declarations.  */
+  VEC(tree,gc) *debug_decls;
+
   /* For md files.  */
 
   /* tm.h can use this to store whatever it likes.  */
-  struct machine_function * GTY ((maybe_undef)) machine;
+  struct machine_function * GTY ((skip)) machine;
 
   /* Language-specific code can use this to store whatever it likes.  */
   struct language_function * language;
Index: gcc/ira-emit.c
===================================================================
--- gcc/ira-emit.c	(revision 169049)
+++ gcc/ira-emit.c	(working copy)
@@ -1097,7 +1097,7 @@ 
   ira_allocno_iterator ai;
 
   FOR_EACH_ALLOCNO (a, ai)
-    ALLOCNO_REG (a) = regno_reg_rtx[ALLOCNO_REGNO (a)];
+    ALLOCNO_REG (a) = crtl->emit.regno_reg_rtx[ALLOCNO_REGNO (a)];
   if (! loops_p)
     return;
   at_bb_start = (move_t *) ira_allocate (sizeof (move_t) * last_basic_block);
Index: gcc/gcse.c
===================================================================
--- gcc/gcse.c	(revision 169049)
+++ gcc/gcse.c	(working copy)
@@ -159,7 +159,6 @@ 
 #include "function.h"
 #include "expr.h"
 #include "except.h"
-#include "ggc.h"
 #include "params.h"
 #include "cselib.h"
 #include "intl.h"
@@ -849,7 +848,7 @@ 
 
 /* Used internally by can_assign_to_reg_without_clobbers_p.  */
 
-static GTY(()) rtx test_insn;
+static rtx test_insn;
 
 /* Return true if we can assign X to a pseudo register such that the
    resulting insn does not result in clobbering a hard register as a
@@ -5437,6 +5436,3 @@ 
   TODO_verify_flow | TODO_ggc_collect   /* todo_flags_finish */
  }
 };
-
-#include "gt-gcse.h"
-
Index: gcc/alias.c
===================================================================
--- gcc/alias.c	(revision 169049)
+++ gcc/alias.c	(working copy)
@@ -203,13 +203,13 @@ 
    current function performs nonlocal memory memory references for the
    purposes of marking the function as a constant function.  */
 
-static GTY(()) VEC(rtx,gc) *reg_base_value;
+static VEC(rtx,heap) *reg_base_value;
 static rtx *new_reg_base_value;
 
 /* We preserve the copy of old array around to avoid amount of garbage
    produced.  About 8% of garbage produced were attributed to this
    array.  */
-static GTY((deletable)) VEC(rtx,gc) *old_reg_base_value;
+static VEC(rtx,heap) *old_reg_base_value;
 
 #define static_reg_base_value \
   (this_target_rtl->x_static_reg_base_value)
@@ -221,10 +221,10 @@ 
 /* Vector indexed by N giving the initial (unchanging) value known for
    pseudo-register N.  This array is initialized in init_alias_analysis,
    and does not change until end_alias_analysis is called.  */
-static GTY((length("reg_known_value_size"))) rtx *reg_known_value;
+static rtx *reg_known_value;
 
 /* Indicates number of valid entries in reg_known_value.  */
-static GTY(()) unsigned int reg_known_value_size;
+static unsigned int reg_known_value_size;
 
 /* Vector recording for each reg_known_value whether it is due to a
    REG_EQUIV note.  Future passes (viz., reload) may replace the
@@ -2742,7 +2742,7 @@ 
   timevar_push (TV_ALIAS_ANALYSIS);
 
   reg_known_value_size = maxreg - FIRST_PSEUDO_REGISTER;
-  reg_known_value = ggc_alloc_cleared_vec_rtx (reg_known_value_size);
+  reg_known_value = XCNEWVEC (rtx, reg_known_value_size);
   reg_known_equiv_p = XCNEWVEC (bool, reg_known_value_size);
 
   /* If we have memory allocated from the previous run, use it.  */
@@ -2752,7 +2752,7 @@ 
   if (reg_base_value)
     VEC_truncate (rtx, reg_base_value, 0);
 
-  VEC_safe_grow_cleared (rtx, gc, reg_base_value, maxreg);
+  VEC_safe_grow_cleared (rtx, heap, reg_base_value, maxreg);
 
   new_reg_base_value = XNEWVEC (rtx, maxreg);
   reg_seen = XNEWVEC (char, maxreg);
@@ -2903,7 +2903,7 @@ 
   /* Fill in the remaining entries.  */
   for (i = 0; i < (int)reg_known_value_size; i++)
     if (reg_known_value[i] == 0)
-      reg_known_value[i] = regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
+      reg_known_value[i] = crtl->emit.regno_reg_rtx[i + FIRST_PSEUDO_REGISTER];
 
   /* Clean up.  */
   free (new_reg_base_value);
@@ -2926,7 +2926,7 @@ 
 end_alias_analysis (void)
 {
   old_reg_base_value = reg_base_value;
-  ggc_free (reg_known_value);
+  free (reg_known_value);
   reg_known_value = 0;
   reg_known_value_size = 0;
   free (reg_known_equiv_p);
Index: gcc/ggc.h
===================================================================
--- gcc/ggc.h	(revision 169049)
+++ gcc/ggc.h	(working copy)
@@ -256,20 +256,12 @@ 
 
 /* Zone collection.  */
 
-/* For regular rtl allocations.  */
-extern struct alloc_zone rtl_zone;
-
 /* For regular tree allocations.  */
 extern struct alloc_zone tree_zone;
 
 /* For IDENTIFIER_NODE allocations.  */
 extern struct alloc_zone tree_id_zone;
 
-#define ggc_alloc_rtvec_sized(NELT)                                     \
-    (ggc_alloc_zone_vec_rtvec_def (sizeof (rtx),                        \
-                                   sizeof (struct rtvec_def) + ((NELT) - 1), \
-                                   &rtl_zone))
-
 #if defined (GGC_ZONE) && !defined (GENERATOR_FILE)
 
 /* Allocate an object into the specified allocation zone.  */
Index: gcc/lower-subreg.c
===================================================================
--- gcc/lower-subreg.c	(revision 169049)
+++ gcc/lower-subreg.c	(working copy)
@@ -366,9 +366,9 @@ 
   unsigned int words, i;
   rtvec v;
 
-  reg = regno_reg_rtx[regno];
+  reg = crtl->emit.regno_reg_rtx[regno];
 
-  regno_reg_rtx[regno] = NULL_RTX;
+  crtl->emit.regno_reg_rtx[regno] = NULL_RTX;
 
   words = GET_MODE_SIZE (GET_MODE (reg));
   words = (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
@@ -1090,8 +1090,8 @@ 
 
     for (i = FIRST_PSEUDO_REGISTER; i < max; ++i)
       {
-	if (regno_reg_rtx[i] != NULL
-	    && GET_MODE_SIZE (GET_MODE (regno_reg_rtx[i])) > UNITS_PER_WORD)
+	if (crtl->emit.regno_reg_rtx[i] != NULL
+	    && GET_MODE_SIZE (GET_MODE (crtl->emit.regno_reg_rtx[i])) > UNITS_PER_WORD)
 	  break;
       }
     if (i == max)
Index: gcc/bt-load.c
===================================================================
--- gcc/bt-load.c	(revision 169049)
+++ gcc/bt-load.c	(working copy)
@@ -567,7 +567,8 @@ 
 
 		      for (regno = first_btr; regno <= last_btr; regno++)
 			if (TEST_HARD_REG_BIT (*clobbered, regno))
-			  note_btr_set (regno_reg_rtx[regno], NULL_RTX, &info);
+			  note_btr_set (crtl->emit.regno_reg_rtx[regno],
+                                        NULL_RTX, &info);
 		    }
 		}
 	    }
Index: gcc/except.c
===================================================================
--- gcc/except.c	(revision 169049)
+++ gcc/except.c	(working copy)
@@ -163,7 +163,7 @@ 
 static int sjlj_fc_jbuf_ofs;
 
 
-struct GTY(()) call_site_record_d
+struct call_site_record_d
 {
   rtx landing_pad;
   int action;
@@ -190,7 +190,7 @@ 
 static int add_call_site (rtx, int, int);
 
 static void push_uleb128 (VEC (uchar, gc) **, unsigned int);
-static void push_sleb128 (VEC (uchar, gc) **, int);
+static void push_sleb128 (VEC (uchar, heap) **, int);
 #ifndef HAVE_AS_LEB128
 static int dw2_size_of_call_site_table (int);
 static int sjlj_size_of_call_site_table (void);
@@ -986,7 +986,7 @@ 
   int i, disp_index;
   eh_landing_pad lp;
 
-  crtl->eh.action_record_data = VEC_alloc (uchar, gc, 64);
+  crtl->eh.action_record_data = VEC_alloc (uchar, heap, 64);
   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
 
   disp_index = 0;
@@ -2338,11 +2338,11 @@ 
 {
   call_site_record record;
 
-  record = ggc_alloc_call_site_record_d ();
+  record = (call_site_record) allocate_in_rtl_mem (sizeof (*record));
   record->landing_pad = landing_pad;
   record->action = action;
 
-  VEC_safe_push (call_site_record, gc,
+  VEC_safe_push (call_site_record, heap,
 		 crtl->eh.call_site_record[section], record);
 
   return call_site_base + VEC_length (call_site_record,
@@ -2372,7 +2372,7 @@ 
   int min_labelno = 0, max_labelno = 0;
   int saved_call_site_base = call_site_base;
 
-  crtl->eh.action_record_data = VEC_alloc (uchar, gc, 64);
+  crtl->eh.action_record_data = VEC_alloc (uchar, heap, 64);
 
   ar_hash = htab_create (31, action_record_hash, action_record_eq, free);
 
@@ -2498,7 +2498,7 @@ 
 	cur_sec++;
 	gcc_assert (crtl->eh.call_site_record[cur_sec] == NULL);
 	crtl->eh.call_site_record[cur_sec]
-	  = VEC_alloc (call_site_record, gc, 10);
+	  = VEC_alloc (call_site_record, heap, 10);
 	max_labelno = max_label_num ();
 	min_labelno = get_first_label_num ();
 	pad_map = XCNEWVEC (rtx, max_labelno - min_labelno + 1);
@@ -2661,7 +2661,7 @@ 
 }
 
 static void
-push_sleb128 (VEC (uchar, gc) **data_area, int value)
+push_sleb128 (VEC (uchar, heap) **data_area, int value)
 {
   unsigned char byte;
   int more;
@@ -2674,7 +2674,7 @@ 
 		|| (value == -1 && (byte & 0x40) != 0));
       if (more)
 	byte |= 0x80;
-      VEC_safe_push (uchar, gc, *data_area, byte);
+      VEC_safe_push (uchar, heap, *data_area, byte);
     }
   while (more);
 }
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	(revision 169049)
+++ gcc/emit-rtl.c	(working copy)
@@ -79,13 +79,6 @@ 
 
 struct rtl_data x_rtl;
 
-/* Indexed by pseudo register number, gives the rtx for that pseudo.
-   Allocated in parallel with regno_pointer_align.
-   FIXME: We could put it into emit_status struct, but gengtype is not able to deal
-   with length attribute nested in top level structures.  */
-
-rtx * regno_reg_rtx;
-
 /* This is *not* reset after each function.  It gives each CODE_LABEL
    in the entire compilation a unique label number.  */
 
@@ -118,25 +111,19 @@ 
 
 /* A hash table storing CONST_INTs whose absolute value is greater
    than MAX_SAVED_CONST_INT.  */
+static htab_t const_int_htab;
 
-static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
-     htab_t const_int_htab;
-
 /* A hash table storing memory attribute structures.  */
-static GTY ((if_marked ("ggc_marked_p"), param_is (struct mem_attrs)))
-     htab_t mem_attrs_htab;
+static htab_t mem_attrs_htab;
 
 /* A hash table storing register attribute structures.  */
-static GTY ((if_marked ("ggc_marked_p"), param_is (struct reg_attrs)))
-     htab_t reg_attrs_htab;
+static htab_t reg_attrs_htab;
 
 /* A hash table storing all CONST_DOUBLEs.  */
-static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
-     htab_t const_double_htab;
+static htab_t const_double_htab;
 
 /* A hash table storing all CONST_FIXEDs.  */
-static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def)))
-     htab_t const_fixed_htab;
+static htab_t const_fixed_htab;
 
 #define cur_insn_uid (crtl->emit.x_cur_insn_uid)
 #define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid)
@@ -281,6 +268,9 @@ 
 		  && operand_equal_p (p->expr, q->expr, 0))));
 }
 
+/* TODO: maybe merge with function->debug_decls? */
+static GTY(()) VEC(tree, gc) *mem_attr_exprs;
+
 /* Allocate a new mem_attrs structure and insert it into the hash table if
    one identical to it is not already in the table.  We are doing this for
    MEM of mode MODE.  */
@@ -302,6 +292,7 @@ 
 	  ? align == GET_MODE_ALIGNMENT (mode) : align == BITS_PER_UNIT))
     return 0;
 
+  VEC_safe_push (tree, gc, mem_attr_exprs, expr);
   attrs.alias = alias;
   attrs.expr = expr;
   attrs.offset = offset;
@@ -312,7 +303,7 @@ 
   slot = htab_find_slot (mem_attrs_htab, &attrs, INSERT);
   if (*slot == 0)
     {
-      *slot = ggc_alloc_mem_attrs ();
+      *slot = XNEW (mem_attrs);
       memcpy (*slot, &attrs, sizeof (mem_attrs));
     }
 
@@ -361,7 +352,7 @@ 
   slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT);
   if (*slot == 0)
     {
-      *slot = ggc_alloc_reg_attrs ();
+      *slot = XNEW (reg_attrs);
       memcpy (*slot, &attrs, sizeof (reg_attrs));
     }
 
@@ -624,7 +615,7 @@ 
 
   if (cfun
       && cfun->emit
-      && regno_reg_rtx
+      && crtl->emit.regno_reg_rtx
       && regno < FIRST_PSEUDO_REGISTER
       && reg_raw_mode[regno] == mode)
     return regno_reg_rtx[regno];
@@ -903,15 +894,15 @@ 
       memset (tmp + old_size, 0, old_size);
       crtl->emit.regno_pointer_align = (unsigned char *) tmp;
 
-      new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, old_size * 2);
+      new1 = XRESIZEVEC (rtx, crtl->emit.regno_reg_rtx, old_size * 2);
       memset (new1 + old_size, 0, old_size * sizeof (rtx));
-      regno_reg_rtx = new1;
+      crtl->emit.regno_reg_rtx = new1;
 
       crtl->emit.regno_pointer_align_length = old_size * 2;
     }
 
   val = gen_raw_REG (mode, reg_rtx_no);
-  regno_reg_rtx[reg_rtx_no++] = val;
+  crtl->emit.regno_reg_rtx[reg_rtx_no++] = val;
   return val;
 }
 
@@ -5205,9 +5196,6 @@ 
     }
 }
 
-/* Space for free sequence stack entries.  */
-static GTY ((deletable)) struct sequence_stack *free_sequence_stack;
-
 /* Begin emitting insns to a sequence.  If this sequence will contain
    something that might cause the compiler to pop arguments to function
    calls (because those pops have previously been deferred; see
@@ -5220,13 +5208,13 @@ 
 {
   struct sequence_stack *tem;
 
-  if (free_sequence_stack != NULL)
+  if (crtl->emit.free_sequence_stack != NULL)
     {
-      tem = free_sequence_stack;
-      free_sequence_stack = tem->next;
+      tem = crtl->emit.free_sequence_stack;
+      crtl->emit.free_sequence_stack = tem->next;
     }
   else
-    tem = ggc_alloc_sequence_stack ();
+    tem = (struct sequence_stack *) allocate_in_rtl_mem (sizeof (*tem));
 
   tem->next = seq_stack;
   tem->first = get_insns ();
@@ -5324,8 +5312,8 @@ 
   seq_stack = tem->next;
 
   memset (tem, 0, sizeof (*tem));
-  tem->next = free_sequence_stack;
-  free_sequence_stack = tem;
+  tem->next = crtl->emit.free_sequence_stack;
+  crtl->emit.free_sequence_stack = tem;
 }
 
 /* Return 1 if currently emitting into a sequence.  */
@@ -5341,12 +5329,15 @@ 
 static void
 init_virtual_regs (void)
 {
-  regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
-  regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
-  regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
-  regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
-  regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
-  regno_reg_rtx[VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM]
+  crtl->emit.regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM]
+    = virtual_incoming_args_rtx;
+  crtl->emit.regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
+  crtl->emit.regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM]
+    = virtual_stack_dynamic_rtx;
+  crtl->emit.regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM]
+    = virtual_outgoing_args_rtx;
+  crtl->emit.regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
+  crtl->emit.regno_reg_rtx[VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM]
     = virtual_preferred_stack_boundary_rtx;
 }
 
@@ -5535,6 +5526,7 @@ 
   last_location = UNKNOWN_LOCATION;
   first_label_num = label_num;
   seq_stack = NULL;
+  crtl->emit.free_sequence_stack = NULL;
 
   /* Init the tables that describe all the pseudo regs.  */
 
@@ -5543,10 +5535,11 @@ 
   crtl->emit.regno_pointer_align
     = XCNEWVEC (unsigned char, crtl->emit.regno_pointer_align_length);
 
-  regno_reg_rtx = ggc_alloc_vec_rtx (crtl->emit.regno_pointer_align_length);
+  crtl->emit.regno_reg_rtx
+      = XNEWVEC (rtx, crtl->emit.regno_pointer_align_length);
 
   /* Put copies of all the hard registers into regno_reg_rtx.  */
-  memcpy (regno_reg_rtx,
+  memcpy (crtl->emit.regno_reg_rtx,
 	  initial_regno_reg_rtx,
 	  FIRST_PSEUDO_REGISTER * sizeof (rtx));
 
@@ -5700,19 +5693,19 @@ 
 
   /* Initialize the CONST_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute
      hash tables.  */
-  const_int_htab = htab_create_ggc (37, const_int_htab_hash,
-				    const_int_htab_eq, NULL);
+  const_int_htab = htab_create (37, const_int_htab_hash, const_int_htab_eq,
+                                NULL);
 
-  const_double_htab = htab_create_ggc (37, const_double_htab_hash,
-				       const_double_htab_eq, NULL);
+  const_double_htab = htab_create (37, const_double_htab_hash,
+                                   const_double_htab_eq, NULL);
 
-  const_fixed_htab = htab_create_ggc (37, const_fixed_htab_hash,
-				      const_fixed_htab_eq, NULL);
+  const_fixed_htab = htab_create (37, const_fixed_htab_hash,
+                                  const_fixed_htab_eq, NULL);
 
-  mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash,
-				    mem_attrs_htab_eq, NULL);
-  reg_attrs_htab = htab_create_ggc (37, reg_attrs_htab_hash,
-				    reg_attrs_htab_eq, NULL);
+  mem_attrs_htab = htab_create (37, mem_attrs_htab_hash, mem_attrs_htab_eq,
+                                NULL);
+  reg_attrs_htab = htab_create (37, reg_attrs_htab_hash, reg_attrs_htab_eq,
+                                NULL);
 
   /* Compute the word and byte modes.  */
 
@@ -6010,7 +6003,7 @@ 
   return new_rtx;
 }
 
-static GTY((deletable)) rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
+static rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
 rtx
 gen_hard_reg_clobber (enum machine_mode mode, unsigned int regno)
 {
Index: gcc/except.h
===================================================================
--- gcc/except.h	(revision 169049)
+++ gcc/except.h	(working copy)
@@ -90,7 +90,7 @@ 
      EXCEPTION_RECEIVER pattern will be expanded here, as well as other
      bookkeeping specific to exceptions.  There must not be normal edges
      into the block containing the landing-pad label.  */
-  rtx landing_pad;
+  rtx GTY((skip)) landing_pad;
 
   /* The index of this landing pad within fun->eh->lp_array.  */
   int index;
@@ -178,7 +178,8 @@ 
   /* EXC_PTR and FILTER values copied from the runtime for this region.
      Each region gets its own psuedos so that if there are nested exceptions
      we do not overwrite the values of the first exception.  */
-  rtx exc_ptr_reg, filter_reg;
+  rtx GTY((skip)) exc_ptr_reg;
+  rtx GTY((skip)) filter_reg;
 
   /* True if this region should use __cxa_end_cleanup instead
      of _Unwind_Resume.  */
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c	(revision 169049)
+++ gcc/cfgexpand.c	(working copy)
@@ -3257,6 +3257,7 @@ 
 	  val = NULL_RTX;
 	else
 	  {
+	    VEC_safe_push (tree, gc, cfun->debug_decls, value);
 	    val = expand_debug_expr (value);
 	    gcc_assert (last == get_last_insn ());
 	  }
@@ -3506,6 +3507,7 @@ 
 	      else
 		mode = TYPE_MODE (TREE_TYPE (var));
 
+	      VEC_safe_push (tree, gc, cfun->debug_decls, value);
 	      val = gen_rtx_VAR_LOCATION
 		(mode, var, (rtx)value, VAR_INIT_STATUS_INITIALIZED);
 
Index: gcc/cselib.c
===================================================================
--- gcc/cselib.c	(revision 169049)
+++ gcc/cselib.c	(working copy)
@@ -35,7 +35,6 @@ 
 #include "emit-rtl.h"
 #include "diagnostic-core.h"
 #include "output.h"
-#include "ggc.h"
 #include "hashtab.h"
 #include "tree-pass.h"
 #include "cselib.h"
@@ -170,7 +169,7 @@ 
 
 /* We pass this to cselib_invalidate_mem to invalidate all of
    memory for a non-const call instruction.  */
-static GTY(()) rtx callmem;
+static rtx callmem;
 
 /* Set by discard_useless_locs if it deleted the last location of any
    value.  */
@@ -2390,5 +2389,3 @@ 
     }
   fprintf (out, "next uid %i\n", next_uid);
 }
-
-#include "gt-cselib.h"
Index: gcc/explow.c
===================================================================
--- gcc/explow.c	(revision 169049)
+++ gcc/explow.c	(working copy)
@@ -36,7 +36,6 @@ 
 #include "libfuncs.h"
 #include "hard-reg-set.h"
 #include "insn-config.h"
-#include "ggc.h"
 #include "recog.h"
 #include "langhooks.h"
 #include "target.h"
@@ -1519,7 +1518,7 @@ 
    run-time routine to call to check the stack, so provide a mechanism for
    calling that routine.  */
 
-static GTY(()) rtx stack_check_libfunc;
+static rtx stack_check_libfunc;
 
 void
 set_stack_check_libfunc (const char *libfunc_name)
@@ -1933,5 +1932,3 @@ 
     }
   return ((int) tcode);
 }
-
-#include "gt-explow.h"
Index: gcc/cfglayout.h
===================================================================
--- gcc/cfglayout.h	(revision 169049)
+++ gcc/cfglayout.h	(working copy)
@@ -22,8 +22,8 @@ 
 
 #include "basic-block.h"
 
-extern GTY(()) rtx cfg_layout_function_footer;
-extern GTY(()) rtx cfg_layout_function_header;
+extern rtx cfg_layout_function_footer;
+extern rtx cfg_layout_function_header;
 
 extern void cfg_layout_initialize (unsigned int);
 extern void cfg_layout_finalize (void);
Index: gcc/ggc-zone.c
===================================================================
--- gcc/ggc-zone.c	(revision 169049)
+++ gcc/ggc-zone.c	(working copy)
@@ -428,7 +428,6 @@ 
 } main_zone;
 
 /* Some default zones.  */
-struct alloc_zone rtl_zone;
 struct alloc_zone tree_zone;
 struct alloc_zone tree_id_zone;
 
@@ -1364,12 +1363,6 @@ 
     case gt_ggc_e_14lang_tree_node:
       return ggc_internal_alloc_zone_pass_stat (size, &tree_zone);
 
-    case gt_ggc_e_7rtx_def:
-      return ggc_internal_alloc_zone_pass_stat (size, &rtl_zone);
-
-    case gt_ggc_e_9rtvec_def:
-      return ggc_internal_alloc_zone_pass_stat (size, &rtl_zone);
-
     default:
       return ggc_internal_alloc_zone_pass_stat (size, &main_zone);
     }
@@ -1637,7 +1630,6 @@ 
   G.zones = &main_zone;
 
   /* Allocate the default zones.  */
-  new_ggc_zone_1 (&rtl_zone, "RTL zone");
   new_ggc_zone_1 (&tree_zone, "Tree zone");
   new_ggc_zone_1 (&tree_id_zone, "Tree identifier zone");
 
Index: gcc/ggc-page.c
===================================================================
--- gcc/ggc-page.c	(revision 169049)
+++ gcc/ggc-page.c	(working copy)
@@ -2361,6 +2361,5 @@ 
   int dummy;
 };
 
-struct alloc_zone rtl_zone;
 struct alloc_zone tree_zone;
 struct alloc_zone tree_id_zone;
Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 169049)
+++ gcc/varasm.c	(working copy)
@@ -182,13 +182,13 @@ 
 static GTY((param_is (section))) htab_t section_htab;
 
 /* A table of object_blocks, indexed by section.  */
-static GTY((param_is (struct object_block))) htab_t object_block_htab;
+static htab_t object_block_htab;
 
 /* The next number to use for internal anchor labels.  */
 static GTY(()) int anchor_labelno;
 
 /* A pool of constants that can be shared between functions.  */
-static GTY(()) struct rtx_constant_pool *shared_constant_pool;
+static struct rtx_constant_pool *shared_constant_pool;
 
 /* Helper routines for maintaining section_htab.  */
 
@@ -331,7 +331,7 @@ 
   block = (struct object_block *) *slot;
   if (block == NULL)
     {
-      block = ggc_alloc_cleared_object_block ();
+      block = XCNEW (struct object_block);
       block->sect = sect;
       *slot = block;
     }
@@ -351,7 +351,7 @@ 
 
   /* Create the extended SYMBOL_REF.  */
   size = RTX_HDR_SIZE + sizeof (struct block_symbol);
-  symbol = ggc_alloc_zone_rtx_def (size, &rtl_zone);
+  symbol = (rtx) allocate_in_rtl_mem (size);
 
   /* Initialize the normal SYMBOL_REF fields.  */
   memset (symbol, 0, size);
@@ -1527,13 +1527,17 @@ 
   if (flag_reorder_blocks_and_partition)
     {
       ASM_GENERATE_INTERNAL_LABEL (tmp_label, "LHOTB", const_labelno);
-      crtl->subsections.hot_section_label = ggc_strdup (tmp_label);
+      crtl->subsections.hot_section_label
+        = strdup_to_permanent_mem (tmp_label);
       ASM_GENERATE_INTERNAL_LABEL (tmp_label, "LCOLDB", const_labelno);
-      crtl->subsections.cold_section_label = ggc_strdup (tmp_label);
+      crtl->subsections.cold_section_label
+        = strdup_to_permanent_mem (tmp_label);
       ASM_GENERATE_INTERNAL_LABEL (tmp_label, "LHOTE", const_labelno);
-      crtl->subsections.hot_section_end_label = ggc_strdup (tmp_label);
+      crtl->subsections.hot_section_end_label
+        = strdup_to_permanent_mem(tmp_label);
       ASM_GENERATE_INTERNAL_LABEL (tmp_label, "LCOLDE", const_labelno);
-      crtl->subsections.cold_section_end_label = ggc_strdup (tmp_label);
+      crtl->subsections.cold_section_end_label
+        = strdup_to_permanent_mem (tmp_label);
       const_labelno++;
     }
   else
@@ -2297,7 +2301,7 @@ 
 
   ASM_GENERATE_INTERNAL_LABEL (name, "LF", const_labelno);
   ++const_labelno;
-  namestring = ggc_strdup (name);
+  namestring = strdup_to_permanent_mem (name);
 
   x = gen_rtx_SYMBOL_REF (Pmode, namestring);
   SYMBOL_REF_FLAGS (x) = SYMBOL_FLAG_LOCAL;
@@ -2328,7 +2332,7 @@ 
    This is done at most once per compilation.
    Returns an RTX for the address of the template.  */
 
-static GTY(()) rtx initial_trampoline;
+static rtx initial_trampoline;
 
 rtx
 assemble_trampoline_template (void)
@@ -2361,7 +2365,7 @@ 
 
   /* Record the rtl to refer to it.  */
   ASM_GENERATE_INTERNAL_LABEL (label, "LTRAMP", 0);
-  name = ggc_strdup (label);
+  name = strdup_to_permanent_mem (label);
   symbol = gen_rtx_SYMBOL_REF (Pmode, name);
   SYMBOL_REF_FLAGS (symbol) = SYMBOL_FLAG_LOCAL;
 
@@ -3024,6 +3028,10 @@ 
   return size;
 }
 
+/* The VAR_DECLs associated with constants */
+/* TODO: can store it somewhere else? */
+static GTY(()) VEC(tree,gc) *saved_constant_decls;
+
 /* Subroutine of output_constant_def:
    No constant equal to EXP is known to have been output.
    Make a constant descriptor to enter EXP in the hash table.
@@ -3074,16 +3082,17 @@ 
     }
   else
     align_variable (decl, 0);
+  VEC_safe_push (tree, gc, saved_constant_decls, decl);
 
   /* Now construct the SYMBOL_REF and the MEM.  */
   if (use_object_blocks_p ())
     {
       section *sect = get_constant_section (exp, DECL_ALIGN (decl));
-      symbol = create_block_symbol (ggc_strdup (label),
+      symbol = create_block_symbol (strdup_to_permanent_mem (label),
 				    get_block_for_section (sect), -1);
     }
   else
-    symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
+    symbol = gen_rtx_SYMBOL_REF (Pmode, strdup_to_permanent_mem (label));
   SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL;
   SET_SYMBOL_REF_DECL (symbol, decl);
   TREE_CONSTANT_POOL_ADDRESS_P (symbol) = 1;
@@ -3286,7 +3295,7 @@ 
    can use one per-file pool.  Should add a targetm bit to tell the
    difference.  */
 
-struct GTY(()) rtx_constant_pool {
+struct rtx_constant_pool {
   /* Pointers to first and last constant in pool, as ordered by offset.  */
   struct constant_descriptor_rtx *first;
   struct constant_descriptor_rtx *last;
@@ -3295,14 +3304,14 @@ 
      It is used on RISC machines where immediate integer arguments and
      constant addresses are restricted so that such constants must be stored
      in memory.  */
-  htab_t GTY((param_is (struct constant_descriptor_rtx))) const_rtx_htab;
+  htab_t const_rtx_htab;
 
   /* Current offset in constant pool (does not include any
      machine-specific header).  */
   HOST_WIDE_INT offset;
 };
 
-struct GTY((chain_next ("%h.next"))) constant_descriptor_rtx {
+struct constant_descriptor_rtx {
   struct constant_descriptor_rtx *next;
   rtx mem;
   rtx sym;
@@ -3435,9 +3444,9 @@ 
 {
   struct rtx_constant_pool *pool;
 
-  pool = ggc_alloc_rtx_constant_pool ();
-  pool->const_rtx_htab = htab_create_ggc (31, const_desc_rtx_hash,
-					  const_desc_rtx_eq, NULL);
+  pool = XNEW (struct rtx_constant_pool);
+  pool->const_rtx_htab = htab_create (31, const_desc_rtx_hash,
+                                      const_desc_rtx_eq, NULL);
   pool->first = NULL;
   pool->last = NULL;
   pool->offset = 0;
@@ -3501,7 +3510,7 @@ 
     return copy_rtx (desc->mem);
 
   /* Otherwise, create a new descriptor.  */
-  desc = ggc_alloc_constant_descriptor_rtx ();
+  desc = XNEW (struct constant_descriptor_rtx);
   *slot = desc;
 
   /* Align the location counter as required by EXP's data type.  */
@@ -3542,11 +3551,11 @@ 
   if (use_object_blocks_p () && targetm.use_blocks_for_constant_p (mode, x))
     {
       section *sect = targetm.asm_out.select_rtx_section (mode, x, align);
-      symbol = create_block_symbol (ggc_strdup (label),
+      symbol = create_block_symbol (strdup_to_permanent_mem (label),
 				    get_block_for_section (sect), -1);
     }
   else
-    symbol = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (label));
+    symbol = gen_rtx_SYMBOL_REF (Pmode, strdup_to_permanent_mem (label));
   desc->sym = symbol;
   SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LOCAL;
   CONSTANT_POOL_ADDRESS_P (symbol) = 1;
@@ -5922,8 +5931,8 @@ 
 {
   section_htab = htab_create_ggc (31, section_entry_hash,
 				  section_entry_eq, NULL);
-  object_block_htab = htab_create_ggc (31, object_block_entry_hash,
-				       object_block_entry_eq, NULL);
+  object_block_htab = htab_create (31, object_block_entry_hash,
+                                   object_block_entry_eq, NULL);
   const_desc_htab = htab_create_ggc (1009, const_desc_hash,
 				     const_desc_eq, NULL);
 
@@ -7026,7 +7035,7 @@ 
   block->alignment = MAX (block->alignment, alignment);
   block->size = offset + size;
 
-  VEC_safe_push (rtx, gc, block->objects, symbol);
+  VEC_safe_push (rtx, heap, block->objects, symbol);
 }
 
 /* Return the anchor that should be used to address byte offset OFFSET
@@ -7104,12 +7113,13 @@ 
 
   /* Create a new anchor with a unique label.  */
   ASM_GENERATE_INTERNAL_LABEL (label, "LANCHOR", anchor_labelno++);
-  anchor = create_block_symbol (ggc_strdup (label), block, offset);
+  anchor = create_block_symbol (strdup_to_permanent_mem (label), block,
+                                offset);
   SYMBOL_REF_FLAGS (anchor) |= SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_ANCHOR;
   SYMBOL_REF_FLAGS (anchor) |= model << SYMBOL_FLAG_TLS_SHIFT;
 
   /* Insert it at index BEGIN.  */
-  VEC_safe_insert (rtx, gc, block->anchors, begin, anchor);
+  VEC_safe_insert (rtx, heap, block->anchors, begin, anchor);
   return anchor;
 }
 
@@ -7303,6 +7313,7 @@ 
   enum machine_mode mode = GET_MODE (exp);
   rtx dval;
 
+  VEC_safe_push (tree, gc, cfun->debug_decls, ddecl);
   DECL_ARTIFICIAL (ddecl) = 1;
   if (REG_P (exp) && REG_EXPR (exp))
     type = TREE_TYPE (REG_EXPR (exp));
Index: gcc/ira.c
===================================================================
--- gcc/ira.c	(revision 169049)
+++ gcc/ira.c	(working copy)
@@ -1691,7 +1691,7 @@ 
 
   if (reg_equiv_init_size < max_regno)
     {
-      reg_equiv_init = GGC_RESIZEVEC (rtx, reg_equiv_init, max_regno);
+      reg_equiv_init = XRESIZEVEC (rtx, reg_equiv_init, max_regno);
       while (reg_equiv_init_size < max_regno)
 	reg_equiv_init[reg_equiv_init_size++] = NULL_RTX;
       for (i = FIRST_PSEUDO_REGISTER; i < reg_equiv_init_size; i++)
@@ -1772,7 +1772,7 @@ 
 
   for (i = start; i < max_regno; i++)
     {
-      old_regno = ORIGINAL_REGNO (regno_reg_rtx[i]);
+      old_regno = ORIGINAL_REGNO (crtl->emit.regno_reg_rtx[i]);
       ira_assert (i != old_regno);
       setup_reg_classes (i, reg_preferred_class (old_regno),
 			 reg_alternate_class (old_regno),
@@ -2274,7 +2274,7 @@ 
   recorded_label_ref = 0;
 
   reg_equiv = XCNEWVEC (struct equivalence, max_regno);
-  reg_equiv_init = ggc_alloc_cleared_vec_rtx (max_regno);
+  reg_equiv_init = XCNEWVEC (rtx, max_regno);
   reg_equiv_init_size = max_regno;
 
   init_alias_analysis ();
@@ -2610,7 +2610,7 @@ 
 		    continue;
 
 		  if (asm_noperands (PATTERN (equiv_insn)) < 0
-		      && validate_replace_rtx (regno_reg_rtx[regno],
+		      && validate_replace_rtx (crtl->emit.regno_reg_rtx[regno],
 					       *(reg_equiv[regno].src_p), insn))
 		    {
 		      rtx equiv_link;
@@ -2761,7 +2761,7 @@ 
 		   int *live_subregs_used, int allocnum, rtx reg)
 {
   unsigned int regno = REGNO (SUBREG_REG (reg));
-  int size = GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno]));
+  int size = GET_MODE_SIZE (GET_MODE (crtl->emit.regno_reg_rtx[regno]));
 
   gcc_assert (size > 0);
 
@@ -3066,7 +3066,7 @@ 
   max_regno = max_reg_num ();
 
   /* And the reg_equiv_memory_loc array.  */
-  VEC_safe_grow (rtx, gc, reg_equiv_memory_loc_vec, max_regno);
+  VEC_safe_grow (rtx, heap, reg_equiv_memory_loc_vec, max_regno);
   memset (VEC_address (rtx, reg_equiv_memory_loc_vec), 0,
 	  sizeof (rtx) * max_regno);
   reg_equiv_memory_loc = VEC_address (rtx, reg_equiv_memory_loc_vec);
Index: gcc/rtl.c
===================================================================
--- gcc/rtl.c	(revision 169049)
+++ gcc/rtl.c	(working copy)
@@ -32,6 +32,7 @@ 
 #include "tm.h"
 #include "rtl.h"
 #include "ggc.h"
+#include "obstack.h"
 #ifdef GENERATOR_FILE
 # include "errors.h"
 #else
@@ -142,6 +143,51 @@ 
 #endif
 
 
+
+static struct obstack function_obstack;
+static struct obstack permanent_obstack;
+struct obstack *rtl_obstack = &function_obstack;
+
+/* Prepares for allocation of RTXes.  */
+void
+init_rtl (void)
+{
+  gcc_obstack_init (&function_obstack);
+  gcc_obstack_init (&permanent_obstack);
+}
+
+/* Allocates memory from the RTL heap with the current lifetime.  */
+void *
+allocate_in_rtl_mem (int size)
+{
+  return obstack_alloc (rtl_obstack, size);
+}
+
+void *
+allocate_in_rtl_function_mem (int size)
+{
+  return obstack_alloc (&function_obstack, size);
+}
+
+rtx
+copy_rtx_to_permanent_mem (rtx x)
+{
+  rtx copy;
+  rtl_obstack = &permanent_obstack;
+  copy = copy_rtx (x);
+  rtl_obstack = &function_obstack;
+  return copy;
+}
+
+char *
+strdup_to_permanent_mem (const char *s)
+{
+  size_t len = strlen (s) + 1;
+  char *result = XOBNEWVAR (&permanent_obstack, char, len);
+  memcpy (result, s, len);
+  return result;
+}
+
 /* Allocate an rtx vector of N elements.
    Store the length, and initialize all elements to zero.  */
 
@@ -150,7 +196,9 @@ 
 {
   rtvec rt;
 
-  rt = ggc_alloc_rtvec_sized (n);
+  rt = (rtvec) obstack_alloc (rtl_obstack,
+                              sizeof (struct rtvec_def)
+                              + ((n - 1) * sizeof (rtunion)));
   /* Clear out the vector.  */
   memset (&rt->elem[0], 0, n * sizeof (rtx));
 
@@ -194,8 +242,11 @@ 
 rtx
 rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL)
 {
-  rtx rt = ggc_alloc_zone_rtx_def_stat (&rtl_zone, RTX_CODE_SIZE (code)
-                                        PASS_MEM_STAT);
+  int length = RTX_CODE_SIZE (code);
+  rtx rt;
+  length = (length + rtl_obstack->alignment_mask)
+    & ~rtl_obstack->alignment_mask;
+  rt = (rtx) obstack_alloc (rtl_obstack, length);
 
   /* We want to clear everything up to the FLD array.  Normally, this
      is one int, but we don't want to assume that and it isn't very
@@ -337,7 +388,7 @@ 
 shallow_copy_rtx_stat (const_rtx orig MEM_STAT_DECL)
 {
   const unsigned int size = rtx_size (orig);
-  rtx const copy = ggc_alloc_zone_rtx_def_stat (&rtl_zone, size PASS_MEM_STAT);
+  rtx const copy = rtx_alloc (GET_CODE(orig));
   return (rtx) memcpy (copy, orig, size);
 }
 
Index: gcc/ira-costs.c
===================================================================
--- gcc/ira-costs.c	(revision 169049)
+++ gcc/ira-costs.c	(working copy)
@@ -1119,7 +1119,7 @@ 
   fprintf (f, "\n");
   for (regno = max_reg_num () - 1; regno >= FIRST_PSEUDO_REGISTER; regno--)
     {
-      if (regno_reg_rtx[regno] == NULL_RTX)
+      if (crtl->emit.regno_reg_rtx[regno] == NULL_RTX)
 	continue;
       fprintf (f, "  r%d costs:", regno);
       for (k = 0; k < cost_classes_num; k++)
@@ -1265,7 +1265,7 @@ 
 
 	  if (! allocno_p)
 	    {
-	      if (regno_reg_rtx[i] == NULL_RTX)
+	      if (crtl->emit.regno_reg_rtx[i] == NULL_RTX)
 		continue;
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 	      inc_dec_p = in_inc_dec[i];
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h	(revision 169049)
+++ gcc/rtl.h	(working copy)
@@ -144,8 +144,8 @@ 
 typedef struct GTY(()) mem_attrs
 {
   tree expr;			/* expr corresponding to MEM.  */
-  rtx offset;			/* Offset from start of DECL, as CONST_INT.  */
-  rtx size;			/* Size in bytes, as a CONST_INT.  */
+  rtx GTY((skip)) offset;	/* Offset from start of DECL, as CONST_INT.  */
+  rtx GTY((skip)) size;		/* Size in bytes, as a CONST_INT.  */
   alias_set_type alias;		/* Memory alias set.  */
   unsigned int align;		/* Alignment of MEM in bits.  */
   unsigned char addrspace;	/* Address space (0 for generic).  */
@@ -200,7 +200,7 @@ 
 
 /* Describes a group of objects that are to be placed together in such
    a way that their relative positions are known.  */
-struct GTY(()) object_block {
+struct object_block {
   /* The section in which these objects should be placed.  */
   section *sect;
 
@@ -218,7 +218,7 @@ 
 	 !SYMBOL_REF_ANCHOR_P (X)
 	 SYMBOL_REF_BLOCK (X) == [address of this structure]
 	 SYMBOL_REF_BLOCK_OFFSET (X) >= 0.  */
-  VEC(rtx,gc) *objects;
+  VEC(rtx,heap) *objects;
 
   /* All the anchor SYMBOL_REFs used to address these objects, sorted
      in order of increasing offset, and then increasing TLS model.
@@ -228,13 +228,12 @@ 
 	 SYMBOL_REF_ANCHOR_P (X)
 	 SYMBOL_REF_BLOCK (X) == [address of this structure]
 	 SYMBOL_REF_BLOCK_OFFSET (X) >= 0.  */
-  VEC(rtx,gc) *anchors;
+  VEC(rtx,heap) *anchors;
 };
 
 /* RTL expression ("rtx").  */
 
-struct GTY((chain_next ("RTX_NEXT (&%h)"),
-	    chain_prev ("RTX_PREV (&%h)"), variable_size)) rtx_def {
+struct rtx_def {
   /* The kind of expression this is.  */
   ENUM_BITFIELD(rtx_code) code: 16;
 
@@ -315,7 +314,7 @@ 
     struct block_symbol block_sym;
     struct real_value rv;
     struct fixed_value fv;
-  } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u;
+  } u;
 };
 
 /* The size in bytes of an rtx header (code, mode and flags).  */
@@ -353,9 +352,9 @@ 
    for a variable number of things.  The principle use is inside
    PARALLEL expressions.  */
 
-struct GTY((variable_size)) rtvec_def {
+struct rtvec_def {
   int num_elem;		/* number of elements */
-  rtx GTY ((length ("%h.num_elem"))) elem[1];
+  rtx elem[1];
 };
 
 #define NULL_RTVEC (rtvec) 0
@@ -1596,6 +1595,9 @@ 
 /* Nonzero when we are expanding trees to RTL.  */
 extern int currently_expanding_to_rtl;
 
+/* Obstack definition for generators only.  */
+extern struct obstack * rtl_obstack;
+
 /* Generally useful functions.  */
 
 /* In expmed.c */
@@ -1606,6 +1608,12 @@ 
 extern rtx plus_constant (rtx, HOST_WIDE_INT);
 
 /* In rtl.c */
+extern void init_rtl (void);
+extern void * allocate_in_rtl_mem (int);
+extern void * allocate_in_rtl_function_mem (int);
+extern rtx copy_rtx_to_permanent_mem (rtx);
+extern char * strdup_to_permanent_mem (const char *);
+
 extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
 #define rtx_alloc(c) rtx_alloc_stat (c MEM_STAT_INFO)
 
@@ -2001,15 +2009,15 @@ 
 extern unsigned int split_all_insns_noflow (void);
 
 #define MAX_SAVED_CONST_INT 64
-extern GTY(()) rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
+extern rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
 
 #define const0_rtx	(const_int_rtx[MAX_SAVED_CONST_INT])
 #define const1_rtx	(const_int_rtx[MAX_SAVED_CONST_INT+1])
 #define const2_rtx	(const_int_rtx[MAX_SAVED_CONST_INT+2])
 #define constm1_rtx	(const_int_rtx[MAX_SAVED_CONST_INT-1])
-extern GTY(()) rtx const_true_rtx;
+extern rtx const_true_rtx;
 
-extern GTY(()) rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
+extern rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
 
 /* Returns a constant 0 rtx in mode MODE.  Integer modes are treated the
    same as VOIDmode.  */
@@ -2077,7 +2085,7 @@ 
 };
 
 /* Target-dependent globals.  */
-struct GTY(()) target_rtl {
+struct target_rtl {
   /* All references to the hard registers in global_rtl_index go through
      these unique rtl objects.  On machines where the frame-pointer and
      arg-pointer are the same register, they use the same unique object.
@@ -2117,7 +2125,7 @@ 
   rtx x_static_reg_base_value[FIRST_PSEUDO_REGISTER];
 };
 
-extern GTY(()) struct target_rtl default_target_rtl;
+extern struct target_rtl default_target_rtl;
 #if SWITCHABLE_TARGET
 extern struct target_rtl *this_target_rtl;
 #else
@@ -2513,7 +2521,7 @@ 
 #endif
 
 /* In toplev.c */
-extern GTY(()) rtx stack_limit_rtx;
+extern rtx stack_limit_rtx;
 
 /* In predict.c */
 extern void invert_br_probabilities (rtx);
Index: gcc/integrate.c
===================================================================
--- gcc/integrate.c	(revision 169049)
+++ gcc/integrate.c	(working copy)
@@ -41,7 +41,6 @@ 
 #include "diagnostic-core.h"
 #include "intl.h"
 #include "params.h"
-#include "ggc.h"
 #include "target.h"
 #include "langhooks.h"
 #include "tree-pass.h"
@@ -52,14 +51,14 @@ 
 
 
 /* Private type used by {get/has}_hard_reg_initial_val.  */
-typedef struct GTY(()) initial_value_pair {
+typedef struct initial_value_pair {
   rtx hard_reg;
   rtx pseudo;
 } initial_value_pair;
-typedef struct GTY(()) initial_value_struct {
+typedef struct initial_value_struct {
   int num_entries;
   int max_entries;
-  initial_value_pair * GTY ((length ("%h.num_entries"))) entries;
+  initial_value_pair * entries;
 } initial_value_struct;
 
 static void set_block_origin_self (tree);
@@ -246,18 +245,23 @@ 
   ivs = crtl->hard_reg_initial_vals;
   if (ivs == 0)
     {
-      ivs = ggc_alloc_initial_value_struct ();
+      ivs = (struct initial_value_struct *)
+	allocate_in_rtl_mem (sizeof (struct initial_value_struct));
       ivs->num_entries = 0;
       ivs->max_entries = 5;
-      ivs->entries = ggc_alloc_vec_initial_value_pair (5);
+      ivs->entries = (struct initial_value_pair *)
+	allocate_in_rtl_mem (5 * sizeof (struct initial_value_pair));
       crtl->hard_reg_initial_vals = ivs;
     }
 
   if (ivs->num_entries >= ivs->max_entries)
     {
+      struct initial_value_pair *newvec = (struct initial_value_pair *)
+	allocate_in_rtl_mem (ivs->max_entries
+			     * sizeof (struct initial_value_pair));
+      memcpy (newvec, ivs->entries,
+	      sizeof (struct initial_value_pair) * ivs->max_entries);
       ivs->max_entries += 5;
-      ivs->entries = GGC_RESIZEVEC (initial_value_pair, ivs->entries,
-				    ivs->max_entries);
     }
 
   ivs->entries[ivs->num_entries].hard_reg = gen_rtx_REG (mode, regno);
@@ -371,5 +375,3 @@ 
 	}
     }
 }
-
-#include "gt-integrate.h"
Index: gcc/combine.c
===================================================================
--- gcc/combine.c	(revision 169049)
+++ gcc/combine.c	(working copy)
@@ -3037,8 +3037,8 @@ 
 		new_dest = gen_rtx_REG (compare_mode, regno);
 	      else
 		{
-		  SUBST_MODE (regno_reg_rtx[regno], compare_mode);
-		  new_dest = regno_reg_rtx[regno];
+		  SUBST_MODE (crtl->emit.regno_reg_rtx[regno], compare_mode);
+		  new_dest = crtl->emit.regno_reg_rtx[regno];
 		}
 
 	      SUBST (SET_DEST (newpat), new_dest);
@@ -3371,8 +3371,9 @@ 
 		ni2dest = gen_rtx_REG (new_mode, REGNO (i2dest));
 	      else
 		{
-		  SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], new_mode);
-		  ni2dest = regno_reg_rtx[REGNO (i2dest)];
+		  SUBST_MODE (crtl->emit.regno_reg_rtx[REGNO (i2dest)],
+			      new_mode);
+		  ni2dest = crtl->emit.regno_reg_rtx[REGNO (i2dest)];
 		}
 
 	      parallel = (gen_rtx_PARALLEL
@@ -3387,7 +3388,8 @@ 
 		{
 		  struct undo *buf;
 
-		  adjust_reg_mode (regno_reg_rtx[REGNO (i2dest)], old_mode);
+		  adjust_reg_mode (crtl->emit.regno_reg_rtx[REGNO (i2dest)],
+				   old_mode);
 		  buf = undobuf.undos;
 		  undobuf.undos = buf->next;
 		  buf->next = undobuf.frees;
@@ -3509,8 +3511,9 @@ 
 		newdest = gen_rtx_REG (split_mode, REGNO (i2dest));
 	      else
 		{
-		  SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], split_mode);
-		  newdest = regno_reg_rtx[REGNO (i2dest)];
+		  SUBST_MODE (crtl->emit.regno_reg_rtx[REGNO (i2dest)],
+			      split_mode);
+		  newdest = crtl->emit.regno_reg_rtx[REGNO (i2dest)];
 		}
 	    }
 
@@ -4505,7 +4508,7 @@ 
 	  && ! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
 					    MEM_ADDR_SPACE (x)))
 	{
-	  rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER];
+	  rtx reg = crtl->emit.regno_reg_rtx[FIRST_PSEUDO_REGISTER];
 	  rtx seq = combine_split_insns (gen_rtx_SET (VOIDmode, reg,
 						      XEXP (x, 0)),
 					 subst_insn);
@@ -6301,8 +6304,8 @@ 
 		new_dest = gen_rtx_REG (compare_mode, regno);
 	      else
 		{
-		  SUBST_MODE (regno_reg_rtx[regno], compare_mode);
-		  new_dest = regno_reg_rtx[regno];
+		  SUBST_MODE (crtl->emit.regno_reg_rtx[regno], compare_mode);
+		  new_dest = crtl->emit.regno_reg_rtx[regno];
 		}
 
 	      SUBST (SET_DEST (x), new_dest);
@@ -12964,7 +12967,8 @@ 
 
 	      for (i = deadregno; i < deadend; i++)
 		if (i < regno || i >= ourend)
-		  add_reg_note (where_dead, REG_DEAD, regno_reg_rtx[i]);
+		  add_reg_note (where_dead, REG_DEAD,
+				crtl->emit.regno_reg_rtx[i]);
 	    }
 
 	  /* If we didn't find any note, or if we found a REG_DEAD note that
@@ -12989,7 +12993,7 @@ 
 		offset = 1;
 
 	      for (i = regno + offset; i < ourend; i++)
-		move_deaths (regno_reg_rtx[i],
+		move_deaths (crtl->emit.regno_reg_rtx[i],
 			     maybe_kill_insn, from_luid, to_insn, &oldnotes);
 	    }
 
@@ -13562,7 +13566,7 @@ 
 		      for (i = regno; i < endregno;
 			   i += hard_regno_nregs[i][reg_raw_mode[i]])
 			{
-			  rtx piece = regno_reg_rtx[i];
+			  rtx piece = crtl->emit.regno_reg_rtx[i];
 			  basic_block bb = this_basic_block;
 
 			  if (! dead_or_set_p (place, piece)
Index: gcc/ggc-none.c
===================================================================
--- gcc/ggc-none.c	(revision 169049)
+++ gcc/ggc-none.c	(working copy)
@@ -68,7 +68,6 @@ 
   int dummy;
 };
 
-struct alloc_zone rtl_zone;
 struct alloc_zone tree_zone;
 struct alloc_zone tree_id_zone;
 
Index: gcc/df-problems.c
===================================================================
--- gcc/df-problems.c	(revision 169049)
+++ gcc/df-problems.c	(working copy)
@@ -2900,7 +2900,7 @@ 
 	if (!bitmap_bit_p (live, r)
 	    && !bitmap_bit_p (artificial_uses, r))
 	  {
-	    df_set_note (REG_UNUSED, insn, regno_reg_rtx[r]);
+	    df_set_note (REG_UNUSED, insn, crtl->emit.regno_reg_rtx[r]);
 	    dead_debug_reset (debug, r);
 #ifdef REG_DEAD_DEBUGGING
 	    df_print_note ("adding 2: ", insn, REG_NOTES (insn));
@@ -2992,7 +2992,7 @@ 
 		*added_notes_p = true;
 		return;
 	      }
-	    df_set_note (REG_DEAD, insn, regno_reg_rtx[r]);
+	    df_set_note (REG_DEAD, insn, crtl->emit.regno_reg_rtx[r]);
 #ifdef REG_DEAD_DEBUGGING
 	    df_print_note ("adding 2: ", insn, REG_NOTES (insn));
 #endif
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 169049)
+++ gcc/Makefile.in	(working copy)
@@ -2557,8 +2557,7 @@ 
    $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \
    output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
    $(TREE_PASS_H) $(FLAGS_H) $(TREE_INLINE_H) $(RECOG_H) insn-config.h \
-   $(EXPR_H) gt-tree-ssa-address.h $(GGC_H) tree-affine.h $(TARGET_H) \
-   tree-pretty-print.h
+   $(EXPR_H) tree-affine.h $(TARGET_H) tree-pretty-print.h
 tree-ssa-loop-niter.o : tree-ssa-loop-niter.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(PARAMS_H) \
    $(TREE_INLINE_H) output.h $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
@@ -2851,7 +2850,7 @@ 
    $(CONFIG_H)
 
 rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
-  $(GGC_H) $(BCONFIG_H) insn-notes.def reg-notes.def toplev.h $(DIAGNOSTIC_CORE_H)
+  $(GGC_H) $(BCONFIG_H) insn-notes.def reg-notes.def toplev.h $(DIAGNOSTIC_CORE_H) $(OBSTACK_H)
 
 print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
@@ -2897,7 +2896,7 @@ 
    $(TREE_PASS_H) $(DF_H) $(DIAGNOSTIC_H) vecprim.h $(SSAEXPAND_H)
 dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
    $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \
-   langhooks.h $(GGC_H) gt-dojump.h vecprim.h $(BASIC_BLOCK_H) output.h
+   langhooks.h vecprim.h $(BASIC_BLOCK_H) output.h
 builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(GIMPLE_H) $(FLAGS_H) $(TARGET_H) $(FUNCTION_H) $(REGS_H) \
    $(EXPR_H) $(OPTABS_H) insn-config.h $(RECOG_H) output.h typeclass.h \
@@ -2916,8 +2915,7 @@ 
    expmed.h
 explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
    $(FLAGS_H) hard-reg-set.h insn-config.h $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
-   $(DIAGNOSTIC_CORE_H) $(EXCEPT_H) $(FUNCTION_H) $(GGC_H) $(TM_P_H) langhooks.h gt-explow.h \
-   $(TARGET_H) output.h
+   $(DIAGNOSTIC_CORE_H) $(EXCEPT_H) $(FUNCTION_H) $(TM_P_H) langhooks.h $(TARGET_H) output.h
 optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(FLAGS_H) insn-config.h $(EXPR_H) $(OPTABS_H) $(LIBFUNCS_H) \
    $(RECOG_H) reload.h $(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) \
@@ -2964,7 +2962,7 @@ 
    $(RTL_H) $(TREE_H) $(FLAGS_H) debug.h $(INTEGRATE_H) insn-config.h \
    $(EXPR_H) $(REGS_H) intl.h $(FUNCTION_H) output.h $(RECOG_H) \
    $(EXCEPT_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h \
-   gt-integrate.h $(GGC_H) $(TREE_PASS_H) $(DF_H)
+   $(TREE_PASS_H) $(DF_H)
 jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) hard-reg-set.h $(REGS_H) insn-config.h $(RECOG_H) $(EXPR_H) \
    $(EXCEPT_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(TREE_PASS_H) \
@@ -3059,8 +3057,7 @@ 
 cselib.o : cselib.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) \
    $(EMIT_RTL_H) $(DIAGNOSTIC_CORE_H) output.h $(FUNCTION_H) $(TREE_PASS_H) \
-   cselib.h gt-cselib.h $(GGC_H) $(TM_P_H) $(PARAMS_H) alloc-pool.h \
-   $(HASHTAB_H) $(TARGET_H) $(BITMAP_H)
+   cselib.h $(TM_P_H) $(PARAMS_H) alloc-pool.h $(HASHTAB_H) $(TARGET_H) $(BITMAP_H)
 cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
    hard-reg-set.h $(FLAGS_H) insn-config.h $(RECOG_H) $(EXPR_H) toplev.h $(DIAGNOSTIC_CORE_H) \
    output.h $(FUNCTION_H) $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \
@@ -3088,9 +3085,9 @@ 
    $(REGS_H) $(TREE_H) $(TM_P_H) insn-config.h $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) \
    $(TARGET_H) $(OPTABS_H) insn-codes.h rtlhooks-def.h $(PARAMS_H) $(CGRAPH_H)
 gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
-   $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(GGC_H) \
+   $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
    $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h toplev.h $(DIAGNOSTIC_CORE_H) \
-   $(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) gt-gcse.h $(TREE_H) $(TIMEVAR_H) \
+   $(TM_P_H) $(PARAMS_H) cselib.h $(EXCEPT_H) $(TREE_H) $(TIMEVAR_H) \
    intl.h $(OBSTACK_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) \
    $(DF_H) gcse.h
 store-motion.o : store-motion.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
@@ -3293,7 +3290,7 @@ 
 caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(FUNCTION_H) \
    addresses.h $(RECOG_H) reload.h $(EXPR_H) $(DIAGNOSTIC_CORE_H) $(TM_P_H) $(DF_H) \
-   output.h gt-caller-save.h $(GGC_H)
+   output.h
 bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(EXCEPT_H) \
    $(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h $(EXPR_H) \
    $(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) $(FUNCTION_H) $(TREE_PASS_H) \
@@ -3427,7 +3424,7 @@ 
    $(COVERAGE_H) $(SCEV_H) $(GGC_H) predict.def $(TIMEVAR_H) $(TREE_DUMP_H) \
    $(TREE_FLOW_H) $(TREE_PASS_H) $(EXPR_H) pointer-set.h
 lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(DIAGNOSTIC_CORE_H) \
-   $(RTL_H) $(GGC_H) gt-lists.h
+   $(RTL_H)
 bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(RTL_H) $(FLAGS_H) $(TIMEVAR_H) output.h $(CFGLAYOUT_H) $(FIBHEAP_H) \
    $(TARGET_H) $(FUNCTION_H) $(TM_P_H) $(OBSTACK_H) $(EXPR_H) $(REGS_H) \
@@ -3719,24 +3716,23 @@ 
   $(srcdir)/fixed-value.h \
   $(srcdir)/output.h $(srcdir)/cfgloop.h \
   $(srcdir)/cselib.h $(srcdir)/basic-block.h  $(srcdir)/ipa-ref.h $(srcdir)/cgraph.h \
-  $(srcdir)/reload.h $(srcdir)/caller-save.c \
-  $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
+  $(srcdir)/reload.h \
+  $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cgraph.c \
   $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-inline.c $(srcdir)/matrix-reorg.c \
   $(srcdir)/dbxout.c $(srcdir)/ipa-struct-reorg.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
   $(srcdir)/tree-vect-generic.c \
-  $(srcdir)/dojump.c \
-  $(srcdir)/emit-rtl.c $(srcdir)/except.h $(srcdir)/explow.c $(srcdir)/expr.c \
+  $(srcdir)/emit-rtl.c $(srcdir)/except.h $(srcdir)/expr.c \
   $(srcdir)/expr.h \
   $(srcdir)/function.c $(srcdir)/except.c \
-  $(srcdir)/gcse.c $(srcdir)/godump.c \
-  $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
+  $(srcdir)/godump.c \
+  $(srcdir)/optabs.c \
   $(srcdir)/profile.c $(srcdir)/mcf.c \
   $(srcdir)/reg-stack.c $(srcdir)/cfglayout.c $(srcdir)/cfglayout.h \
   $(srcdir)/sdbout.c $(srcdir)/stor-layout.c \
   $(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
   $(srcdir)/gimple.h $(srcdir)/gimple.c \
   $(srcdir)/tree-mudflap.c $(srcdir)/tree-flow.h \
-  $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c $(srcdir)/tree-ssa-address.c \
+  $(srcdir)/tree-ssanames.c $(srcdir)/tree-eh.c \
   $(srcdir)/tree-cfg.c \
   $(srcdir)/tree-dfa.c \
   $(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
Index: gcc/basic-block.h
===================================================================
--- gcc/basic-block.h	(revision 169049)
+++ gcc/basic-block.h	(working copy)
@@ -41,7 +41,7 @@ 
   /* Instructions queued on the edge.  */
   union edge_def_insns {
     gimple_seq GTY ((tag ("true"))) g;
-    rtx GTY ((tag ("false"))) r;
+    rtx GTY ((tag ("false"),skip)) r;
   } GTY ((desc ("current_ir_type () == IR_GIMPLE"))) insns;
 
   /* Auxiliary info specific to a pass.  */
@@ -147,7 +147,7 @@ 
 
   union basic_block_il_dependent {
       struct gimple_bb_info * GTY ((tag ("0"))) gimple;
-      struct rtl_bb_info * GTY ((tag ("1"))) rtl;
+      struct rtl_bb_info * GTY ((tag ("1"), skip)) rtl;
     } GTY ((desc ("((%1.flags & BB_RTL) != 0)"))) il;
 
   /* Expected number of executions: calculated in profile.c.  */
@@ -169,7 +169,7 @@ 
   int flags;
 };
 
-struct GTY(()) rtl_bb_info {
+struct rtl_bb_info {
   /* The first and last insns of the block.  */
   rtx head_;
   rtx end_;
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	(revision 169049)
+++ gcc/config/i386/i386.h	(working copy)
@@ -2218,7 +2218,7 @@ 
   /* This pair tracks the currently active CFA as reg+offset.  When reg
      is drap_reg, we don't bother trying to record here the real CFA when
      it might really be a DW_CFA_def_cfa_expression.  */
-  rtx cfa_reg;
+  rtx GTY((skip)) cfa_reg;
   HOST_WIDE_INT cfa_offset;
 
   /* The current offset (canonically from the CFA) of ESP and EBP.
@@ -2251,7 +2251,7 @@ 
 /* Private to winnt.c.  */
 struct seh_frame_state;
 
-struct GTY(()) machine_function {
+struct machine_function {
   struct stack_local_entry *stack_locals;
   const char *some_ld_name;
   int varargs_gpr_size;
@@ -2318,7 +2318,7 @@ 
   struct machine_frame_state fs;
 
   /* During SEH output, this is non-null.  */
-  struct seh_frame_state * GTY((skip(""))) seh;
+  struct seh_frame_state * seh;
 };
 #endif
 
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 169049)
+++ gcc/config/i386/i386.c	(working copy)
@@ -2161,7 +2161,7 @@ 
 
 /* Define the structure for the machine field in struct function.  */
 
-struct GTY(()) stack_local_entry {
+struct stack_local_entry {
   unsigned short mode;
   unsigned short n;
   rtx rtl;
@@ -9486,7 +9486,7 @@ 
       }
 }
 
-static GTY(()) rtx queued_cfa_restores;
+static rtx queued_cfa_restores;
 
 /* Add a REG_CFA_RESTORE REG note to INSN or queue them until next stack
    manipulation insn.  The value is on the stack at CFA - CFA_OFFSET.
@@ -11218,12 +11218,12 @@ 
 /* A SYMBOL_REF for the function which allocates new stackspace for
    -fsplit-stack.  */
 
-static GTY(()) rtx split_stack_fn;
+static rtx split_stack_fn;
 
 /* A SYMBOL_REF for the more stack function when using the large
    model.  */
 
-static GTY(()) rtx split_stack_fn_large;
+static rtx split_stack_fn_large;
 
 /* Handle -fsplit-stack.  These are the first instructions in the
    function, even before the regular prologue.  */
@@ -21905,9 +21905,10 @@ 
 static struct machine_function *
 ix86_init_machine_status (void)
 {
-  struct machine_function *f;
+  struct machine_function *f = (struct machine_function *)
+    allocate_in_rtl_function_mem (sizeof (struct machine_function));;
+  memset (f, 0, sizeof (*f));
 
-  f = ggc_alloc_cleared_machine_function ();
   f->use_fast_prologue_epilogue_nregs = -1;
   f->tls_descriptor_call_expanded_p = 0;
   f->call_abi = ix86_abi;
@@ -21935,7 +21936,8 @@ 
     if (s->mode == mode && s->n == n)
       return copy_rtx (s->rtl);
 
-  s = ggc_alloc_stack_local_entry ();
+  s = (struct stack_local_entry *)
+    allocate_in_rtl_mem (sizeof (struct stack_local_entry));
   s->n = n;
   s->mode = mode;
   s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
@@ -21947,7 +21949,7 @@ 
 
 /* Construct the SYMBOL_REF for the tls_get_addr function.  */
 
-static GTY(()) rtx ix86_tls_symbol;
+static rtx ix86_tls_symbol;
 rtx
 ix86_tls_get_addr (void)
 {
@@ -21966,7 +21968,7 @@ 
 
 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
 
-static GTY(()) rtx ix86_tls_module_base_symbol;
+static rtx ix86_tls_module_base_symbol;
 rtx
 ix86_tls_module_base (void)
 {
Index: gcc/cfgrtl.c
===================================================================
--- gcc/cfgrtl.c	(revision 169049)
+++ gcc/cfgrtl.c	(working copy)
@@ -3086,7 +3086,9 @@ 
 init_rtl_bb_info (basic_block bb)
 {
   gcc_assert (!bb->il.rtl);
-  bb->il.rtl = ggc_alloc_cleared_rtl_bb_info ();
+  bb->il.rtl = (struct rtl_bb_info *)
+      allocate_in_rtl_mem (sizeof (struct rtl_bb_info));
+  memset (bb->il.rtl, 0, sizeof (struct rtl_bb_info));
 }
 
 /* Returns true if it is possible to remove edge E by redirecting
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c	(revision 169049)
+++ gcc/stmt.c	(working copy)
@@ -866,7 +866,7 @@ 
 
   body = gen_rtx_ASM_OPERANDS ((noutputs == 0 ? VOIDmode
 				: GET_MODE (output_rtx[0])),
-			       ggc_strdup (TREE_STRING_POINTER (string)),
+			       strdup_to_permanent_mem (TREE_STRING_POINTER (string)),
 			       empty_string, 0, argvec, constraintvec,
 			       labelvec, locus);
 
@@ -952,7 +952,7 @@ 
 
       ASM_OPERANDS_INPUT_CONSTRAINT_EXP (body, i)
 	= gen_rtx_ASM_INPUT (TYPE_MODE (type),
-			     ggc_strdup (constraints[i + noutputs]));
+			     strdup_to_permanent_mem (constraints[i + noutputs]));
 
       if (tree_conflicts_with_clobbers_p (val, &clobbered_regs))
 	clobber_conflict_found = 1;
@@ -1022,8 +1022,8 @@ 
 			   output_rtx[i],
 			   gen_rtx_ASM_OPERANDS
 			   (GET_MODE (output_rtx[i]),
-			    ggc_strdup (TREE_STRING_POINTER (string)),
-			    ggc_strdup (constraints[i]),
+			    strdup_to_permanent_mem (TREE_STRING_POINTER (string)),
+			    strdup_to_permanent_mem (constraints[i]),
 			    i, argvec, constraintvec, labelvec, locus));
 
 	  MEM_VOLATILE_P (SET_SRC (XVECEXP (body, 0, i))) = vol;
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c	(revision 169049)
+++ gcc/reload1.c	(working copy)
@@ -118,9 +118,8 @@ 
    is transferred to either reg_equiv_address or reg_equiv_mem.  */
 rtx *reg_equiv_memory_loc;
 
-/* We allocate reg_equiv_memory_loc inside a varray so that the garbage
-   collector can keep track of what is inside.  */
-VEC(rtx,gc) *reg_equiv_memory_loc_vec;
+/* We allocate reg_equiv_memory_loc inside a varray because of FIXME GC.  */
+VEC(rtx,heap) *reg_equiv_memory_loc_vec;
 
 /* Element N is the address of stack slot to which pseudo reg N is equivalent.
    This is used when the address is not valid as a memory address
@@ -606,9 +605,9 @@ 
 	*loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address[regno]);
       else
 	{
-	  gcc_assert (!REG_P (regno_reg_rtx[regno])
-		      || REGNO (regno_reg_rtx[regno]) != regno);
-	  *loc = regno_reg_rtx[regno];
+	  gcc_assert (!REG_P (crtl->emit.regno_reg_rtx[regno])
+		      || REGNO (crtl->emit.regno_reg_rtx[regno]) != regno);
+	  *loc = crtl->emit.regno_reg_rtx[regno];
 	}
 
       return;
@@ -887,7 +886,7 @@ 
 				    NULL_RTX);
 
 	    if (strict_memory_address_addr_space_p
-		  (GET_MODE (regno_reg_rtx[i]), XEXP (x, 0),
+		  (GET_MODE (crtl->emit.regno_reg_rtx[i]), XEXP (x, 0),
 		   MEM_ADDR_SPACE (x)))
 	      reg_equiv_mem[i] = x, reg_equiv_address[i] = 0;
 	    else if (CONSTANT_P (XEXP (x, 0))
@@ -1037,7 +1036,8 @@ 
 	      if (NOTE_P (equiv_insn)
 		  || can_throw_internal (equiv_insn))
 		;
-	      else if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn)))
+	      else if (reg_set_p (crtl->emit.regno_reg_rtx[i],
+				  PATTERN (equiv_insn)))
 		delete_dead_insn (equiv_insn);
 	      else
 		SET_INSN_DELETED (equiv_insn);
@@ -1103,7 +1103,7 @@ 
 	{
 	  if (reg_renumber[i] < 0)
 	    {
-	      rtx reg = regno_reg_rtx[i];
+	      rtx reg = crtl->emit.regno_reg_rtx[i];
 
 	      REG_USERVAR_P (reg) = 0;
 	      PUT_CODE (reg, MEM);
@@ -1126,7 +1126,7 @@ 
 	 in debug insns.  */
       if (MAY_HAVE_DEBUG_INSNS && reg_renumber[i] < 0)
 	{
-	  rtx reg = regno_reg_rtx[i];
+	  rtx reg = crtl->emit.regno_reg_rtx[i];
 	  rtx equiv = 0;
 	  df_ref use, next;
 
@@ -2140,17 +2140,17 @@ 
 {
   /* When outputting an inline function, this can happen
      for a reg that isn't actually used.  */
-  if (regno_reg_rtx[i] == 0)
+  if (crtl->emit.regno_reg_rtx[i] == 0)
     return;
 
   /* If the reg got changed to a MEM at rtl-generation time,
      ignore it.  */
-  if (!REG_P (regno_reg_rtx[i]))
+  if (!REG_P (crtl->emit.regno_reg_rtx[i]))
     return;
 
   /* Modify the reg-rtx to contain the new hard reg
      number or else to contain its pseudo reg number.  */
-  SET_REGNO (regno_reg_rtx[i],
+  SET_REGNO (crtl->emit.regno_reg_rtx[i],
 	     reg_renumber[i] >= 0 ? reg_renumber[i] : i);
 
   /* If we have a pseudo that is needed but has no hard reg or equivalent,
@@ -2163,7 +2163,7 @@ 
       && reg_equiv_memory_loc[i] == 0)
     {
       rtx x = NULL_RTX;
-      enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
+      enum machine_mode mode = GET_MODE (crtl->emit.regno_reg_rtx[i]);
       unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
       unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
       unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
@@ -2278,7 +2278,8 @@ 
 
       /* If we have any adjustment to make, or if the stack slot is the
 	 wrong mode, make a new stack slot.  */
-      x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust);
+      x = adjust_address_nv (x, GET_MODE (crtl->emit.regno_reg_rtx[i]),
+                             adjust);
 
       /* Set all of the memory attributes as appropriate for a spill.  */
       set_mem_attrs_for_spill (x);
@@ -4212,7 +4213,7 @@ 
     free (reg_equiv_invariant);
   reg_equiv_constant = 0;
   reg_equiv_invariant = 0;
-  VEC_free (rtx, gc, reg_equiv_memory_loc_vec);
+  VEC_free (rtx, heap, reg_equiv_memory_loc_vec);
   reg_equiv_memory_loc = 0;
 
   if (offsets_known_at)
@@ -7797,7 +7798,7 @@ 
       && MEM_P (rl->in_reg)
       && reload_spill_index[j] >= 0
       && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j]))
-    rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];
+    rl->in = crtl->emit.regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];
 
   /* If we are reloading a register that was recently stored in with an
      output-reload, see if we can prove there was
@@ -8129,7 +8130,7 @@ 
 		  if (HARD_REGISTER_NUM_P (out_regno))
 		    for (k = 1; k < out_nregs; k++)
 		      reg_last_reload_reg[out_regno + k]
-			= (piecemeal ? regno_reg_rtx[regno + k] : 0);
+			= (piecemeal ? crtl->emit.regno_reg_rtx[regno + k] : 0);
 
 		  /* Now do the inverse operation.  */
 		  for (k = 0; k < nregs; k++)
@@ -8201,7 +8202,7 @@ 
 		  if (HARD_REGISTER_NUM_P (in_regno))
 		    for (k = 1; k < in_nregs; k++)
 		      reg_last_reload_reg[in_regno + k]
-			= (piecemeal ? regno_reg_rtx[regno + k] : 0);
+			= (piecemeal ? crtl->emit.regno_reg_rtx[regno + k] : 0);
 
 		  /* Unless we inherited this reload, show we haven't
 		     recently done a store.