[LLVMdev] RFC: GSoC Project

Justin Holewinski justin.holewinski at gmail.com
Mon Apr 11 07:34:01 PDT 2011


On Mon, Apr 11, 2011 at 9:07 AM, Sanjoy Das
<sanjoy at playingwithpointers.com>wrote:

> Hi!
>
> Thanks for the feedback. For context, my implementation plan is here:
> http://pastebin.com/e9JMZNCE
>
> First, about unwinding:
>
> In architectures like x86-64, where unwinding based on DWARF info, there
> shouldn't be any problems; since the DWARF info will be emitted
> correctly. Otherwise, if the unwinding is done by following BP, it
> should still be possible to have BP de-reference correctly (ref. "Frame
> Pointers" section in the implementation plan). SP will not always have a
> correct value - I don't know if this is problem.
>
> About co-routines:
>
> Here is a sketch of how I think co-routines can be implemented (I'll
> merge this with the main implementation plan after I get some feedback):
>
> Have a new instruction, called "yield" to return a value from a
> co-routine, preserving the state. Thus, we immediately know which
> functions are co-routines. Each co-routine will have a new stack.
> Associate each co-routine with a thread-local global variable (called
> saved_stack here, will have to be mangled with the name of the
> co-routine) which points to the start stack block for that co-routine.
> This will be the first block in the chain of blocks to follow.
>
> The structure of the block will be similar to the structure of a regular
> stack block, except that it will also have space to store two registers
> - this_ip and this_sp.
>
> The prologue of a co-routine will jump to a function similar to
> setup_new_block (setup_new_block_coroutine) which will work like
> setup_new_block, except:
>
> 1. It will first check if saved_stack is NULL. If it is NULL, it will
> allocate a new block and save it to saved_stack. It if isn't, it'll
> simply restore saved_sp, saved_ip.
>
> 2. In case a new block was allocated, it will pretty much do what
> setup_block does, after which it will adjust the SP to make space for
> the saved registers.
>
> The destroy_block procedure will also have to be a little different
> (mentioned below).
>
> There are four things (relevant to this discussion) a co-routine can do:
>
> Yield
>
> This returns control to the calling function, without forgetting the
> current state of the function. To do this, we save saved_ip and
> saved_sp. Every yield be padded with instructions pushing and popping
> the registers live at that point. Then we set the return value (register
> or memory), and restore saved_sp and saved_ip from the current block. We
> can't simply return because the actual return value has been hijacked to
> provide for block cleanup.
>
> Call to regular function
>
> Just a simple call - the caller's prologue will handle setting up a it's
> own stack space etc.
>
> Call to Co-routine
>
> This too should "just work", since all the heavy-lifting is done in the
> co-routine's prologue. However, the above approach will not work for
> nested co-routines (i.e. calling the same co-routine body with one call
> is still active, recursively). I'm not sure if having support for nested
> co-routines will add any value.
>
> Return
>
> This will be a regular return. Since the return value has been hijacked
> to point to a another block of code (destroy_block_coroutine), control
> will jump there instead.
>
> destroy_block_coroutine will free the linked-list of stack blocks (we
> have to free this, since we will won't have a reference to this list
> anymore), set saved_stack for this co-routine to NULL, and restore
> saved_sp and saved_ip.
>

I'm wondering how much of this should be implemented as new LLVM
functionality, and how much should be left to the front-end compiler.  With
some additional LLVM intrinsics (e.g. llvm.stack.new.block,
llvm.stack.delete.block, etc.), a front-end could take care of the details
of how co-routines are actually implemented.  This would also give the
front-end freedom to implement whatever semantics/conventions are
necessary/required for the source language.  I'm just not sure having LLVM
dictate *how* co-routines are implemented is the best way to approach this.


>
> --
> Sanjoy Das
> http://playingwithpointers.com
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>



-- 

Thanks,

Justin Holewinski
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20110411/94d06a41/attachment.html>


More information about the llvm-dev mailing list