diff options
author | Jaden Weiss <[email protected]> | 2019-10-05 21:43:27 -0400 |
---|---|---|
committer | Ayke <[email protected]> | 2019-10-16 16:04:37 +0200 |
commit | 8906192690d71392c46ad56cffb7d4ce6b6e5529 (patch) | |
tree | a46fb105caff95c3fff88dddce2715b3c9a1e233 | |
parent | 20a55e79441ef224b92e17a1e4b621e67021e506 (diff) | |
download | tinygo-8906192690d71392c46ad56cffb7d4ce6b6e5529.tar.gz tinygo-8906192690d71392c46ad56cffb7d4ce6b6e5529.zip |
fix goroutine lowering type errors
-rw-r--r-- | compiler/goroutine-lowering.go | 20 | ||||
-rw-r--r-- | compiler/llvm.go | 16 |
2 files changed, 22 insertions, 14 deletions
diff --git a/compiler/goroutine-lowering.go b/compiler/goroutine-lowering.go index 45465b2f8..5641a6ed8 100644 --- a/compiler/goroutine-lowering.go +++ b/compiler/goroutine-lowering.go @@ -450,8 +450,6 @@ func (c *Compiler) markAsyncFunctions() (needsScheduler bool, err error) { } coroDebugPrintln("scanning", f.Name()) - var retAlloc llvm.Value - // Rewrite async calls for bb := f.EntryBasicBlock(); !bb.IsNil(); bb = llvm.NextBasicBlock(bb) { for inst := bb.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) { @@ -511,9 +509,9 @@ func (c *Compiler) markAsyncFunctions() (needsScheduler bool, err error) { // pass parent handle directly into function inst.SetOperand(inst.OperandsCount()-2, parentHandle) - if inst.Type().TypeKind() != llvm.VoidTypeKind { + if callee.Type().ElementType().ReturnType().TypeKind() != llvm.VoidTypeKind { // delete return value - uses[0].SetOperand(0, llvm.Undef(inst.Type())) + uses[0].SetOperand(0, llvm.Undef(callee.Type().ElementType().ReturnType())) } c.builder.SetInsertPointBefore(next) @@ -534,15 +532,9 @@ func (c *Compiler) markAsyncFunctions() (needsScheduler bool, err error) { // Allocate space for the return value. var retvalAlloca llvm.Value - if inst.Type().TypeKind() != llvm.VoidTypeKind { - if retAlloc.IsNil() { - // insert at start of function - c.builder.SetInsertPointBefore(f.EntryBasicBlock().FirstInstruction()) - - // allocate return value buffer - retAlloc = c.builder.CreateAlloca(inst.Type(), "coro.retvalAlloca") - } - retvalAlloca = retAlloc + if callee.Type().ElementType().ReturnType().TypeKind() != llvm.VoidTypeKind { + // allocate return value buffer + retvalAlloca = c.createInstructionAlloca(callee.Type().ElementType().ReturnType(), inst, "coro.retvalAlloca") // call before function c.builder.SetInsertPointBefore(inst) @@ -672,7 +664,7 @@ func (c *Compiler) markAsyncFunctions() (needsScheduler bool, err error) { c.builder.CreateStore(inst.Operand(0), retPtr) // delete return value - inst.SetOperand(0, llvm.Undef(inst.Type())) + inst.SetOperand(0, llvm.Undef(f.Type().ElementType().ReturnType())) } // insert reactivation call diff --git a/compiler/llvm.go b/compiler/llvm.go index 747edabbd..2df6d2768 100644 --- a/compiler/llvm.go +++ b/compiler/llvm.go @@ -54,6 +54,22 @@ func (c *Compiler) createTemporaryAlloca(t llvm.Type, name string) (alloca, bitc return } +// createInstructionAlloca creates an alloca in the entry block, and places lifetime control intrinsics around the instruction +func (c *Compiler) createInstructionAlloca(t llvm.Type, inst llvm.Value, name string) llvm.Value { + alloca := c.createEntryBlockAlloca(t, name) + c.builder.SetInsertPointBefore(inst) + bitcast := c.builder.CreateBitCast(alloca, c.i8ptrType, name+".bitcast") + size := llvm.ConstInt(c.ctx.Int64Type(), c.targetData.TypeAllocSize(t), false) + c.builder.CreateCall(c.getLifetimeStartFunc(), []llvm.Value{size, bitcast}, "") + if next := llvm.NextInstruction(inst); !next.IsNil() { + c.builder.SetInsertPointBefore(next) + } else { + c.builder.SetInsertPointAtEnd(inst.InstructionParent()) + } + c.builder.CreateCall(c.getLifetimeEndFunc(), []llvm.Value{size, bitcast}, "") + return alloca +} + // emitLifetimeEnd signals the end of an (alloca) lifetime by calling the // llvm.lifetime.end intrinsic. It is commonly used together with // createTemporaryAlloca. |