/* Procedure integration for GNU CC.
- Copyright (C) 1988, 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+ Copyright (C) 1988, 91, 93, 94, 95, 1996 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
static rtx copy_for_inline PROTO((rtx));
static void integrate_parm_decls PROTO((tree, struct inline_remap *, rtvec));
static void integrate_decl_tree PROTO((tree, int, struct inline_remap *));
+static void save_constants_in_decl_trees PROTO ((tree));
static void subst_constants PROTO((rtx *, rtx, struct inline_remap *));
static void restore_constants PROTO((rtx *));
static void set_block_origin_self PROTO((tree));
int max_uid;
rtx first_nonparm_insn;
char *new, *new1;
- rtx *new2;
/* Make and emit a return-label if we have not already done so.
- Do this before recording the bounds on label numbers. */
+ Do this before recording the bounds on label numbers. */
if (return_label == 0)
{
save_constants (®_NOTES (insn));
}
+ /* Also scan all decls, and replace any constant pool references with the
+ actual constant. */
+ save_constants_in_decl_trees (DECL_INITIAL (fndecl));
+
/* Clear out the constant pool so that we can recreate it with the
copied constants below. */
init_const_rtx_hash_table ();
Make these new rtx's now, and install them in regno_reg_rtx, so they
will be the official pseudo-reg rtx's for the rest of compilation. */
- reg_map = (rtx *) alloca ((max_reg + 1) * sizeof (rtx));
+ reg_map = (rtx *) savealloc (regno_pointer_flag_length * sizeof (rtx));
len = sizeof (struct rtx_def) + (GET_RTX_LENGTH (REG) - 1) * sizeof (rtunion);
for (i = max_reg - 1; i > LAST_VIRTUAL_REGISTER; i--)
reg_map[i] = (rtx)obstack_copy (function_maybepermanent_obstack,
regno_reg_rtx[i], len);
- bcopy ((char *) (reg_map + LAST_VIRTUAL_REGISTER + 1),
- (char *) (regno_reg_rtx + LAST_VIRTUAL_REGISTER + 1),
- (max_reg - (LAST_VIRTUAL_REGISTER + 1)) * sizeof (rtx));
+ regno_reg_rtx = reg_map;
+
+ /* Put copies of all the virtual register rtx into the new regno_reg_rtx. */
+ regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
+ regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
+ regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
+ regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
/* Likewise each label rtx must have a unique rtx as its copy. */
bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
new1 = (char *) savealloc (regno_pointer_flag_length);
bcopy (regno_pointer_align, new1, regno_pointer_flag_length);
- new2 = (rtx *) savealloc (regno_pointer_flag_length * sizeof (rtx));
- bcopy ((char *) regno_reg_rtx, (char *) new2,
- regno_pointer_flag_length * sizeof (rtx));
regno_pointer_flag = new;
regno_pointer_align = new1;
- regno_reg_rtx = new2;
set_new_first_and_last_insn (first_insn, last_insn);
}
}
}
+ /* Also scan all decls, and replace any constant pool references with the
+ actual constant. */
+ save_constants_in_decl_trees (DECL_INITIAL (fndecl));
+
/* We have now allocated all that needs to be allocated permanently
on the rtx obstack. Set our high-water mark, so that we
can free the rest of this when the time comes. */
/* If they are block mode, the types should match exactly.
They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
which could happen if the parameter has incomplete type. */
- || (mode == BLKmode && TREE_TYPE (arg) != TREE_TYPE (formal)))
+ || (mode == BLKmode
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (arg))
+ != TYPE_MAIN_VARIANT (TREE_TYPE (formal)))))
return (rtx) (HOST_WIDE_INT) -1;
}
that flag set if it is a register.
Also, don't allow hard registers here; they might not be valid
- when substituted into insns. */
+ when substituted into insns. */
if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
|| (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
that flag set if it is a register.
Also, don't allow hard registers here; they might not be valid
- when substituted into insns. */
+ when substituted into insns. */
rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
if (GET_CODE (XEXP (loc, 0)) == REG)
{
- temp = force_reg (Pmode, structure_value_addr);
+ temp = force_reg (Pmode,
+ 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) == PLUS
}
}
}
+
+/* Given a BLOCK node LET, search for all DECL_RTL fields, and pass them
+ through save_constants. */
+
+static void
+save_constants_in_decl_trees (let)
+ tree let;
+{
+ tree t;
+
+ for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
+ if (DECL_RTL (t) != 0)
+ save_constants (&DECL_RTL (t));
+
+ for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
+ save_constants_in_decl_trees (t);
+}
\f
/* Create a new copy of an rtx.
Recursively copies the operands of the rtx,
else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
{
/* Do the same for a block to contain any arguments referenced
- in memory. */
+ in memory. */
rtx loc, seq;
int size = FUNCTION_ARGS_SIZE (DECL_SAVED_INSNS (map->fndecl));
loc = XEXP (loc, 0);
/* When arguments grow downward, the virtual incoming
args pointer points to the top of the argument block,
- so the remapped location better do the same. */
+ so the remapped location better do the same. */
#ifdef ARGS_GROW_DOWNWARD
loc = plus_constant (loc, size);
#endif
will not have valid reg_map entries. This can cause try_constants()
to fail because assumes that all registers in the rtx have valid
reg_map entries, and it may end up replacing one of these new
- registers with junk. */
+ registers with junk. */
if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));