There are two problems with reusing values across coroutine suspensions:
- It has been assumed that all the code within the same function would run in the same thread. For example, the glibc library pthread_self is defined with attribute((const)) (which would have readnone attribute in LLVM IR) even though it in fact reads global memory. This was OK because within the same function the thread ID will never change in a non-coroutine function. Optimizazers take advantage of that and would reuse the results if there are multiple calls to pthread_self within the same function. However with coroutines this is no longer true. We cannot reuse the results of pthread_self if they cross suspension points because they could be running on different threads.
- Any data that needs to lives across coroutine suspensions will have to be spilled onto the coroutine frame (heap). Value reusing across suspensions would generate lots of data that needs to live on the frame. This can be expensive and makes the frame large unnecessarily in common cases.