summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlauras <lauras@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-29 03:13:06 +0000
committerlauras <lauras@138bc75d-0d04-0410-961f-82ee72b054a4>2011-03-29 03:13:06 +0000
commita5ff64ea6267bfcd4dd04666acc364aabd18c33f (patch)
tree281dd3f09080e04b2b0e62260099db2d69a055c9
parentbe8a82b8e4ad4886a4fc8210ea7f6b48bd0f10ee (diff)
downloadgcc-a5ff64ea6267bfcd4dd04666acc364aabd18c33f.tar.gz
2011-03-29 Laurynas Biveinis <laurynas.biveinis@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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gc-improv@171651 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.gc-improv75
-rw-r--r--gcc/alias.c6
-rw-r--r--gcc/caller-save.c3
-rw-r--r--gcc/cfgexpand.c2
-rw-r--r--gcc/cfgloopanal.c4
-rw-r--r--gcc/config/i386/i386.c8
-rw-r--r--gcc/cselib.c6
-rw-r--r--gcc/dwarf2out.c25
-rw-r--r--gcc/emit-rtl.c63
-rw-r--r--gcc/function.c2
-rw-r--r--gcc/function.h3
-rw-r--r--gcc/gcse.c2
-rw-r--r--gcc/gengenrtl.c3
-rw-r--r--gcc/lists.c8
-rw-r--r--gcc/reginfo.c2
-rw-r--r--gcc/rtl.c44
-rw-r--r--gcc/rtl.h8
-rw-r--r--gcc/tree-ssa-address.c6
-rw-r--r--gcc/varasm.c16
19 files changed, 256 insertions, 30 deletions
diff --git a/gcc/ChangeLog.gc-improv b/gcc/ChangeLog.gc-improv
index ebe33431a72..b835e556a6b 100644
--- a/gcc/ChangeLog.gc-improv
+++ b/gcc/ChangeLog.gc-improv
@@ -1,3 +1,78 @@
+2011-03-29 Laurynas Biveinis <laurynas.biveinis@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.biveinis@gmail.com>
* varpool.c (varpool_finalize_decl): Fix typo in comment.
diff --git a/gcc/alias.c b/gcc/alias.c
index 7669eb1cc3e..60d7e48f0db 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -208,7 +208,7 @@ 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. */
+ array. TODO gc-improv. */
static VEC(rtx,heap) *old_reg_base_value;
#define static_reg_base_value \
@@ -2678,6 +2678,8 @@ init_alias_target (void)
{
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 @@ init_alias_target (void)
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
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index 8b796b9d2fa..801deb43992 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -192,6 +192,8 @@ init_caller_save (void)
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 @@ init_caller_save (void)
SET_HARD_REG_BIT (no_caller_save_reg_set, i);
}
}
+ use_rtl_function_mem ();
}
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 19278c30162..f41dfff63d1 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2424,9 +2424,11 @@ expand_debug_expr (tree exp)
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;
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 02f02657699..eecf46be7c2 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -335,6 +335,8 @@ init_set_costs (void)
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 @@ init_set_costs (void)
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
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d2500a19944..fa0e7cfaa62 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -22016,8 +22016,10 @@ ix86_output_call_insn (rtx insn, rtx call_op, int addr_op)
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 @@ ix86_tls_get_addr (void)
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 @@ ix86_tls_module_base (void)
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;
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 1ea708dc27e..89ef19b3da9 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -2419,7 +2419,11 @@ cselib_init (int record_what)
/* (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 ();
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 0dcb3f5357f..0e5c56c4ebf 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -7650,7 +7650,7 @@ add_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr)
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 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode,
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 @@ loc_list_from_tree (tree loc, int want_address)
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 @@ loc_list_from_tree (tree loc, int want_address)
{
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 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
&& 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 @@ gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
&& 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);
}
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index b002654b862..02f7a1ab3cc 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -391,6 +391,26 @@ gen_raw_REG (enum machine_mode mode, int regno)
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 @@ gen_rtx_CONST_INT (enum machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
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 @@ lookup_const_double (rtx real)
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 @@ immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, enum machine_mode mode)
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 @@ widen_memory_access (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset)
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 @@ get_spill_slot_decl (bool force_build_p)
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 @@ init_emit_regs (void)
{
int i;
+ use_rtl_permanent_mem ();
+
/* Reset register attributes */
htab_empty (reg_attrs_htab);
@@ -5680,6 +5710,8 @@ init_emit_regs (void)
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 @@ init_emit_once (void)
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 @@ init_emit_once (void)
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 @@ static rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
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"
diff --git a/gcc/function.c b/gcc/function.c
index 76dee465615..a9c1541d2bc 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -226,6 +226,8 @@ free_after_compilation (struct function *f)
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.
diff --git a/gcc/function.h b/gcc/function.h
index 27a5387c88d..781e0d3f11a 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -537,6 +537,9 @@ struct GTY(()) function {
/* 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. */
diff --git a/gcc/gcse.c b/gcc/gcse.c
index e337502842c..7fdd1acccf6 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -878,12 +878,14 @@ can_assign_to_reg_without_clobbers_p (rtx x)
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
diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c
index fc530288b3e..e64770070cf 100644
--- a/gcc/gengenrtl.c
+++ b/gcc/gengenrtl.c
@@ -128,7 +128,8 @@ special_rtx (int idx)
|| 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
diff --git a/gcc/lists.c b/gcc/lists.c
index 6e631edc1a3..174a39f5eb2 100644
--- a/gcc/lists.c
+++ b/gcc/lists.c
@@ -213,3 +213,11 @@ remove_free_EXPR_LIST_node (rtx *listp)
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;
+}
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 83ac4499b51..c8561293c12 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -614,8 +614,10 @@ init_fake_stack_mems (void)
{
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 ();
}
diff --git a/gcc/rtl.c b/gcc/rtl.c
index d010d6df3d7..b10abd83fb5 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -147,13 +147,34 @@ static int rtvec_alloc_sizes;
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. */
@@ -169,13 +190,19 @@ allocate_in_rtl_function_mem (int size)
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 @@ char *
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 @@ strdup_to_rtl_mem (const char *s)
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 @@ rtx_alloc_stat (RTX_CODE code MEM_STAT_DECL)
{
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 @@ copy_rtx (rtx orig)
case CONST_INT:
case CONST_DOUBLE:
case CONST_FIXED:
- case CONST_VECTOR:
case SYMBOL_REF:
case CODE_LABEL:
case PC:
diff --git a/gcc/rtl.h b/gcc/rtl.h
index eaf2f324211..6de7b2a2fd1 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1609,12 +1609,19 @@ extern rtx plus_constant (rtx, HOST_WIDE_INT);
/* 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_list_elem (rtx, rtx *);
extern rtx remove_free_INSN_LIST_node (rtx *);
extern rtx remove_free_EXPR_LIST_node (rtx *);
+extern void discard_rtx_lists (void);
/* reginfo.c */
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index e944d0d9fb8..59963b3d97b 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -114,6 +114,8 @@ gen_addr_rtx (enum machine_mode address_mode,
if (offset_p)
*offset_p = NULL;
+ use_rtl_permanent_mem ();
+
if (index)
{
act_elem = index;
@@ -175,6 +177,8 @@ gen_addr_rtx (enum machine_mode address_mode,
if (!*addr)
*addr = const0_rtx;
+
+ use_rtl_function_mem ();
}
/* Returns address for TARGET_MEM_REF with parameters given by ADDR
@@ -218,6 +222,7 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
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 @@ addr_for_mem_ref (struct mem_address *addr, addr_space_t as,
&templ->ref,
&templ->step_p,
&templ->off_p);
+ use_rtl_function_mem ();
}
if (st)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 16489c5d662..032885ece9d 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1294,6 +1294,8 @@ make_decl_rtl (tree decl)
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_decl_rtl (tree decl)
/* 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 @@ build_constant_desc (tree exp)
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 @@ build_constant_desc (tree exp)
desc->rtl = rtl;
+ use_rtl_function_mem ();
+
return desc;
}
@@ -3530,6 +3538,9 @@ force_const_mem (enum machine_mode mode, rtx x)
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 @@ force_const_mem (enum machine_mode mode, rtx x)
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. */