summaryrefslogtreecommitdiff
path: root/gcc/integrate.c
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1997-11-02 14:19:36 -0700
committerJeff Law <law@gcc.gnu.org>1997-11-02 14:19:36 -0700
commite9a25f70a0a7b82881b56cb3dfa7422b2968682a (patch)
tree46fe768360493f03f7282d07762e7b26c292aabd /gcc/integrate.c
parentbb84e66919817020267815eed4304e543688e722 (diff)
downloadgcc-e9a25f70a0a7b82881b56cb3dfa7422b2968682a.tar.gz
Update mainline egcs to gcc2 snapshot 971021.
From-SVN: r16278
Diffstat (limited to 'gcc/integrate.c')
-rw-r--r--gcc/integrate.c82
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);