+ write_symbols = old_write_symbols;
+ debug_hooks = old_debug_hooks;
+}
+
+\f
+/* Functions to keep track of the values hard regs had at the start of
+ the function. */
+
+rtx
+has_func_hard_reg_initial_val (fun, reg)
+ 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;
+}
+
+rtx
+get_func_hard_reg_initial_val (fun, reg)
+ struct function *fun;
+ rtx reg;
+{
+ struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
+ rtx rv = has_func_hard_reg_initial_val (fun, reg);
+
+ if (rv)
+ return rv;
+
+ if (ivs == 0)
+ {
+ fun->hard_reg_initial_vals = (void *) xmalloc (sizeof (initial_value_struct));
+ ivs = fun->hard_reg_initial_vals;
+ ivs->num_entries = 0;
+ ivs->max_entries = 5;
+ ivs->entries = (initial_value_pair *) xmalloc (5 * sizeof (initial_value_pair));
+ }
+
+ if (ivs->num_entries >= ivs->max_entries)
+ {
+ ivs->max_entries += 5;
+ ivs->entries =
+ (initial_value_pair *) xrealloc (ivs->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));
+
+ return ivs->entries[ivs->num_entries++].pseudo;
+}
+
+rtx
+get_hard_reg_initial_val (mode, regno)
+ enum machine_mode mode;
+ int regno;
+{
+ return get_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
+}
+
+rtx
+has_hard_reg_initial_val (mode, regno)
+ enum machine_mode mode;
+ int regno;
+{
+ return has_func_hard_reg_initial_val (cfun, gen_rtx_REG (mode, regno));
+}
+
+void
+mark_hard_reg_initial_vals (fun)
+ struct function *fun;
+{
+ struct initial_value_struct *ivs = fun->hard_reg_initial_vals;
+ int i;
+
+ if (ivs == 0)
+ return;
+
+ for (i = 0; i < ivs->num_entries; i ++)
+ {
+ ggc_mark_rtx (ivs->entries[i].hard_reg);
+ ggc_mark_rtx (ivs->entries[i].pseudo);
+ }
+}
+
+static void
+setup_initial_hard_reg_value_integration (inl_f, remap)
+ struct function *inl_f;
+ struct inline_remap *remap;
+{
+ struct initial_value_struct *ivs = inl_f->hard_reg_initial_vals;
+ int i;
+
+ if (ivs == 0)
+ return;
+
+ for (i = 0; i < ivs->num_entries; i ++)
+ remap->reg_map[REGNO (ivs->entries[i].pseudo)]
+ = get_func_hard_reg_initial_val (cfun, ivs->entries[i].hard_reg);
+}
+
+
+void
+emit_initial_value_sets ()
+{
+ struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
+ int i;
+ rtx seq;
+
+ if (ivs == 0)
+ return;
+
+ start_sequence ();
+ for (i = 0; i < ivs->num_entries; i++)
+ emit_move_insn (ivs->entries[i].pseudo, ivs->entries[i].hard_reg);
+ seq = get_insns ();
+ end_sequence ();
+
+ emit_insns_after (seq, get_insns ());
+}
+
+/* If the backend knows where to allocate pseudos for hard
+ register initial values, register these allocations now. */
+void
+allocate_initial_values (reg_equiv_memory_loc)
+ rtx *reg_equiv_memory_loc ATTRIBUTE_UNUSED;
+{
+#ifdef ALLOCATE_INITIAL_VALUE
+ struct initial_value_struct *ivs = cfun->hard_reg_initial_vals;
+ int i;
+
+ if (ivs == 0)
+ return;
+
+ for (i = 0; i < ivs->num_entries; i++)
+ {
+ int regno = REGNO (ivs->entries[i].pseudo);
+ rtx x = ALLOCATE_INITIAL_VALUE (ivs->entries[i].hard_reg);
+
+ if (x == NULL_RTX || REG_N_SETS (REGNO (ivs->entries[i].pseudo)) > 1)
+ ; /* Do nothing. */
+ else if (GET_CODE (x) == MEM)
+ reg_equiv_memory_loc[regno] = x;
+ else if (GET_CODE (x) == REG)
+ {
+ reg_renumber[regno] = REGNO (x);
+ /* Poke the regno right into regno_reg_rtx
+ so that even fixed regs are accepted. */
+ REGNO (ivs->entries[i].pseudo) = REGNO (x);
+ }
+ else abort ();
+ }
+#endif