[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