This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: RETURN_ADDR_RTX / new target macro: ALLOCATE_INITIAL_VALUE


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]