/* Procedure integration for GCC.
Copyright (C) 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GCC.
#define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
\f
-/* Private type used by {get/has}_func_hard_reg_initial_val. */
+/* Private type used by {get/has}_hard_reg_initial_val. */
typedef struct initial_value_pair GTY(()) {
rtx hard_reg;
rtx pseudo;
if (TREE_CODE (copy) == LABEL_DECL)
{
TREE_ADDRESSABLE (copy) = 0;
+ LABEL_DECL_UID (copy) = -1;
}
}
return NULL_RTX;
}
-static rtx
-has_func_hard_reg_initial_val (struct function *fun, rtx reg)
-{
- struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
- int i;
-
- if (ivs == 0)
- return NULL_RTX;
-
- for (i = 0; i < ivs->num_entries; i++)
- if (rtx_equal_p (ivs->entries[i].hard_reg, reg))
- return ivs->entries[i].pseudo;
-
- return NULL_RTX;
-}
+/* Make sure that there's a pseudo register of mode MODE that stores the
+ initial value of hard register REGNO. Return an rtx for such a pseudo. */
-static rtx
-get_func_hard_reg_initial_val (struct function *fun, rtx reg)
+rtx
+get_hard_reg_initial_val (enum machine_mode mode, unsigned int regno)
{
- struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
- rtx rv = has_func_hard_reg_initial_val (fun, reg);
+ struct initial_value_struct *ivs;
+ rtx rv;
+ rv = has_hard_reg_initial_val (mode, regno);
if (rv)
return rv;
+ ivs = cfun->hard_reg_initial_vals;
if (ivs == 0)
{
- fun->hard_reg_initial_vals = ggc_alloc (sizeof (initial_value_struct));
- ivs = fun->hard_reg_initial_vals;
+ ivs = ggc_alloc (sizeof (initial_value_struct));
ivs->num_entries = 0;
ivs->max_entries = 5;
ivs->entries = ggc_alloc (5 * sizeof (initial_value_pair));
+ cfun->hard_reg_initial_vals = ivs;
}
if (ivs->num_entries >= ivs->max_entries)
* sizeof (initial_value_pair));
}
- ivs->entries[ivs->num_entries].hard_reg = reg;
- ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (GET_MODE (reg));
+ ivs->entries[ivs->num_entries].hard_reg = gen_rtx_REG (mode, regno);
+ ivs->entries[ivs->num_entries].pseudo = gen_reg_rtx (mode);
return ivs->entries[ivs->num_entries++].pseudo;
}
-rtx
-get_hard_reg_initial_val (enum machine_mode mode, int regno)
-{
- return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
-}
+/* See if get_hard_reg_initial_val has been used to create a pseudo
+ for the initial value of hard register REGNO in mode MODE. Return
+ the associated pseudo if so, otherwise return NULL. */
rtx
-has_hard_reg_initial_val (enum machine_mode mode, int regno)
+has_hard_reg_initial_val (enum machine_mode mode, unsigned int regno)
{
- return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
+ struct initial_value_struct *ivs;
+ int i;
+
+ ivs = cfun->hard_reg_initial_vals;
+ if (ivs != 0)
+ for (i = 0; i < ivs->num_entries; i++)
+ if (GET_MODE (ivs->entries[i].hard_reg) == mode
+ && REGNO (ivs->entries[i].hard_reg) == regno)
+ return ivs->entries[i].pseudo;
+
+ return NULL_RTX;
}
void
reg_equiv_memory_loc[regno] = x;
else
{
+ basic_block bb;
+ int new_regno;
+
gcc_assert (REG_P (x));
- reg_renumber[regno] = REGNO (x);
+ new_regno = REGNO (x);
+ reg_renumber[regno] = new_regno;
/* Poke the regno right into regno_reg_rtx so that even
fixed regs are accepted. */
- REGNO (ivs->entries[i].pseudo) = REGNO (x);
+ REGNO (ivs->entries[i].pseudo) = new_regno;
+ /* Update global register liveness information. */
+ FOR_EACH_BB (bb)
+ {
+ if (REGNO_REG_SET_P(bb->global_live_at_start, regno))
+ SET_REGNO_REG_SET (bb->global_live_at_start, new_regno);
+ if (REGNO_REG_SET_P(bb->global_live_at_end, regno))
+ SET_REGNO_REG_SET (bb->global_live_at_end, new_regno);
+ }
}
}
}