[tree-ssa] Thoughts on live-on-entry variables

Andrew MacLeod amacleod@redhat.com
Mon Jun 16 18:02:00 GMT 2003


On Mon, 2003-06-16 at 12:18, Diego Novillo wrote:
> On Sat, 2003-06-14 at 05:07, Jan Hubicka wrote:
> 
> > In RTL we keep track of this by having pointer to the original register
> > (variable) it has been derrived from.  Would this satisfy your needs?
> >
> I'm not sure we are talking about the same thing, but we already have
> that.  If you have and SSA_NAME b_34, you know that the original
> VAR_DECL is 'b'.  We also know whether b_34 has been artificially
> created.
> 
> The request was to have the creation of b_34 be explicitly exposed in
> the IL.
> 

I for one want them explicitly exposed. It accomplishes a few things.

First, It makes it easier for the SSA->Normal pahse to figure out that a
parameter needs to be coalesced with an SSA name variable.

ie, today, we see:

void f(int a)
  int b = a + 2;

looks to tree-ssa like:

  b_2 = a_1 + 2;

THere is no definition of a_1, so I must coalesce anything which is live
on entry with it's real variable. That means I have to go looking for
them.  If first there were a copy of some sort, ie

  a_1 = a
  b_2 - a_1 + 2;

Then the only thing the Coalescer needs to work about is making sure
anything of the form 
  SSA_NAME = NON_SSA_NAME  
is coalesced.

Second, once these are exposed this way, we can do some bug-catching.
When  SSA->Normal finds something which is live on entry, but does not
have a copy of the above form (or whatever form we end up with), we can
flag it immediately. Some optimization has done something wrong and
introduced something with a DEF in the wrong part of the CFG or without
a DEF. We still find lots of these, and this would catch more of them.

Third, and finally, its a step towards being able to handle globals and
local statics.. Once we know what we have to copy in, we need to know
what to copy out at Calls and returns. Ideally, the reverse copy would
be true at all these places,

ie

int a;
void f()
{
  b = a;
  c = func(b)
  a = c + 2
  return
}
would look something like:

  a_1 = a
  b_2 = a_1
  a = a_1	/* Copy a_1 back to the global  */
  c_3 = func (b_2)
  a_4 = a       /* Copy the global into a new 'a'.  */
  a_5 = c_3 + 2;
  a = a_5;      /* Copy current a into global.  */
  return;

So some of these copies back and forth into the global could be
trivially eliminated, others eliminated by dead code, and presumably
most of them will coalesce back to 'a' in the SSA->Normal pass.

>From this example, you can see why we don't currently do globals what a
lot of gorp eh..., but its something we plan to examine eventually.

We need a mechanism to associate the current version of a variable with
the global storage so we can ensure the right value is in the correct
memory location when control is transferred.  You can, in theory, hunt
them down, but with overlapping live ranges and copy propagation, Im not
convinced you'd always be right. So In order to do this, I want to see
these things fully exposed in the IL, one way or another

We may not choose to use these forms of copies for the on-exit stuff,
but I do think we need it for the on-entry variables. There shouldn't be
very many of them, so it shouldn't be much of an impact.

Andrew

  



More information about the Gcc mailing list