This is a first attempt to separate function RTL and make it default. This patch is enough for --disable-bootstrap --enable-languages=c to complete on Linux x64, but there still remains some RTL that is allocated on function obstack when it should be permanent instead.
The patch disables sharing of CONST_VECTOR rtxes. If that impacts memory usage too much, a new hash table can be introduced for storing them. That is for later, though. Committed to gc-improv. 2011-03-29 Laurynas Biveinis <laurynas.bivei...@gmail.com> * rtl.h (use_rtl_permanent_mem): New. (use_rtl_function_mem): New. (allocate_in_rtl_permanent_mem): New. (free_rtl_function_mem): New. (discard_rtx_lists): New. * rtl.c (obstack_nesting_level): New. (function_ob_first_obj): New. (init_rtl): Set function_ob_first_obj and obstack_nesting_level. (use_rtl_permanent_mem): New. (use_rtl_function_mem): New. (allocate_in_rtl_permanent_mem): New. (copy_rtx_to_permanent_mem): Use use_rtl_permanent_mem and use_rtl_function_mem. (strdup_to_permanent_mem): Likewise. (free_rtl_function_mem): New. (copy_rtx): Do not share CONST_VECTOR rtxes. * alias.c (init_alias_target): Allocate RTXes in permanent RTL memory. * cselib.c (cselib_init): Likewise. * config/i386/i386.c (ix86_init_machine_status): Likewise. (ix86_tls_get_addr): Likewise. (ix86_tls_module_base): Likewise. * cfgloopanal.c (init_set_costs): Likewise. * cfgexpand.c (expand_debug_expr): Likewise. * caller-save.c (init_caller_save): Likewise. * gcse.c (can_assign_to_reg_without_clobbers_p): Likewise. * tree-ssa-address.c (gen_addr_rtx): Likewise. (addr_for_mem_ref): Likewise. * reginfo.c (init_fake_stack_mems): Likewise. * varasm.c (make_decl_rtl): Likewise. (build_constant_desc): Likewise. (force_const_mem): Use RTL permanent memory for shared constant pool. * lists.c (discard_rtx_lists): New. * gengenrtl.c (special_rtx): Add "CONST" to specially handled rtxes. * function.h (struct function): New field spill_slot_decl. * function.c (free_after_compilation): Call free_rtl_function_mem and discard_rtx_lists. * emit-rtl.c (gen_rtx_CONST): New. (gen_rtx_CONST_INT): Perform the gen_rtx_raw_CONST_INT call using permanent RTL memory. (const_double_from_real_value): Allocate RTXes in permanent RTL memory. (immed_double_const): Likewise. (spill_slot_decl): Removed. (get_spill_slot_decl): Use cfun->spill_slot_decl. (init_emit_regs): Allocate RTXes in permanent RTL memory. (init_emit_once): Likewise.. (gen_hard_reg_clobber): Likewise. * dwarf2out.c (add_AT_addr): Copy addr to permanent RTL memory. (mem_loc_descriptor): Copy rtl to permanent RTL memory. (loc_list_from_tree): Likewise. (gen_variable_die): Perform the plus_constant calls using permanent RTL memory.
Index: gengenrtl.c =================================================================== --- gengenrtl.c (revision 170593) +++ gengenrtl.c (working copy) @@ -128,7 +128,8 @@ || strcmp (defs[idx].enumname, "REG") == 0 || strcmp (defs[idx].enumname, "SUBREG") == 0 || strcmp (defs[idx].enumname, "MEM") == 0 - || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0); + || strcmp (defs[idx].enumname, "CONST_VECTOR") == 0 + || strcmp (defs[idx].enumname, "CONST") == 0); } /* Return nonzero if the RTL code given by index IDX is one that we should Index: lists.c =================================================================== --- lists.c (revision 170593) +++ lists.c (working copy) @@ -213,3 +213,11 @@ return elem; } + +/* Discards the cache lists once the RTXes in them are freed. */ +void +discard_rtx_lists (void) +{ + unused_insn_list = NULL; + unused_expr_list = NULL; +} Index: cfgloopanal.c =================================================================== --- cfgloopanal.c (revision 170593) +++ cfgloopanal.c (working copy) @@ -335,6 +335,8 @@ rtx mem = validize_mem (gen_rtx_MEM (SImode, addr)); unsigned i; + use_rtl_permanent_mem (); + target_avail_regs = 0; target_clobbered_regs = 0; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) @@ -373,7 +375,9 @@ end_sequence (); target_spill_cost [speed] = seq_cost (seq, speed); } + default_rtl_profile (); + use_rtl_function_mem (); } /* Estimates cost of increased register pressure caused by making N_NEW new Index: caller-save.c =================================================================== --- caller-save.c (revision 170594) +++ caller-save.c (working copy) @@ -192,6 +192,8 @@ caller_save_initialized_p = true; + use_rtl_permanent_mem (); + CLEAR_HARD_REG_SET (no_caller_save_reg_set); /* First find all the registers that we need to deal with and all the modes that they can have. If we can't find a mode to use, @@ -280,6 +282,7 @@ SET_HARD_REG_BIT (no_caller_save_reg_set, i); } } + use_rtl_function_mem (); } Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 170594) +++ dwarf2out.c (working copy) @@ -7650,7 +7650,7 @@ attr.dw_attr = attr_kind; attr.dw_attr_val.val_class = dw_val_class_addr; - attr.dw_attr_val.v.val_addr = addr; + attr.dw_attr_val.v.val_addr = copy_rtx_to_permanent_mem (addr); add_dwarf_attr (die, &attr); } @@ -13937,7 +13937,7 @@ temp = new_loc_descr (DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u, 0, 0); temp->dw_loc_oprnd1.val_class = dw_val_class_addr; - temp->dw_loc_oprnd1.v.val_addr = rtl; + temp->dw_loc_oprnd1.v.val_addr = copy_rtx_to_permanent_mem (rtl); temp->dtprel = true; mem_loc_result = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0); @@ -15520,7 +15520,7 @@ ret = new_loc_descr (first_op, 0, 0); ret->dw_loc_oprnd1.val_class = dw_val_class_addr; - ret->dw_loc_oprnd1.v.val_addr = rtl; + ret->dw_loc_oprnd1.v.val_addr = copy_rtx_to_permanent_mem (rtl); ret->dtprel = dtprel; ret1 = new_loc_descr (second_op, 0, 0); @@ -15571,7 +15571,7 @@ { ret = new_loc_descr (DW_OP_addr, 0, 0); ret->dw_loc_oprnd1.val_class = dw_val_class_addr; - ret->dw_loc_oprnd1.v.val_addr = rtl; + ret->dw_loc_oprnd1.v.val_addr = copy_rtx_to_permanent_mem (rtl); } else { @@ -19542,8 +19542,13 @@ && loc->expr->dw_loc_next == NULL && GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF) - loc->expr->dw_loc_oprnd1.v.val_addr - = plus_constant (loc->expr->dw_loc_oprnd1.v.val_addr, off); + { + use_rtl_permanent_mem (); + loc->expr->dw_loc_oprnd1.v.val_addr + = plus_constant (loc->expr->dw_loc_oprnd1.v.val_addr, + off); + use_rtl_function_mem (); + } else loc_list_plus_const (loc, off); } @@ -19605,8 +19610,12 @@ && loc->expr->dw_loc_opc == DW_OP_addr && loc->expr->dw_loc_next == NULL && GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF) - loc->expr->dw_loc_oprnd1.v.val_addr - = plus_constant (loc->expr->dw_loc_oprnd1.v.val_addr, off); + { + use_rtl_permanent_mem (); + loc->expr->dw_loc_oprnd1.v.val_addr + = plus_constant (loc->expr->dw_loc_oprnd1.v.val_addr, off); + use_rtl_function_mem (); + } else loc_list_plus_const (loc, off); } Index: tree-ssa-address.c =================================================================== --- tree-ssa-address.c (revision 170593) +++ tree-ssa-address.c (working copy) @@ -114,6 +114,8 @@ if (offset_p) *offset_p = NULL; + use_rtl_permanent_mem (); + if (index) { act_elem = index; @@ -175,6 +177,8 @@ if (!*addr) *addr = const0_rtx; + + use_rtl_function_mem (); } /* Returns address for TARGET_MEM_REF with parameters given by ADDR @@ -218,6 +222,7 @@ templ = VEC_index (mem_addr_template, mem_addr_template_list, templ_index); if (!templ->ref) { + use_rtl_permanent_mem (); sym = (addr->symbol ? gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol")) : NULL_RTX); @@ -234,6 +239,7 @@ &templ->ref, &templ->step_p, &templ->off_p); + use_rtl_function_mem (); } if (st) Index: function.c =================================================================== --- function.c (revision 170593) +++ function.c (working copy) @@ -226,6 +226,8 @@ f->cfg = NULL; insn_locators_free (); + free_rtl_function_mem (); + discard_rtx_lists (); } /* Return size needed for stack frame based on slots so far allocated. Index: function.h =================================================================== --- function.h (revision 170593) +++ function.h (working copy) @@ -537,6 +537,9 @@ /* Vector of various tree declarations. */ VEC(tree,gc) *debug_decls; + /* A fake decl that is used as the MEM_EXPR of spill slots. */ + tree spill_slot_decl; + /* For md files. */ /* tm.h can use this to store whatever it likes. */ Index: gcse.c =================================================================== --- gcse.c (revision 170594) +++ gcse.c (working copy) @@ -878,12 +878,14 @@ our test insn if we haven't already. */ if (test_insn == 0) { + use_rtl_permanent_mem (); test_insn = make_insn_raw (gen_rtx_SET (VOIDmode, gen_rtx_REG (word_mode, FIRST_PSEUDO_REGISTER * 2), const0_rtx)); NEXT_INSN (test_insn) = PREV_INSN (test_insn) = 0; + use_rtl_function_mem (); } /* Now make an insn like the one we would make when GCSE'ing and see if Index: alias.c =================================================================== --- alias.c (revision 170593) +++ alias.c (working copy) @@ -208,7 +208,7 @@ /* We preserve the copy of old array around to avoid amount of garbage produced. About 8% of garbage produced were attributed to this - array. */ + array. TODO gc-improv. */ static VEC(rtx,heap) *old_reg_base_value; #define static_reg_base_value \ @@ -2678,6 +2678,8 @@ { int i; + use_rtl_permanent_mem (); + memset (static_reg_base_value, 0, sizeof static_reg_base_value); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) @@ -2699,6 +2701,8 @@ static_reg_base_value[HARD_FRAME_POINTER_REGNUM] = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx); #endif + + use_rtl_function_mem (); } /* Set MEMORY_MODIFIED when X modifies DATA (that is assumed Index: ChangeLog.gc-improv =================================================================== --- ChangeLog.gc-improv (revision 170593) +++ ChangeLog.gc-improv (working copy) @@ -1,3 +1,78 @@ +2011-03-29 Laurynas Biveinis <laurynas.bivei...@gmail.com> + + * rtl.h (use_rtl_permanent_mem): New. + (use_rtl_function_mem): New. + (allocate_in_rtl_permanent_mem): New. + (free_rtl_function_mem): New. + (discard_rtx_lists): New. + + * rtl.c (obstack_nesting_level): New. + (function_ob_first_obj): New. + (init_rtl): Set function_ob_first_obj and obstack_nesting_level. + (use_rtl_permanent_mem): New. + (use_rtl_function_mem): New. + (allocate_in_rtl_permanent_mem): New. + (copy_rtx_to_permanent_mem): Use use_rtl_permanent_mem and + use_rtl_function_mem. + (strdup_to_permanent_mem): Likewise. + (free_rtl_function_mem): New. + (copy_rtx): Do not share CONST_VECTOR rtxes. + + * alias.c (init_alias_target): Allocate RTXes in permanent RTL + memory. + + * cselib.c (cselib_init): Likewise. + + * config/i386/i386.c (ix86_init_machine_status): Likewise. + (ix86_tls_get_addr): Likewise. + (ix86_tls_module_base): Likewise. + + * cfgloopanal.c (init_set_costs): Likewise. + + * cfgexpand.c (expand_debug_expr): Likewise. + + * caller-save.c (init_caller_save): Likewise. + + * gcse.c (can_assign_to_reg_without_clobbers_p): Likewise. + + * tree-ssa-address.c (gen_addr_rtx): Likewise. + (addr_for_mem_ref): Likewise. + + * reginfo.c (init_fake_stack_mems): Likewise. + + * varasm.c (make_decl_rtl): Likewise. + (build_constant_desc): Likewise. + (force_const_mem): Use RTL permanent memory for shared constant + pool. + + * lists.c (discard_rtx_lists): New. + + * gengenrtl.c (special_rtx): Add "CONST" to specially handled + rtxes. + + * function.h (struct function): New field spill_slot_decl. + + * function.c (free_after_compilation): Call free_rtl_function_mem + and discard_rtx_lists. + + * emit-rtl.c (gen_rtx_CONST): New. + (gen_rtx_CONST_INT): Perform the gen_rtx_raw_CONST_INT call using + permanent RTL memory. + (const_double_from_real_value): Allocate RTXes in permanent RTL + memory. + (immed_double_const): Likewise. + (spill_slot_decl): Removed. + (get_spill_slot_decl): Use cfun->spill_slot_decl. + (init_emit_regs): Allocate RTXes in permanent RTL memory. + (init_emit_once): Likewise.. + (gen_hard_reg_clobber): Likewise. + + * dwarf2out.c (add_AT_addr): Copy addr to permanent RTL memory. + (mem_loc_descriptor): Copy rtl to permanent RTL memory. + (loc_list_from_tree): Likewise. + (gen_variable_die): Perform the plus_constant calls using + permanent RTL memory. + 2011-03-01 Laurynas Biveinis <laurynas.bivei...@gmail.com> * varpool.c (varpool_finalize_decl): Fix typo in comment. Index: emit-rtl.c =================================================================== --- emit-rtl.c (revision 170594) +++ emit-rtl.c (working copy) @@ -391,6 +391,26 @@ special_rtx in gengenrtl.c as well. */ rtx +gen_rtx_CONST (enum machine_mode mode, rtx arg) +{ + rtx x; + /* CONST can be shared if it contains a SYMBOL_REF. If it contains + a LABEL_REF, it isn't sharable. */ + bool shared = (GET_CODE (arg) == PLUS + && GET_CODE (XEXP (arg, 0)) == SYMBOL_REF + && CONST_INT_P (XEXP (arg, 1))); + if (shared) + { + use_rtl_permanent_mem (); + arg = copy_rtx (arg); + } + x = gen_rtx_raw_CONST (mode, arg); + if (shared) + use_rtl_function_mem (); + return x; +} + +rtx gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg) { void **slot; @@ -407,7 +427,11 @@ slot = htab_find_slot_with_hash (const_int_htab, &arg, (hashval_t) arg, INSERT); if (*slot == 0) - *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg); + { + use_rtl_permanent_mem (); + *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg); + use_rtl_function_mem (); + } return (rtx) *slot; } @@ -440,11 +464,16 @@ rtx const_double_from_real_value (REAL_VALUE_TYPE value, enum machine_mode mode) { - rtx real = rtx_alloc (CONST_DOUBLE); + rtx real; + use_rtl_permanent_mem (); + + real = rtx_alloc (CONST_DOUBLE); PUT_MODE (real, mode); real->u.rv = value; + use_rtl_function_mem (); + return lookup_const_double (real); } @@ -546,7 +575,9 @@ return GEN_INT (i0); /* We use VOIDmode for integers. */ + use_rtl_permanent_mem (); value = rtx_alloc (CONST_DOUBLE); + use_rtl_function_mem (); PUT_MODE (value, VOIDmode); CONST_DOUBLE_LOW (value) = i0; @@ -2219,13 +2250,10 @@ return new_rtx; } -/* A fake decl that is used as the MEM_EXPR of spill slots. */ -static GTY(()) tree spill_slot_decl; - tree get_spill_slot_decl (bool force_build_p) { - tree d = spill_slot_decl; + tree d = cfun->spill_slot_decl; rtx rd; if (d || !force_build_p) @@ -2236,7 +2264,7 @@ DECL_ARTIFICIAL (d) = 1; DECL_IGNORED_P (d) = 1; TREE_USED (d) = 1; - spill_slot_decl = d; + cfun->spill_slot_decl = d; rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx); MEM_NOTRAP_P (rd) = 1; @@ -5641,6 +5669,8 @@ { int i; + use_rtl_permanent_mem (); + /* Reset register attributes */ htab_empty (reg_attrs_htab); @@ -5680,6 +5710,8 @@ pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); else pic_offset_table_rtx = NULL_RTX; + + use_rtl_function_mem (); } /* Create some permanent unique rtl objects shared between all functions. */ @@ -5691,6 +5723,8 @@ enum machine_mode mode; enum machine_mode double_mode; + use_rtl_permanent_mem (); + /* Initialize the CONST_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute hash tables. */ const_int_htab = htab_create (37, const_int_htab_hash, const_int_htab_eq, @@ -5936,6 +5970,8 @@ const_tiny_rtx[0][(int) BImode] = const0_rtx; if (STORE_FLAG_VALUE == 1) const_tiny_rtx[1][(int) BImode] = const1_rtx; + + use_rtl_function_mem (); } /* Produce exact duplicate of insn INSN after AFTER. @@ -6007,11 +6043,14 @@ rtx gen_hard_reg_clobber (enum machine_mode mode, unsigned int regno) { - if (hard_reg_clobbers[mode][regno]) - return hard_reg_clobbers[mode][regno]; - else - return (hard_reg_clobbers[mode][regno] = - gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno))); + if (!hard_reg_clobbers[mode][regno]) + { + use_rtl_permanent_mem (); + hard_reg_clobbers[mode][regno] = + gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)); + use_rtl_function_mem (); + } + return hard_reg_clobbers[mode][regno]; } #include "gt-emit-rtl.h" Index: cfgexpand.c =================================================================== --- cfgexpand.c (revision 170594) +++ cfgexpand.c (working copy) @@ -2424,9 +2424,11 @@ if (op0) return op0; + use_rtl_permanent_mem (); op0 = gen_rtx_DEBUG_EXPR (mode); DEBUG_EXPR_TREE_DECL (op0) = exp; SET_DECL_RTL (exp, op0); + use_rtl_function_mem (); return op0; Index: cselib.c =================================================================== --- cselib.c (revision 170594) +++ cselib.c (working copy) @@ -2419,7 +2419,11 @@ /* (mem:BLK (scratch)) is a special mechanism to conflict with everything, see canon_true_dependence. This is only created once. */ if (! callmem) - callmem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)); + { + use_rtl_permanent_mem (); + callmem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)); + use_rtl_function_mem (); + } cselib_nregs = max_reg_num (); Index: varasm.c =================================================================== --- varasm.c (revision 170594) +++ varasm.c (working copy) @@ -1294,6 +1294,8 @@ if (TREE_CODE (decl) == VAR_DECL && DECL_WEAK (decl)) DECL_COMMON (decl) = 0; + use_rtl_permanent_mem (); + if (use_object_blocks_p () && use_blocks_for_decl_p (decl)) x = create_block_symbol (name, get_block_for_decl (decl), -1); else @@ -1323,6 +1325,8 @@ /* Make this function static known to the mudflap runtime. */ if (flag_mudflap && TREE_CODE (decl) == VAR_DECL) mudflap_enqueue_decl (decl); + + use_rtl_function_mem (); } /* Like make_decl_rtl, but inhibit creation of new alias sets when @@ -3105,6 +3109,8 @@ align_variable (decl, 0); VEC_safe_push (tree, gc, saved_constant_decls, decl); + use_rtl_permanent_mem (); + /* Now construct the SYMBOL_REF and the MEM. */ if (use_object_blocks_p ()) { @@ -3136,6 +3142,8 @@ desc->rtl = rtl; + use_rtl_function_mem (); + return desc; } @@ -3530,6 +3538,9 @@ if (desc) return copy_rtx (desc->mem); + if (pool == shared_constant_pool) + use_rtl_permanent_mem (); + /* Otherwise, create a new descriptor. */ desc = XNEW (struct constant_descriptor_rtx); *slot = desc; @@ -3592,7 +3603,10 @@ if (GET_CODE (x) == LABEL_REF) LABEL_PRESERVE_P (XEXP (x, 0)) = 1; - return copy_rtx (def); + if (pool == shared_constant_pool) + use_rtl_function_mem (); + + return def; // TODO: gc-improv: why copy_rtx? } /* Given a constant pool SYMBOL_REF, return the corresponding constant. */ Index: rtl.c =================================================================== --- rtl.c (revision 170593) +++ rtl.c (working copy) @@ -147,15 +147,36 @@ static struct obstack function_obstack; static struct obstack permanent_obstack; struct obstack *rtl_obstack = &function_obstack; +static unsigned int obstack_nesting_level; +static void *function_ob_first_obj; /* Prepares for allocation of RTXes. */ void init_rtl (void) { gcc_obstack_init (&function_obstack); + function_ob_first_obj = obstack_alloc (&function_obstack, 0); gcc_obstack_init (&permanent_obstack); + obstack_nesting_level = 0; } +void +use_rtl_permanent_mem (void) +{ + if (obstack_nesting_level == 0) + rtl_obstack = &permanent_obstack; + obstack_nesting_level++; +} + +void +use_rtl_function_mem (void) +{ + gcc_assert (obstack_nesting_level > 0); + obstack_nesting_level--; + if (obstack_nesting_level == 0) + rtl_obstack = &function_obstack; +} + /* Allocates memory from the RTL heap with the current lifetime. */ void * allocate_in_rtl_mem (int size) @@ -169,13 +190,19 @@ return obstack_alloc (&function_obstack, size); } +void * +allocate_in_rtl_permanent_mem (int size) +{ + return obstack_alloc (&permanent_obstack, size); +} + rtx copy_rtx_to_permanent_mem (rtx x) { rtx copy; - rtl_obstack = &permanent_obstack; + use_rtl_permanent_mem (); copy = copy_rtx (x); - rtl_obstack = &function_obstack; + use_rtl_function_mem (); return copy; } @@ -183,9 +210,9 @@ strdup_to_permanent_mem (const char *s) { char *result; - rtl_obstack = &permanent_obstack; + use_rtl_permanent_mem (); result = strdup_to_rtl_mem (s); - rtl_obstack = &function_obstack; + use_rtl_function_mem (); return result; } @@ -198,6 +225,13 @@ return result; } +/* Frees everything in the RTL memory of the current function. */ +void +free_rtl_function_mem (void) +{ + obstack_free (&function_obstack, function_ob_first_obj); +} + /* Allocate an rtx vector of N elements. Store the length, and initialize all elements to zero. */ @@ -254,6 +288,7 @@ { int length = RTX_CODE_SIZE (code); rtx rt; + /* TODO gc-improv: do not manipulate obstack alignment directly. */ length = (length + rtl_obstack->alignment_mask) & ~rtl_obstack->alignment_mask; rt = (rtx) obstack_alloc (rtl_obstack, length); @@ -311,7 +346,6 @@ case CONST_INT: case CONST_DOUBLE: case CONST_FIXED: - case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: case PC: Index: rtl.h =================================================================== --- rtl.h (revision 170594) +++ rtl.h (working copy) @@ -1609,12 +1609,19 @@ /* In rtl.c */ extern void init_rtl (void); + +extern void use_rtl_permanent_mem (void); +extern void use_rtl_function_mem (void); + extern void * allocate_in_rtl_mem (int); extern void * allocate_in_rtl_function_mem (int); +extern void * allocate_in_rtl_permanent_mem (int); extern rtx copy_rtx_to_permanent_mem (rtx); extern char * strdup_to_permanent_mem (const char *); extern char * strdup_to_rtl_mem (const char *); +extern void free_rtl_function_mem (void); + extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL); #define rtx_alloc(c) rtx_alloc_stat (c MEM_STAT_INFO) @@ -1993,6 +2000,7 @@ extern rtx remove_free_INSN_LIST_node (rtx *); extern rtx remove_free_EXPR_LIST_node (rtx *); +extern void discard_rtx_lists (void); /* reginfo.c */ Index: reginfo.c =================================================================== --- reginfo.c (revision 170593) +++ reginfo.c (working copy) @@ -614,8 +614,10 @@ { int i; + use_rtl_permanent_mem (); for (i = 0; i < MAX_MACHINE_MODE; i++) top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx); + use_rtl_function_mem (); } Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 170594) +++ config/i386/i386.c (working copy) @@ -22016,8 +22016,10 @@ static struct machine_function * ix86_init_machine_status (void) { + /* TODO gc-improv: workout lifetime of this. It seems that it is live for + every function throughout the whole compilation. */ struct machine_function *f = (struct machine_function *) - allocate_in_rtl_function_mem (sizeof (struct machine_function));; + allocate_in_rtl_permanent_mem (sizeof (struct machine_function));; memset (f, 0, sizeof (*f)); f->use_fast_prologue_epilogue_nregs = -1; @@ -22067,11 +22069,13 @@ if (!ix86_tls_symbol) { + use_rtl_permanent_mem (); ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, (TARGET_ANY_GNU_TLS && !TARGET_64BIT) ? "___tls_get_addr" : "__tls_get_addr"); + use_rtl_function_mem (); } return ix86_tls_symbol; @@ -22086,10 +22090,12 @@ if (!ix86_tls_module_base_symbol) { + use_rtl_permanent_mem (); ix86_tls_module_base_symbol = gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_"); SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol) |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT; + use_rtl_function_mem (); } return ix86_tls_module_base_symbol;