diff options
author | lauras <lauras@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-29 03:13:06 +0000 |
---|---|---|
committer | lauras <lauras@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-03-29 03:13:06 +0000 |
commit | a5ff64ea6267bfcd4dd04666acc364aabd18c33f (patch) | |
tree | 281dd3f09080e04b2b0e62260099db2d69a055c9 | |
parent | be8a82b8e4ad4886a4fc8210ea7f6b48bd0f10ee (diff) | |
download | gcc-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-improv | 75 | ||||
-rw-r--r-- | gcc/alias.c | 6 | ||||
-rw-r--r-- | gcc/caller-save.c | 3 | ||||
-rw-r--r-- | gcc/cfgexpand.c | 2 | ||||
-rw-r--r-- | gcc/cfgloopanal.c | 4 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 8 | ||||
-rw-r--r-- | gcc/cselib.c | 6 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 25 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 63 | ||||
-rw-r--r-- | gcc/function.c | 2 | ||||
-rw-r--r-- | gcc/function.h | 3 | ||||
-rw-r--r-- | gcc/gcse.c | 2 | ||||
-rw-r--r-- | gcc/gengenrtl.c | 3 | ||||
-rw-r--r-- | gcc/lists.c | 8 | ||||
-rw-r--r-- | gcc/reginfo.c | 2 | ||||
-rw-r--r-- | gcc/rtl.c | 44 | ||||
-rw-r--r-- | gcc/rtl.h | 8 | ||||
-rw-r--r-- | gcc/tree-ssa-address.c | 6 | ||||
-rw-r--r-- | gcc/varasm.c | 16 |
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. */ |