Segmented Stacks: Breaking libgcc compatibility

Hi llvmdev!

I've been working on implementing support for segmented stacks in LLVM
(towards GSoC '11). Currently I'm working on adding intrinsics for
coroutines. The problem is this:

Till now I had been depending on libgcc for runtime support (and was
being 100% libgcc compatible in the process). However, since all the
stack allocation routines in libgcc depend on TLS variables to manage
dynamically allocated stack blocks (stacklets), it may not be possible
to have more than one stack in a single thread. This makes coroutines
less interesting, since the whole point was to use multiple, cheap
stacks from a single thread (and switch between them, at will).

My current idea is to port segmented stack related routines to
compiler-rt (or to a different "segmented-stacks" library
altogether). That way, __generic_morestack (the function in libgcc
that allocates space for a new stacklet) gets a cousin
__generic_morestack_with_context, which take a pointer to a "context"
holding the otherwise thread local variables use by libgcc's
__generic_morestack. That way, every coroutine can have its own
"context" which it passes to __generic_morestack_context.

__generic_morestack in compiler-rt can then call __generic_morestack
with a context which it holds in a TLS variable, to take care of the
most common case.

Does this sound sane?

Thanks!

Hi Sanjoy,

I've been working on implementing support for segmented stacks in LLVM
(towards GSoC '11). Currently I'm working on adding intrinsics for
coroutines. The problem is this:

Till now I had been depending on libgcc for runtime support (and was
being 100% libgcc compatible in the process). However, since all the
stack allocation routines in libgcc depend on TLS variables to manage
dynamically allocated stack blocks (stacklets), it may not be possible
to have more than one stack in a single thread. This makes coroutines
less interesting, since the whole point was to use multiple, cheap
stacks from a single thread (and switch between them, at will).

My current idea is to port segmented stack related routines to
compiler-rt (or to a different "segmented-stacks" library
altogether). That way, __generic_morestack (the function in libgcc
that allocates space for a new stacklet) gets a cousin
__generic_morestack_with_context, which take a pointer to a "context"
holding the otherwise thread local variables use by libgcc's
__generic_morestack. That way, every coroutine can have its own
"context" which it passes to __generic_morestack_context.

__generic_morestack in compiler-rt can then call __generic_morestack
with a context which it holds in a TLS variable, to take care of the
most common case.

I think it is important to retain gcc compatibility, at least in the
following sense: if someone only wants to make use of the segmented
stack facilities that GCC provides, then they should be able to link
with libgcc. Do you think you can set things up so that if people
want the extra functionality you mention above, then they have to use
compiler-rt; but if they just use basic functionality then libgcc is
OK? I'm thinking of dragonegg, which hopefully will support GNU Go
one day (this needs segmented stacks support), but for which I'd much
rather avoid any requirement to use compiler-rt if possible.

Alternatively, maybe you could implement the extra functionality in
libgcc.

Ciao, Duncan.

Hi

with libgcc. Do you think you can set things up so that if people
want the extra functionality you mention above, then they have to use
compiler-rt; but if they just use basic functionality then libgcc is
OK? I'm thinking of dragonegg, which hopefully will support GNU Go

That should be doable. I'll do that.