[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