diff options
author | Nia Waldvogel <[email protected]> | 2021-09-17 12:23:01 -0400 |
---|---|---|
committer | Ayke <[email protected]> | 2021-09-21 20:08:30 +0200 |
commit | 157382600535c95bdbf5d6e8c4b9e5ca71749018 (patch) | |
tree | ee2866f936f9fe315b176fd9430e44edc664ba0f | |
parent | ecd8c2d902498c9b3c39417b9e52e8844adcb1cd (diff) | |
download | tinygo-157382600535c95bdbf5d6e8c4b9e5ca71749018.tar.gz tinygo-157382600535c95bdbf5d6e8c4b9e5ca71749018.zip |
transform (coroutines): move any misplaced entry-block allocas to the start of the entry block before loweringv0.20.0
-rw-r--r-- | transform/coroutines.go | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/transform/coroutines.go b/transform/coroutines.go index 9a382c3ae..e1f109b1b 100644 --- a/transform/coroutines.go +++ b/transform/coroutines.go @@ -763,6 +763,27 @@ func (c *coroutineLoweringPass) lowerCallReturn(caller *asyncFunc, call llvm.Val // lowerFuncCoro transforms an async function into a coroutine by lowering async operations to `llvm.coro` intrinsics. // See https://llvm.org/docs/Coroutines.html for more information on these intrinsics. func (c *coroutineLoweringPass) lowerFuncCoro(fn *asyncFunc) { + // Ensure that any alloca instructions in the entry block are at the start. + // Otherwise, block splitting would result in unintended behavior. + { + // Skip alloca instructions at the start of the block. + inst := fn.fn.FirstBasicBlock().FirstInstruction() + for !inst.IsAAllocaInst().IsNil() { + inst = llvm.NextInstruction(inst) + } + + // Find any other alloca instructions and move them after the other allocas. + c.builder.SetInsertPointBefore(inst) + for !inst.IsNil() { + next := llvm.NextInstruction(inst) + if !inst.IsAAllocaInst().IsNil() { + inst.RemoveFromParentAsInstruction() + c.builder.Insert(inst) + } + inst = next + } + } + returnType := fn.fn.Type().ElementType().ReturnType() // Prepare coroutine state. |