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 <[email protected]>
* 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 <[email protected]>
+
+ * 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 <[email protected]>
* 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;