This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RETURN_ADDR_RTX / new target macro: ALLOCATE_INITIAL_VALUE
- To: gcc-patches at gcc dot gnu dot org
- Subject: Re: RETURN_ADDR_RTX / new target macro: ALLOCATE_INITIAL_VALUE
- From: Joern Rennecke <amylaar at redhat dot com>
- Date: Mon, 17 Sep 2001 09:56:30 +0100 (BST)
- Cc: amylaar at cambridge dot redhat dot com
Hmm, it just occured to me that we havt to guard against the - although
rather unlikely - possibility that the pseudo the hard reg had been copied
to has been changed by one of the optimizers to be set multiple times,
to different values.
So I've added a check for REG_N_SETS > 1 in allocate_initial_values.
Otherwise, this patch is unchanged.
Mon Sep 17 09:49:09 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.
Index: integrate.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/integrate.c,v
retrieving revision 1.160
diff -p -r1.160 integrate.c
*** integrate.c 2001/09/05 17:48:26 1.160
--- integrate.c 2001/09/17 08:49:19
*************** emit_initial_value_sets ()
*** 3036,3038 ****
--- 3036,3072 ----
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
+ }
Index: integrate.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/integrate.h,v
retrieving revision 1.20
diff -p -r1.20 integrate.h
*** integrate.h 2001/08/22 14:35:19 1.20
--- integrate.h 2001/09/17 08:49:20
*************** extern rtx has_hard_reg_initial_val PAR
*** 144,149 ****
--- 144,150 ----
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. */
Index: local-alloc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/local-alloc.c,v
retrieving revision 1.87
diff -p -r1.87 local-alloc.c
*** local-alloc.c 2001/09/05 15:32:12 1.87
--- local-alloc.c 2001/09/17 08:49:26
*************** local_alloc ()
*** 372,380 ****
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.
--- 372,377 ----
Index: reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.161
diff -p -r1.161 reload.c
*** reload.c 2001/09/07 22:19:05 1.161
--- reload.c 2001/09/17 08:49:42
*************** reg_overlap_mentioned_for_reload_p (x, i
*** 6128,6133 ****
--- 6128,6139 ----
else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
|| GET_CODE (x) == CC0)
return reg_mentioned_p (x, in);
+ else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_INC
+ || GET_CODE (x) == POST_DEC || GET_CODE (x) == PRE_DEC)
+ return refers_to_mem_for_reload_p (in);
+ else if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG && CONSTANT_P (XEXP (x, 1)))
+ return 0;
else
abort ();
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.291
diff -p -r1.291 reload1.c
*** reload1.c 2001/09/02 16:38:46 1.291
--- reload1.c 2001/09/17 08:50:05
*************** reload (first, global)
*** 733,739 ****
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));
--- 733,738 ----
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.510
diff -p -r1.510 toplev.c
*** toplev.c 2001/09/05 17:48:25 1.510
--- toplev.c 2001/09/17 08:50:19
*************** rest_of_compilation (decl)
*** 3398,3403 ****
--- 3398,3412 ----
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 ();
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.55
diff -p -r1.55 tm.texi
*** tm.texi 2001/08/30 20:44:51 1.55
--- tm.texi 2001/09/17 08:50:54
*************** On some targets, branches may have a lim
*** 8759,8762 ****
--- 8759,8781 ----
filling of delay slots can result in branches being redirected, and this
may in turn cause a branch offset to overflow.
+ @table @code
+ @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. 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 get_func_hard_reg_initial_val or
+ get_hard_reg_initial_val. Possible values are NULL_RTX, if you don't want
+ to do any special allocation, a REG rtx - that would typically be the hard
+ register itself, if it is known not to be clobbered - or a MEM.
+ If you are returning a MEM, this is only a hint for the allocator; it might
+ decide to use another register anyways.
+ You may use current_function_leaf_function in the definition of the macro,
+ functions that use REG_N_SETS, to determine if the hard register in question
+ will not be clobbered.
+
@end table