[rs6000] Don't emit libcall notes around TLS address

Steven Bosscher stevenb@suse.de
Tue Jun 14 22:22:00 GMT 2005


On Tuesday 14 June 2005 21:59, Richard Henderson wrote:
> On Tue, Jun 14, 2005 at 12:16:58PM +0200, Steven Bosscher wrote:
> > IIUC this be done with a const builtin to turn it into something like
> >
> > int foo2 (void)
> > {
> >   int *t1 = builtin_get_tls_addr (a);
> >   bar (*t1);
> >   int *t2 = builtin_get_tls_addr (a);
> >   bar (*t2);
> >   int *t3 = builtin_get_tls_addr (a);
> >   bar (*t3);
> > }
> >
> > which PRE would turn into this:
> >
> > int foo2 (void)
> > {
> >   int *t1 = builtin_get_tls_addr (a);
>
> Yes, this could be done.  Though, really, I'm not sure a builtin buys
> us anything here over just treating the ADDR_EXPR specially.

I was trying to avoid special-casing this to avoid _EXPR nodes with 
special semantics as much as possible.  But in fact this

   int *t1 = builtin_get_tls_addr (a);

wouldn't even work because we can't pass a global variable as a function
argument, so it would have to be

   int *t1 = builtin_get_tls_addr (&a);

and you still need the ADDR_EXPR anyway.  So yes, just treating the
ADDR_EXPR specially may be better after all.  It's a bit fragile, as we
must teach the optimizers not to propagate them, etc.  I'll look at this
first, before the local-dynamic TLS stuff, which still has me pondering...


> > If so, would you have ideas for a similar trick for the local-dynamic
> > case?
>
> Well, you need to split the address into two parts, like it really is
> in practice.  A builtin with no arguments for the base plus a DTP_EXPR
> for the offset.

Right, I was first thinking about something with builtins again, e.g.

static __thread int c, d;
int foo3 (void)
{
  return c + d;
}

-->

static __thread int c, d;
int foo3 (void)
{
  void *t1;
  int *cp, *dp;
  t1 = builtin_tls_ld_base ();
  cp = builtin_tls_ld_addr (t1, c);
  dp = builtin_tls_ld_addr (t1, d);
  return *cp + *cd;
}

but this needs &c and &d again for the same reasons mentioned above.  On
the  other hand, I also don't like adding a new _EXPR node just for this
very specific case :-/  What would your DTP_EXPR look like (and what does
DTP stand for btw)?  I suppose you need the result of that builtin with no
arguments (my builtin_tls_ld_base) as an operand to the DTP_EXPR, to make
code motion for the builtin possible, and the address of the thread local
variable as a second operand.  What about the type of the result, always
(void *) followed by a cast to the proper type, i.e.

static __thread int c, d;
int foo3 (void)
{
  void *t1, *t2, *t3, *t4, *t5;
  int *cp, *dp;
  t1 = builtin_tls_ld_base ();
  t2 = (void *) &c;
  t3 = (void *) &d;
  t4 = DTP_EXPR<t1,t2>;
  t5 = DTP_EXPR<t1,t3>
  cp = (int *) t4;
  dp = (int *) t5;
  return *cp + *cd;
}

or did you have something completely different in mind?


> You'll want an EXPR not a builtin so that it can get 
> stuffed into TARGET_MEM_REF at some point.

I'm not sure how this would translate to a TARGET_MEM_REF.

It looks to me (so take this with a grain of salt ;-) that to allow the
tree optimizers to work on local-dynamic TLS variables, we really want
to keep 'em around as regular variables for as long as possible.  I'm not
sure how to do that yet.  A new pass for rewriting them somewhere in the
middle of the tree optimizations schedule doesn't sound very attractive
(inserting stores and such is hard :-/) but I'm not sure if we may lose
opportunities if we'd build those DTP_EXPRs already in the gimplifier...

Gr.
Steven



More information about the Gcc-patches mailing list