ideas for TLS implementation

For everyone understand which code must be emitted to implement TLS, I
will paste the code generated by gcc for a simple function:

__thread int a = 1;

int f(){
  return a;
}

gcc teste.c -o teste.s -S -O2 (arm-linux-gnueabi):

        .global a
        .section .tdata,"awT",%progbits <== special section for
tls symbols
        .align 2
        .type a, %object
        .size a, 4
a:
        .word 1
        .text
        .align 2
        .global f
        .type f, %function
f:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        str lr, [sp, #-4]!
        ldr r3, .L2
        bl __aeabi_read_tp @ load_tp_soft <== get thread pointer
(abi dependent)
        ldr r0, [r0, r3]
        ldr pc, [sp], #4
.L3:
        .align 2
.L2:
        .word a(tpoff) <== offset of "a"
        .size f, .-f

The idea of implementing TLS is to create the "thread_local" keyword.
The program above would be converted to this:

@a = thread_local global i32 1 ; <i32*> [#uses=1] <== Thread
local keyword

define i32 @f() {
entry:
        %tmp1 = load i32* @a ; <i32> [#uses=1]
        ret i32 %tmp1
}

With "thread_local" keyword, the backends can emit TLS code. The TLS
is architecture and abi dependent, so I think we must let the backends
handle with TLS symbols. Each backend must handle each TLS model.

Adding TLS support seems to be tricky, since there are 4
different TLS "models" with different "assumptions".

There is a model ("general dynamic") that works in all situations. The
other three models are optimizations of the first. So, I think we
should start implementing the "general dynamic" model.

I believe the roadmap is:

1. make LLVM understand "thread_local" keyword. (AsmParser, AsmWriter,
BCReader, BCWriter)
2. make llvm-gcc emit "thread_local" keyword
3. implement "thread_local" in C backend (model independent)
3. implement "general dynamic" tls model for i386-linux-gnu
4. implement "general dynamic" tls model for arm-linux-gnueabi (this
is more complex because gcc 4.0 doesn't support tls for arm. I will
have to backport a patch from gcc 4.1 to llvm-gcc)
5. Maybe implement other models for arm-linux-gnueabi

Suggestions are appreciated. :slight_smile:

Lauro

Hi Lauro,

For everyone understand which code must be emitted to implement TLS, I
will paste the code generated by gcc for a simple function:

... snip ...

This proposal sounds really good to me. I only have a couple comments.

We have a "section" keyword already developed in LLVM assembly. Perhaps
instead of introducing a new keyword we just do: section "TLS" ? This
should reduce the amount of work needed to get the feature done.

The "general dynamic" mechanism seems to be the way to start this. Get
that working on all targets (not just X86 and ARM :slight_smile: .. then move on to
target specific optimizations.

If you're signing up for this, could you cut & past it into a new
enhancement (if you haven't already) so we can track discussion on the
design and progress.

Thanks Lauro,

Reid.

This proposal sounds really good to me. I only have a couple comments.

We have a "section" keyword already developed in LLVM assembly. Perhaps
instead of introducing a new keyword we just do: section "TLS" ? This
should reduce the amount of work needed to get the feature done.

This is not possible because the programmer can define the TLS section
name. The code

__thread int a __attribute__ ((section ("teste"))) = 1;

is valid.

The "general dynamic" mechanism seems to be the way to start this. Get
that working on all targets (not just X86 and ARM :slight_smile: .. then move on to
target specific optimizations.

Not only the optimizations are target specific. The ELF TLS manual has
a section for each target for each TLS model. So, I think we will
have an TLS implementation similar to "LowerCallTo" (every backend
must implement or assert).

Thanks,
Lauro