The purest solution here is to introduce @llvm.threadlocal.address
to compute the address of thread-local variables as discussed. And then to handle the “readnone” problem, we introduce attributes readnone_except_thread_id
to indicate a function is pure except that it computes the thread id/address of thread-local variables, and attribute may_suspend_thread
to indicate that a function contains a suspend point where the current hardware thread can change. And then use all of this globally everywhere. This works not only for coroutines, but also any other form of cooperative green threads.
The primary problem is the “globally everywhere” part; the changes aren’t isolated to programs that use coroutines, so we’d have work carefully to avoid regressions.