[llvm-dev] RFC: LLVM Coroutine Representation, Round 2

Gor Nishanov via llvm-dev llvm-dev at lists.llvm.org
Wed Jul 20 15:11:51 PDT 2016


Hi, Antoine:

> Say I have (Python notation):
>
> def coroutine(n):
>     for i in range(n):
>         yield i
>
> def consumer(n):
>     for val in coroutine(n):
>         # do something with val
>
> How does consumer() know the coroutine has exited after the n'th
> iteration?  It can't call @coro.done() as there is a single suspend
> point...

There is a single suspend point at a python level, but not, necessarily, at LLVM
level. I would inject two more suspend points in your python frontend, so the
LLVM looks like this:

  Iterator coroutine(int n) {
    int current_value;
    CORO_BEGIN(..., &current_value); // designate current_value as promise
    SUSPEND(); // coroutine starts suspended
    for (int i = 0; i < n; ++i) {
      curren_value = i; SUSPEND(); // yield i
    }
    SUSPEND(/*final=*/true);
    ...
  }

  int __next__(void* hdl) {
    coro.resume(hdl);
    if (coro.done(hdl)) throw StopIteration();
    return *(int*)coro.promise(hdl);
  }

Essentially, for every generator, you always insert an initial suspend point
before any user authored code and you insert a final suspend point after all
the user authored code.

Gor


More information about the llvm-dev mailing list