public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFC] Problem with EH regs in global register allocation
@ 2007-12-13 18:27 Andreas Krebbel
  2007-12-14  9:41 ` Michael Matz
  0 siblings, 1 reply; 2+ messages in thread
From: Andreas Krebbel @ 2007-12-13 18:27 UTC (permalink / raw)
  To: gcc-patches; +Cc: matz

Hello,

on s390x I currently see a failure of the hash_data_map_rand testcase
of the libstdc++ testsuite when compiling with -march=z9-ec.

It looks to be related to greg not handling eh regs properly.

Last year I've added a piece of code to global_conflicts in order to
record conflicts between the eh regs and any live pseudo for basic
blocks with an eh edge:
http://gcc.gnu.org/ml/gcc-patches/2006-09/msg00399.html

These conflicts are properly recorded also for that testcase.  I see
in the greg dump (on s390 r6, r7, r8 and r9 are used for eh):

...
roc adding 46<=>9

and also the dump done later in greg confirms this:

;; 46 conflicts: 47 50 51 48 137 52 59 60 61 62 79 143 142 99 84 104
102 101 89 86 159 90 110 106 103 83 72 70 71 44 68 66 67 43 75 65 63
78 129 128 157 5 4 53 0 1 2 3 4 5 6 7 8 9 10 12 14 16 17 18 19 20 21
22 23

but unfortunately the code in find_reg (global.c:1187) starting with:


/* If we haven't succeeded yet,
     see if some hard reg that conflicts with us
     was utilized poorly by local-alloc.
     If so, kick out the regs that were put there by local-alloc
     so we can use it instead.  */
  if (best_reg < 0 && !retrying
      /* Let's not bother with multi-reg allocnos.  */
      && allocno[num].size == 1
      && REG_BASIC_BLOCK (allocno[num].reg) == REG_BLOCK_GLOBAL)
    {
	...

finds out that r9 would be the best choice for r46 and reassigns r9 to
r46 assuming that all former users of r9 can be referred to a stack
slot:

Regno 9 better for global 46...


But this is of course not possible if r9 is set on an eh edge.


As a quick hack I've tried the attached patch which seems to fix the
problem.  But this is overly pessimistic since we should only avoid
using the hard reg if it is really used on an eh edge.

Unfortunately the information that the conflict with the hard reg was
added due to its use on an eh edge is lost.  In find_reg we only have
the hard_reg_conflicts bitmap which doesn't tell us anything about the
reason of the conflict.

Any suggestions?

Bye,

-Andreas-


Index: gcc/global.c
===================================================================
*** gcc/global.c.orig	2007-11-21 10:49:17.000000000 +0100
--- gcc/global.c	2007-12-13 19:10:45.000000000 +0100
*************** along with GCC; see the file COPYING3.  
*** 42,47 ****
--- 42,48 ----
  #include "vecprim.h"
  #include "dbgcnt.h"
  #include "ra.h"
+ #include "except.h"
  
  /* This pass of the compiler performs global register allocation.
     It assigns hard register numbers to all the pseudo registers
*************** find_reg (int num, HARD_REG_SET losers, 
*** 1202,1207 ****
--- 1203,1220 ----
  	  int regno = i;
  #endif
  
+ #ifdef EH_RETURN_DATA_REGNO
+ 	  if (current_function_has_exception_handlers ())
+ 	    {
+ 	      bool is_eh_reg = false;
+ 	      unsigned int j;
+ 	      for (j = 0; EH_RETURN_DATA_REGNO (j) != INVALID_REGNUM; j++)
+ 		if (EH_RETURN_DATA_REGNO (j) == (unsigned int)regno)
+ 		  is_eh_reg = true;
+ 	      if (is_eh_reg)
+ 		continue;
+ 	    }
+ #endif
  	  if (local_reg_n_refs[regno] != 0
  	      /* Don't use a reg no good for this pseudo.  */
  	      && ! TEST_HARD_REG_BIT (used2, regno)

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [RFC] Problem with EH regs in global register allocation
  2007-12-13 18:27 [RFC] Problem with EH regs in global register allocation Andreas Krebbel
@ 2007-12-14  9:41 ` Michael Matz
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Matz @ 2007-12-14  9:41 UTC (permalink / raw)
  To: Andreas Krebbel; +Cc: gcc-patches

Hi,

On Thu, 13 Dec 2007, Andreas Krebbel wrote:

> /* If we haven't succeeded yet,
>      see if some hard reg that conflicts with us
>      was utilized poorly by local-alloc.
>      If so, kick out the regs that were put there by local-alloc
>      so we can use it instead.  */
>   if (best_reg < 0 && !retrying
>       /* Let's not bother with multi-reg allocnos.  */
>       && allocno[num].size == 1
>       && REG_BASIC_BLOCK (allocno[num].reg) == REG_BLOCK_GLOBAL)
>     {
> 	...
> 
> finds out that r9 would be the best choice for r46 and reassigns r9 to 
> r46

Blaeh.  There's a similar problem with stack regs on x86.  At that time we 
solved it by adding a new field to struct allocno.  I would do that here 
too.  Make it a bitfield, and add a new bit for no_eh_regs to not enlarge 
the structure too much.

You can then use this in find_reg to either initialize used1 before it's 
copied to used2 (the hardreg set of unusable registers), or explicitely 
test it only in reuse-local-regs loop.


Ciao,
Michael.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-12-14  9:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-13 18:27 [RFC] Problem with EH regs in global register allocation Andreas Krebbel
2007-12-14  9:41 ` Michael Matz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).