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
next prev parent 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).