[llvm-commits] [llvm] r66922 - in /llvm/trunk: lib/Target/X86/X86InstrInfo.td test/CodeGen/X86/tls13.ll test/CodeGen/X86/tls14.ll

Dan Gohman gohman at apple.com
Thu Apr 2 15:00:37 PDT 2009


On Apr 2, 2009, at 1:46 PM, Rafael Espindola wrote:

>> I agree with your analysis. It looks like too much complexity to  
>> handle
>> in Select. This is something X86ISelLowering should handle.
>>
>> I think Chris' interest is to have a single place where TLS is  
>> lowered
>> to segment register usage, with the particular place being less
>> important. This can be accomplished with the approach you describe
>> only with THREAD_POINTER renamed to GET_GS, so that it's clear that
>> Lowering has fully lowered the TLS addressing.
>
> The problem is that gs is not the same as THREAD_POINTER. The content
> in gs:0 is.
>
> The attached patch is correct, but has some generated code performance
> regressions. What it does is
>
> *) LowerToTLSExecModel lowers a thread local address to (add
> THREAD_POINTER, offset) (for local exec)
> *) THREAD_POINTER is selected to mov %gs:0,
>
> The problem is that this produces
>
> movl	%gs:0, %eax
> movl	i at NTPOFF(%eax), %eax
>
> Instead of
>
> movl	%gs:i at NTPOFF, %eax}
>
> I can try to fold the instructions, but the optimization is
> only valid because the GNU TLS model requires
> that the value in gs:0 be its own address.
>
> The other option is to in LowerToTLSExecModel produce a
> SegmentAddress node. The problem now is when we just
> want to compute the address, not load from it. Since LEA
> doesn't use segments, we would have to select
> SegmentAddress(address, GS) into
>
> mov gs:0, eax
> leal address(%eax), %eax
>
> This again depends on the GNU TLS model. In both cases
> (using THREAD_POINTER or SegmentAddress) both
> lowering and selection have to be aware of the TLS model.
>
> If using SegmentAddress, another interesting case will be
>
> int __thread a;
> int __thread b;
> void f(int **c, int **d)
> {
>  *c = &a;
>  *d = &b;
> }
>
> In this case we will select
>
> mov %gs:0, eax
> leal address_a(%eax), %eax
> ....
> mov %gs:0, eax
> leal address_b(%eax), %eax
>
> Will we automatically remove the second
> "mov %gs:0, %eax" and use the value from the first one?
>
> So what strategy do you suggest?
>
> 1) Remove THREAD_POINTER and add a SegmentAddress
> 2) Keep THREAD_POINTER and try to figure out how to fold
> "mov gs:0, eax" into (for example)
> "movl i at NTPOFF(%eax), %eax"?

Ok, thanks for explaining this. How about this approach:

On GNU and any other target that supports it, lower using a
SegmentAddress node.  On other targets, lower using a load
from a SegmentAddress node.  Make address-mode matching
recognize SegmentAddress nodes (with appropriate special-cases
for LEA).

Then in the Select phase, define a special "def : Pat" that maps
the SegmentAddress node to a load from the SegmentAddress node
with a predicate to limit it to GNU and similar targets.

Does this sound reasonable?

Dan




More information about the llvm-commits mailing list