diff options
author | Jeff Law <law@gcc.gnu.org> | 1997-11-02 14:19:36 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1997-11-02 14:19:36 -0700 |
commit | e9a25f70a0a7b82881b56cb3dfa7422b2968682a (patch) | |
tree | 46fe768360493f03f7282d07762e7b26c292aabd /gcc/integrate.c | |
parent | bb84e66919817020267815eed4304e543688e722 (diff) | |
download | gcc-e9a25f70a0a7b82881b56cb3dfa7422b2968682a.tar.gz |
Update mainline egcs to gcc2 snapshot 971021.
From-SVN: r16278
Diffstat (limited to 'gcc/integrate.c')
-rw-r--r-- | gcc/integrate.c | 82 |
1 files changed, 67 insertions, 15 deletions
diff --git a/gcc/integrate.c b/gcc/integrate.c index 27aa4df6ebf..3931dee279d 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -20,9 +20,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> - #include "config.h" +#include <stdio.h> #include "rtl.h" #include "tree.h" #include "regs.h" @@ -31,6 +30,7 @@ Boston, MA 02111-1307, USA. */ #include "insn-flags.h" #include "expr.h" #include "output.h" +#include "recog.h" #include "integrate.h" #include "real.h" #include "except.h" @@ -218,7 +218,8 @@ static rtx *insn_map; static tree *parmdecl_map; /* Keep track of first pseudo-register beyond those that are parms. */ -static int max_parm_reg; +extern int max_parm_reg; +extern rtx *parm_reg_stack_loc; /* When an insn is being copied by copy_for_inline, this is nonzero if we have copied an ASM_OPERANDS. @@ -344,7 +345,8 @@ initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, copy) current_function_outgoing_args_size, arg_vector, (rtx) DECL_INITIAL (fndecl), (rtvec) regno_reg_rtx, regno_pointer_flag, - regno_pointer_align); + regno_pointer_align, + (rtvec) parm_reg_stack_loc); } /* Subroutine for `save_for_inline{copying,nocopy}'. Finishes up the @@ -435,7 +437,6 @@ save_for_inline_copying (fndecl) for the parms, prior to elimination of virtual registers. These values are needed for substituting parms properly. */ - max_parm_reg = max_parm_reg_num (); parmdecl_map = (tree *) alloca (max_parm_reg * sizeof (tree)); head = initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, 1); @@ -776,7 +777,6 @@ save_for_inline_nocopy (fndecl) for the parms, prior to elimination of virtual registers. These values are needed for substituting parms properly. */ - max_parm_reg = max_parm_reg_num (); parmdecl_map = (tree *) alloca (max_parm_reg * sizeof (tree)); /* Make and emit a return-label if we have not already done so. */ @@ -1134,6 +1134,8 @@ copy_for_inline (orig) } break; #endif + default: + break; } /* Replace this rtx with a copy of itself. */ @@ -1428,7 +1430,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, and argument memory blocks. If there are no insns yet, add a dummy insn that can be used as an insertion point. */ map->insns_at_start = get_last_insn (); - if (!map->insns_at_start) + if (map->insns_at_start == 0) map->insns_at_start = emit_note (NULL_PTR, NOTE_INSN_DELETED); map->regno_pointer_flag = INLINE_REGNO_POINTER_FLAG (header); @@ -1655,6 +1657,7 @@ expand_inline_function (fndecl, parms, target, ignore, type, force_operand (structure_value_addr, NULL_RTX)); map->reg_map[REGNO (XEXP (loc, 0))] = temp; if ((CONSTANT_P (structure_value_addr) + || GET_CODE (structure_value_addr) == ADDRESSOF || (GET_CODE (structure_value_addr) == PLUS && XEXP (structure_value_addr, 0) == virtual_stack_vars_rtx && GET_CODE (XEXP (structure_value_addr, 1)) == CONST_INT)) @@ -2333,6 +2336,30 @@ copy_rtx_and_substitute (orig, map) return gen_rtx (SUBREG, GET_MODE (orig), copy, SUBREG_WORD (orig)); + case ADDRESSOF: + copy = gen_rtx (ADDRESSOF, mode, + copy_rtx_and_substitute (XEXP (orig, 0), map)); + SET_ADDRESSOF_DECL (copy, ADDRESSOF_DECL (orig)); + regno = ADDRESSOF_REGNO (orig); + if (map->reg_map[regno]) + regno = REGNO (map->reg_map[regno]); + else if (regno > LAST_VIRTUAL_REGISTER) + { + temp = XEXP (orig, 0); + map->reg_map[regno] = gen_reg_rtx (GET_MODE (temp)); + REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (temp); + REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (temp); + RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (temp); + /* A reg with REG_FUNCTION_VALUE_P true will never reach here. */ + + if (map->regno_pointer_flag[regno]) + mark_reg_pointer (map->reg_map[regno], + map->regno_pointer_align[regno]); + regno = REGNO (map->reg_map[regno]); + } + ADDRESSOF_REGNO (copy) = regno; + return copy; + case USE: case CLOBBER: /* USE and CLOBBER are ordinary, but we convert (use (subreg foo)) @@ -2510,13 +2537,26 @@ copy_rtx_and_substitute (orig, map) case SET: /* If this is setting fp or ap, it means that we have a nonlocal goto. - Don't alter that. + Adjust the setting by the offset of the area we made. If the nonlocal goto is into the current function, this will result in unnecessarily bad code, but should work. */ if (SET_DEST (orig) == virtual_stack_vars_rtx || SET_DEST (orig) == virtual_incoming_args_rtx) - return gen_rtx (SET, VOIDmode, SET_DEST (orig), - copy_rtx_and_substitute (SET_SRC (orig), map)); + { + /* In case a translation hasn't occurred already, make one now. */ + rtx junk = copy_rtx_and_substitute (SET_DEST (orig), map); + rtx equiv_reg = map->reg_map[REGNO (SET_DEST (orig))]; + rtx equiv_loc = map->const_equiv_map[REGNO (equiv_reg)]; + HOST_WIDE_INT loc_offset + = GET_CODE (equiv_loc) == REG ? 0 : INTVAL (XEXP (equiv_loc, 1)); + + return gen_rtx (SET, VOIDmode, SET_DEST (orig), + force_operand + (plus_constant + (copy_rtx_and_substitute (SET_SRC (orig), map), + - loc_offset), + NULL_RTX)); + } break; case MEM: @@ -2535,6 +2575,9 @@ copy_rtx_and_substitute (orig, map) RTX_UNCHANGING_P (copy) = RTX_UNCHANGING_P (orig); return copy; + + default: + break; } copy = rtx_alloc (code); @@ -2550,6 +2593,7 @@ copy_rtx_and_substitute (orig, map) switch (*format_ptr++) { case '0': + XEXP (copy, i) = XEXP (orig, i); break; case 'e': @@ -2827,9 +2871,11 @@ subst_constants (loc, insn, map) map->equiv_sets[map->num_sets].equiv = copy_rtx (src); map->equiv_sets[map->num_sets++].dest = dest; } - - return; } + return; + + default: + break; } format_ptr = GET_RTX_FORMAT (code); @@ -2949,9 +2995,13 @@ mark_stores (dest, x) : regno + HARD_REGNO_NREGS (regno, mode) - 1); int i; - for (i = regno; i <= last_reg; i++) - if (i < global_const_equiv_map_size) - global_const_equiv_map[i] = 0; + /* Ignore virtual stack var or virtual arg register since those + are handled separately. */ + if (regno != VIRTUAL_INCOMING_ARGS_REGNUM + && regno != VIRTUAL_STACK_VARS_REGNUM) + for (i = regno; i <= last_reg; i++) + if (i < global_const_equiv_map_size) + global_const_equiv_map[i] = 0; } } @@ -3197,6 +3247,8 @@ output_inline_function (fndecl) regno_reg_rtx = (rtx *) INLINE_REGNO_REG_RTX (head); regno_pointer_flag = INLINE_REGNO_POINTER_FLAG (head); regno_pointer_align = INLINE_REGNO_POINTER_ALIGN (head); + max_parm_reg = MAX_PARMREG (head); + parm_reg_stack_loc = (rtx *) PARMREG_STACK_LOC (head); stack_slot_list = STACK_SLOT_LIST (head); forced_labels = FORCED_LABELS (head); |