From 4da137d7c88cb96ccae5ebb6bca75065c7c9a3f7 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 7 Dec 2019 22:12:27 +0100 Subject: [PATCH] compiler: check for non-static allocas Non-static allocas are disallowed for a number of reasons, so check for their presence. See the commit diff for details. --- compiler/check.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/compiler/check.go b/compiler/check.go index 8be5c702..5372b1ef 100644 --- a/compiler/check.go +++ b/compiler/check.go @@ -101,6 +101,24 @@ func (c *Compiler) checkInstruction(inst llvm.Value, types map[llvm.Type]struct{ return errorAt(inst, err.Error()) } + // The alloca instruction can be present in every basic block. However, + // allocas in basic blocks other than the entry basic block have a number of + // problems: + // * They are hard to optimize, leading to potential missed optimizations. + // * They may cause stack overflows in loops that would otherwise be + // innocent. + // * They cause extra code to be generated, because it requires the use of + // a frame pointer. + // * Perhaps most importantly, the coroutine lowering pass of LLVM (as of + // LLVM 9) cannot deal with these allocas: + // https://llvm.org/docs/Coroutines.html + // Therefore, alloca instructions should be limited to the entry block. + if !inst.IsAAllocaInst().IsNil() { + if inst.InstructionParent() != inst.InstructionParent().Parent().EntryBasicBlock() { + return errorAt(inst, "internal error: non-static alloca") + } + } + // check operands for i := 0; i < inst.OperandsCount(); i++ { if err := c.checkValue(inst.Operand(i), types, specials); err != nil {