public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Zack Weinberg <zack@rabi.columbia.edu>
To: law@cygnus.com
Cc: Joern Rennecke <amylaar@cygnus.co.uk>, egcs@egcs.cygnus.com
Subject: Re: a strange infelicity of register allocation
Date: Wed, 27 Jan 1999 09:26:00 -0000	[thread overview]
Message-ID: <199901271725.MAA20390@blastula.phys.columbia.edu> (raw)
In-Reply-To: <21653.917355321@hurl.cygnus.com>

On Tue, 26 Jan 1999 05:55:21 -0700, Jeffrey A Law wrote:
>  > >The next step is to find out what registers are used by the
>  > >entries on the conflict list.  In the .greg file there should be
>  > >something like this:
>  > >
>  > >;; Register dispositions:
>  > >94 in 5  96 in 7  97 in 20  98 in 5  99 in 4  100 in 9
>  > >102 in 13  104 in 14  106 in 15  108 in 16  110 in 31  112 in 22
>  > >[ ... ]
>  > 
>  > 23 in 0  27 in 4  28 in 3  32 in 1  40 in 0  42 in 3  
>  > 43 in 5  46 in 0  49 in 0  57 in 5  64 in 0  70 in 0  
>  > 75 in 0  79 in 0  80 in 0  85 in 0  94 in 0  
>  > 
>  > which is strange: hard register 2 (ecx) isn't used for anything.  What
>  > would cause that?
>Check and see if there are any "Spilling reg 2." messages.  I bet you'll find
>one for an insn over which pseudo 30 is live.

Nope.  No spills of reg 2 anywhere.

