* integrate.c (allocate_initial_values): New function.
* integrate.h (allocate_initial_values): Declare.
* local-alloc.c (local_alloc): Move call to allocate_reg_info from
here...
* reload1.c (reload): And initialization of reg_equiv_memory_loc
from here...
* toplev.c (rest_of_compilation): To here.
Call allocate_initial_values.
* tm.texi: add description for ALLOCATE_INITIAL_VALUE.
From-SVN: r45716
+Fri Sep 21 01:13:56 2001 J"orn Rennecke <amylaar@redhat.com>
+
+ * integrate.c (allocate_initial_values): New function.
+ * integrate.h (allocate_initial_values): Declare.
+ * local-alloc.c (local_alloc): Move call to allocate_reg_info from
+ here...
+ * reload1.c (reload): And initialization of reg_equiv_memory_loc
+ from here...
+ * toplev.c (rest_of_compilation): To here.
+ Call allocate_initial_values.
+ * tm.texi: add description for ALLOCATE_INITIAL_VALUE.
+
Thu Sep 20 09:00:27 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* ggc-page.c (ggc_marked_p): Properly convert return to boolean.
filling of delay slots can result in branches being redirected, and this
may in turn cause a branch offset to overflow.
+@findex ALLOCATE_INITIAL_VALUE
+@item ALLOCATE_INITIAL_VALUE(@var{hard_reg})
+
+When the initial value of a hard register has been copied in a pseudo
+register, it is often not necessary to actually allocate a another register
+to this pseudo register, because the original hard register or a stack slot
+it has been saved into can be used. @code{ALLOCATE_INITIAL_VALUE}, if
+defined, is called at the start of register allocation once for each
+hard register that had its initial value copied by using
+@code{get_func_hard_reg_initial_val} or @code{get_hard_reg_initial_val}.
+Possible values are @code{NULL_RTX}, if you don't want
+to do any special allocation, a @code{REG} rtx---that would typically be
+the hard register itself, if it is known not to be clobbered---or a
+@code{MEM}.
+If you are returning a @code{MEM}, this is only a hint for the allocator;
+it might decide to use another register anyways.
+You may use @code{current_function_leaf_function} in the definition of the
+macro, functions that use @code{REG_N_SETS}, to determine if the hard
+register in question will not be clobbered.
+
@end table
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;
+{
+#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
+}
extern void mark_hard_reg_initial_vals PARAMS ((struct function *));
/* Called from rest_of_compilation. */
extern void emit_initial_value_sets PARAMS ((void));
+extern void allocate_initial_values PARAMS ((rtx *));
/* Copy a declaration when one function is substituted inline into
another. */
reg_offset = (char *) xmalloc (max_regno * sizeof (char));
reg_next_in_qty = (int *) xmalloc (max_regno * sizeof (int));
- /* Allocate the reg_renumber array. */
- allocate_reg_info (max_regno, FALSE, TRUE);
-
/* Determine which pseudo-registers can be allocated by local-alloc.
In general, these are the registers used only in a single block and
which only die once.
be substituted eventually by altering the REG-rtx's. */
reg_equiv_constant = (rtx *) xcalloc (max_regno, sizeof (rtx));
- reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
reg_equiv_mem = (rtx *) xcalloc (max_regno, sizeof (rtx));
reg_equiv_init = (rtx *) xcalloc (max_regno, sizeof (rtx));
reg_equiv_address = (rtx *) xcalloc (max_regno, sizeof (rtx));
if (! register_life_up_to_date)
recompute_reg_usage (insns, ! optimize_size);
+
+ /* Allocate the reg_renumber array. */
+ allocate_reg_info (max_regno, FALSE, TRUE);
+
+ /* And the reg_equiv_memory_loc array. */
+ reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
+
+ allocate_initial_values (reg_equiv_memory_loc);
+
regclass (insns, max_reg_num (), rtl_dump_file);
rebuild_label_notes_after_reload = local_alloc ();