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]
Other format: [Raw text]

alias.c patch for multi-reg hard registers


This showed up as a v850 PlumHall testsuite failure.

The testcase has RTL that loads r15 with the address of a SYMBOL_REF.  Later
in the function, we load a structure containing two pointers into the register
pair r14/r15, and then derefence r15.  At this point, the code in alias.c
still thinks that r15 holds a SYMBOL_REF address and it incorrectly decides
that two MEMs don't alias because of the MEM_IN_STRUCT_P rule.  This happened
in the second scheduling pass after reload.

We need to detect when we have multi-reg hard registers and handle them
appropriately.

I considered trying to fix the code to keep alias info for multi-reg hard
registers, in case we have targets with pointers larger than a register.
However, we need to handle both overlaps above and below, and this gets tricky.
If we load into r15/r16 first, and then r14/r15 later it is easy clobber the
info in r15.  If we load into r14/r15 first, and then r15/r16 later, then we
have to clobber backwards.  And we might have to go arbitrarily far backwards
for very large modes.  This is easier if we verify values when reading
reg_base_value.  E.g. if reg_base_value has a multi-reg mode, then we verify
that every register we are using has a valid value.  This results in a much
larger patch than I was willing to write for a simple problem, especially
considering that this is going to be rare, and I have no testcase that shows
it is useful.

So I just wrote a patch to force multi-reg hard registers to have unusable
values.

This was tested with v850 gcc, g++, and PlumHall testsuite runs, and an
i686-linux bootstrap.  I have more tests running just to be safe.

I will be offline for a week starting tomorrow because of the holidays.  If
I broke something, feel free to reverse my patch and I will deal with it when
I am back online.

2002-12-24  Jim Wilson  <wilson@redhat.com>

	* alias.c (record_set): Handle multi-reg hard registers.

Index: alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/alias.c,v
retrieving revision 1.182
diff -p -r1.182 alias.c
*** alias.c	16 Dec 2002 18:18:58 -0000	1.182
--- alias.c	24 Dec 2002 15:46:17 -0000
*************** record_set (dest, set, data)
*** 932,937 ****
--- 932,938 ----
  {
    unsigned regno;
    rtx src;
+   int n;
  
    if (GET_CODE (dest) != REG)
      return;
*************** record_set (dest, set, data)
*** 940,945 ****
--- 941,962 ----
  
    if (regno >= reg_base_value_size)
      abort ();
+ 
+   /* If this spans multiple hard registers, then we must indicate that every
+      register has an unusable value.  */
+   if (regno < FIRST_PSEUDO_REGISTER)
+     n = HARD_REGNO_NREGS (regno, GET_MODE (dest));
+   else
+     n = 1;
+   if (n != 1)
+     {
+       while (--n >= 0)
+ 	{
+ 	  reg_seen[regno + n] = 1;
+ 	  new_reg_base_value[regno + n] = 0;
+ 	}
+       return;
+     }
  
    if (set)
      {


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