>As you mentioned, it might be worth doing a manual live range split so that
>reg 44 can get allocated into a hard register rather than a stack slot.
>
>It's interesting to note that pseudos 27 and 32 are the only registers
>allocated to hard registers 4 and 1 respectively.  Presumably they have long
>lifetimes (which makes them conflict with everything) and high usage counts
>which gives them a high priority.
>
>It would be interesting to know what user variables those pseudos correspond
>to (or temporary expressions if they aren't a user variable).  They may be
>candidates for splitting too.  It would also be interesting to relate them
>back to the source to see if their weighted counts make any sense.

Pseudo 27 was the input buffer pointer, which deserved a permanent
register.  Pseudo 32 was `count', a variable used heavily in the outer
loop but not anywhere in the inner loop - code like this:

for (;;)
{
  count = read (...);
  if (count < 0) goto error;
  else if (count == 0) break;
  offset += count;
  ip = ibase;
  ip[count] = '\0';
  if (offset > limit) { /* grow output buffer */ }

  while ((c = *ip++) != '\0')
    switch (c)
    {
      /* count not used anywhere in here */
    }
}

I put a block around the real useful range of `count' and declared it
there, and it now shares reg 1 with pseudo 96 which appears to be a
pointer to the `cpp_options' structure.

That, plus inventing a variable to use instead of `c' inside the
switch, and adjusting some branches to go straight to their final
destinations, has fixed up the allocation pretty well.

;; Register dispositions:
23 in 0  27 in 4  28 in 3  29 in 5  35 in 1  40 in 0  
42 in 3  43 in 5  44 in 2  46 in 0  49 in 0  58 in 0  
65 in 0  76 in 0  80 in 0  81 in 0  86 in 0  96 in 1  
;; Hard regs used:  0 1 2 3 4 5 6 7 16

Reg 76 used to be reg 75.  Reg 44 now gets a hard register, and we're
using all the registers again.  The invented variable, which is reg
56, does not get a hard register - that's unfortunate but not nearly
as bad.  I think it's because the code that uses reg 56 looks like
this:

	case '?':
	if (opts->trigraphs || opts->warn_trigraphs)
	{
	  char d;
	  ... stuff involving d but not c ...
	}
	else
	   *op++ = c;
	break;

It would need to realize that c is dead if the conditional is true.
That's live-range-splitting again, yes?

The failure to recognize that `count' is only live in the outer part
of the loop concerns me.  We do have live range *trimming*, don't we?
If so, why doesn't it work here?

So yes, this code benefits considerably from live range splitting.  I
am not sure about the use-count issue, I'd have to stare a lot more.
Another place this code could win is if local register allocation
could handle a block like this itself:

{
  int x = read(...)
  if (x < 0)
    goto error;
  else if (x == 0)
    goto eof;
 
   /* do stuff with x here */
}

I think this is what you meant by `extended basic blocks' ?  There are
a bunch of cases like this.

zw

WARNING: multiple messages have this Message-ID
From: Zack Weinberg <zack@rabi.columbia.edu>
To: law@cygnus.com
Cc: Joern Rennecke <amylaar@cygnus.co.uk>, egcs@egcs.cygnus.com
Subject: Re: a strange infelicity of register allocation
Date: Sun, 31 Jan 1999 23:58:00 -0000	[thread overview]
Message-ID: <199901271725.MAA20390@blastula.phys.columbia.edu> (raw)
Message-ID: <19990131235800.ve0QcuBIIDarvKOgRqKoG3d4GK-M4cFxITHXXkfa1Z8@z> (raw)
In-Reply-To: <21653.917355321@hurl.cygnus.com>

On Tue, 26 Jan 1999 05:55:21 -0700, Jeffrey A Law wrote:
>  > >The next step is to find out what registers are used by the
>  > >entries on the conflict list.  In the .greg file there should be
>  > >something like this:
>  > >
>  > >;; Register dispositions:
>  > >94 in 5  96 in 7  97 in 20  98 in 5  99 in 4  100 in 9
>  > >102 in 13  104 in 14  106 in 15  108 in 16  110 in 31  112 in 22
>  > >[ ... ]
>  > 
>  > 23 in 0  27 in 4  28 in 3  32 in 1  40 in 0  42 in 3  
>  > 43 in 5  46 in 0  49 in 0  57 in 5  64 in 0  70 in 0  
>  > 75 in 0  79 in 0  80 in 0  85 in 0  94 in 0  
>  > 
>  > which is strange: hard register 2 (ecx) isn't used for anything.  What
>  > would cause that?
>Check and see if there are any "Spilling reg 2." messages.  I bet you'll find
>one for an insn over which pseudo 30 is live.

Nope.  No spills of reg 2 anywhere.

>As you mentioned, it might be worth doing a manual live range split so that
>reg 44 can get allocated into a hard register rather than a stack slot.
>
>It's interesting to note that pseudos 27 and 32 are the only registers
>allocated to hard registers 4 and 1 respectively.  Presumably they have long
>lifetimes (which makes them conflict with everything) and high usage counts
>which gives them a high priority.
>
>It would be interesting to know what user variables those pseudos correspond
>to (or temporary expressions if they aren't a user variable).  They may be
>candidates for splitting too.  It would also be interesting to relate them
>back to the source to see if their weighted counts make any sense.

Pseudo 27 was the input buffer pointer, which deserved a permanent
register.  Pseudo 32 was `count', a variable used heavily in the outer
loop but not anywhere in the inner loop - code like this:

for (;;)
{
  count = read (...);
  if (count < 0) goto error;
  else if (count == 0) break;
  offset += count;
  ip = ibase;
  ip[count] = '\0';
  if (offset > limit) { /* grow output buffer */ }

  while ((c = *ip++) != '\0')
    switch (c)
    {
      /* count not used anywhere in here */
    }
}

I put a block around the real useful range of `count' and declared it
there, and it now shares reg 1 with pseudo 96 which appears to be a
pointer to the `cpp_options' structure.

That, plus inventing a variable to use instead of `c' inside the
switch, and adjusting some branches to go straight to their final
destinations, has fixed up the allocation pretty well.

;; Register dispositions:
23 in 0  27 in 4  28 in 3  29 in 5  35 in 1  40 in 0  
42 in 3  43 in 5  44 in 2  46 in 0  49 in 0  58 in 0  
65 in 0  76 in 0  80 in 0  81 in 0  86 in 0  96 in 1  
;; Hard regs used:  0 1 2 3 4 5 6 7 16

Reg 76 used to be reg 75.  Reg 44 now gets a hard register, and we're
using all the registers again.  The invented variable, which is reg
56, does not get a hard register - that's unfortunate but not nearly
as bad.  I think it's because the code that uses reg 56 looks like
this:

	case '?':
	if (opts->trigraphs || opts->warn_trigraphs)
	{
	  char d;
	  ... stuff involving d but not c ...
	}
	else
	   *op++ = c;
	break;

It would need to realize that c is dead if the conditional is true.
That's live-range-splitting again, yes?

The failure to recognize that `count' is only live in the outer part
of the loop concerns me.  We do have live range *trimming*, don't we?
If so, why doesn't it work here?

So yes, this code benefits considerably from live range splitting.  I
am not sure about the use-count issue, I'd have to stare a lot more.
Another place this code could win is if local register allocation
could handle a block like this itself:

{
  int x = read(...)
  if (x < 0)
    goto error;
  else if (x == 0)
    goto eof;
 
   /* do stuff with x here */
}

I think this is what you meant by `extended basic blocks' ?  There are
a bunch of cases like this.

zw

  reply	other threads:[~1999-01-27  9:26 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-01-23 22:42 Zack Weinberg
1999-01-25  4:56 ` Joern Rennecke
1999-01-25 11:47   ` Zack Weinberg
1999-01-25 11:50     ` Joern Rennecke
1999-01-31 23:58       ` Joern Rennecke
1999-01-25 12:00     ` Jeffrey A Law
1999-01-25 13:14       ` John S. Dyson
1999-01-31 23:58         ` John S. Dyson
1999-01-25 13:31       ` Zack Weinberg
1999-01-25 13:36         ` Jeffrey A Law
1999-01-25 19:56           ` Zack Weinberg
1999-01-25 20:33             ` Jeffrey A Law
1999-01-25 20:41               ` Zack Weinberg
1999-01-25 20:53                 ` Jeffrey A Law
1999-01-25 21:18                   ` Zack Weinberg
1999-01-25 21:30                     ` Jeffrey A Law
1999-01-25 21:38                       ` Zack Weinberg
1999-01-26  4:59                         ` Jeffrey A Law
1999-01-27  9:26                           ` Zack Weinberg [this message]
1999-01-28  5:26                             ` Jeffrey A Law
1999-01-28 17:20                               ` Zack Weinberg
1999-01-28 17:33                                 ` Joern Rennecke
1999-01-28 18:01                                 ` Jeffrey A Law
1999-01-28 18:27                                   ` Zack Weinberg
1999-01-28 19:58                                     ` Jeffrey A Law
1999-01-31 23:58                               ` Jeffrey A Law
1999-01-31 23:58                             ` Zack Weinberg
1999-01-31 23:58                           ` Jeffrey A Law
1999-01-31 23:58                         ` Zack Weinberg
1999-01-31 23:58                       ` Jeffrey A Law
1999-01-31 23:58                     ` Zack Weinberg
1999-01-31 23:58                   ` Jeffrey A Law
1999-01-31 23:58                 ` Zack Weinberg
1999-01-31 23:58               ` Jeffrey A Law
1999-01-31 23:58             ` Zack Weinberg
1999-01-31 23:58           ` Jeffrey A Law
1999-01-26  7:44         ` Joern Rennecke
1999-01-27  8:35           ` Zack Weinberg
1999-01-27  9:08             ` Joern Rennecke
1999-01-27  9:52               ` Zack Weinberg
1999-01-27 11:49                 ` Marc Espie
1999-01-31 23:58                   ` Marc Espie
1999-01-31 23:58                 ` Zack Weinberg
1999-01-31 23:58               ` Joern Rennecke
1999-01-28  8:11             ` Jeffrey A Law
1999-01-28 11:40               ` Zack Weinberg
1999-01-31 23:58               ` Jeffrey A Law
1999-01-31 23:58             ` Zack Weinberg
1999-01-31 23:58           ` Joern Rennecke
1999-01-31 23:58         ` Zack Weinberg
1999-01-31 23:58       ` Jeffrey A Law
1999-01-31 23:58     ` Zack Weinberg
1999-01-31 23:58   ` Joern Rennecke
1999-01-31 23:58 ` Zack Weinberg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199901271725.MAA20390@blastula.phys.columbia.edu \
    --to=zack@rabi.columbia.edu \
    --cc=amylaar@cygnus.co.uk \
    --cc=egcs@egcs.cygnus.com \
    --cc=law@cygnus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).