Index: gcc/function.c =================================================================== --- gcc/function.c (revision 171651) +++ gcc/function.c (working copy) @@ -151,6 +151,7 @@ static void do_clobber_return_reg (rtx, void *); static void do_use_return_reg (rtx, void *); static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED; +static void reinit_struct_function (void); /* Stack of nested functions. */ /* Keep track of the cfun stack. */ @@ -4316,6 +4317,7 @@ { cfun = new_cfun; invoke_set_current_function_hook (new_cfun ? new_cfun->decl : NULL_TREE); + reinit_struct_function (); } } @@ -4417,6 +4419,16 @@ allocate_struct_function (fndecl, false); } +/* Initialize those parts of struct function that are cleared during PCH read + and write. */ + +static void +reinit_struct_function (void) +{ + if (cfun && !cfun->machine && init_machine_status) + cfun->machine = (*init_machine_status) (); +} + /* Reset crtl and other non-struct-function variables to defaults as appropriate for emitting rtl at the start of a function. */ @@ -4437,8 +4449,7 @@ } /* cfun->machine is NULL after PCH read. Initialize it. */ - if (!cfun->machine && init_machine_status) - cfun->machine = (*init_machine_status) (); + reinit_struct_function (); cse_not_expected = ! optimize; Index: gcc/ChangeLog.gc-improv =================================================================== --- gcc/ChangeLog.gc-improv (revision 172076) +++ gcc/ChangeLog.gc-improv (working copy) @@ -1,3 +1,22 @@ +2011-06-02 Laurynas Biveinis + + * varasm.c (make_decl_rtl): Allocate DECL_RTL in the permanent RTL + memory. + + * rtl.c: (_obstack_allocated_p): Declare. + (allocated_in_function_mem_p): New. + (need_copy_p): New. + (copy_rtx): Re-enable sharing of CONST_VECTOR rtxes. Use + need_copy_p to decide on copying vs. sharing of rtxes. + + * function.c (reinit_struct_function): New. + (set_cfun, prepare_function_start): Call it. + + * config/i386/i386.c (ix86_expand_split_stack_prologue): Allocate + split_stack_fn in the permanent RTL memory. + (ix86_expand_split_stack_prologue): Allocate split_stack_fn_large + in the permanent RTL memory. + 2011-04-07 Laurynas Biveinis * stmt.c (label_rtx): Allocate RTX in permanent RTL memory. Index: gcc/varasm.c =================================================================== --- gcc/varasm.c (revision 171651) +++ gcc/varasm.c (working copy) @@ -1238,6 +1238,9 @@ "optimization may eliminate reads and/or " "writes to register variables"); + if (TREE_STATIC (decl)) + use_rtl_permanent_mem (); + /* If the user specified one of the eliminables registers here, e.g., FRAME_POINTER_REGNUM, we don't want to get this variable confused with that register and be eliminated. This usage is @@ -1248,6 +1251,9 @@ REG_USERVAR_P (DECL_RTL (decl)) = 1; if (TREE_STATIC (decl)) + use_rtl_function_mem (); + + if (TREE_STATIC (decl)) { /* Make this register global, so not usable for anything else. */ Index: gcc/rtl.c =================================================================== --- gcc/rtl.c (revision 171651) +++ gcc/rtl.c (working copy) @@ -150,6 +150,9 @@ static unsigned int obstack_nesting_level; static void *function_ob_first_obj; +/* obstack.[ch] explicitly declined to prototype this. */ +extern int _obstack_allocated_p (struct obstack *h, void *obj); + /* Prepares for allocation of RTXes. */ void init_rtl (void) @@ -323,7 +326,22 @@ && CONST_INT_P(XEXP (XEXP (orig, 0), 1))); } +/* Return TRUE if PTR points to function RTL memory. */ +static bool +allocated_in_function_mem_p(void * ptr) +{ + return _obstack_allocated_p (&function_obstack, ptr); +} +/* If original is in the function memory and the current allocation mode + is permanent memory, do a copy, share otherwise. */ +static bool +need_copy_p(rtx orig) +{ + return allocated_in_function_mem_p (orig) + && rtl_obstack == &permanent_obstack; +} + /* Create a new copy of an rtx. Recursively copies the operands of the rtx, except for those few rtx codes that are sharable. */ @@ -346,21 +364,33 @@ case CONST_INT: case CONST_DOUBLE: case CONST_FIXED: + case CONST_VECTOR: case SYMBOL_REF: case CODE_LABEL: case PC: case CC0: case SCRATCH: + if (!need_copy_p (orig)) + return orig; + /* TODO gc-improv: this and other RTX where it really does not make sense + to copy. */ /* SCRATCH must be shared because they represent distinct values. */ - return orig; + gcc_assert(code != SCRATCH); + break; case CLOBBER: - if (REG_P (XEXP (orig, 0)) && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER) + if (!need_copy_p (orig) + && REG_P (XEXP (orig, 0)) + && REGNO (XEXP (orig, 0)) < FIRST_PSEUDO_REGISTER) return orig; break; case CONST: if (shared_const_p (orig)) - return orig; + { + /* Shared constants must be allocated in the permanent memory. */ + gcc_assert (!need_copy_p (orig)); + return orig; + } break; /* A MEM with a constant address is not sharable. The problem is that Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 171651) +++ gcc/config/i386/i386.c (working copy) @@ -11413,7 +11413,11 @@ GEN_INT (REG_BR_PROB_BASE - REG_BR_PROB_BASE / 100)); if (split_stack_fn == NULL_RTX) - split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack"); + { + use_rtl_permanent_mem (); + split_stack_fn = gen_rtx_SYMBOL_REF (Pmode, "__morestack"); + use_rtl_function_mem (); + } fn = split_stack_fn; /* Get more stack space. We pass in the desired stack space and the @@ -11456,8 +11460,12 @@ gcc_assert ((args_size & 0xffffffff) == args_size); if (split_stack_fn_large == NULL_RTX) - split_stack_fn_large = - gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model"); + { + use_rtl_permanent_mem (); + split_stack_fn_large = + gen_rtx_SYMBOL_REF (Pmode, "__morestack_large_model"); + use_rtl_function_mem (); + } if (ix86_cmodel == CM_LARGE_PIC) {