compiler: fix phi nodes for type asserts

Type asserts insert more basic block, causing phi node values to be
invalid. Fix this by remembering the outgoing LLVM basic block.
Этот коммит содержится в:
Ayke van Laethem 2018-09-13 20:42:04 +02:00
родитель 57661a3c76
коммит 9cd7c7f0ba
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED

Просмотреть файл

@ -63,6 +63,7 @@ type Frame struct {
params map[*ssa.Parameter]int // arguments to the function params map[*ssa.Parameter]int // arguments to the function
locals map[ssa.Value]llvm.Value // local variables locals map[ssa.Value]llvm.Value // local variables
blocks map[*ssa.BasicBlock]llvm.BasicBlock blocks map[*ssa.BasicBlock]llvm.BasicBlock
currentBlock *ssa.BasicBlock
phis []Phi phis []Phi
blocking bool blocking bool
taskHandle llvm.Value taskHandle llvm.Value
@ -1316,6 +1317,7 @@ func (c *Compiler) parseFunc(frame *Frame) error {
fmt.Printf("%s:\n", block.Comment) fmt.Printf("%s:\n", block.Comment)
} }
c.builder.SetInsertPointAtEnd(frame.blocks[block]) c.builder.SetInsertPointAtEnd(frame.blocks[block])
frame.currentBlock = block
for _, instr := range block.Instrs { for _, instr := range block.Instrs {
if c.dumpSSA { if c.dumpSSA {
if val, ok := instr.(ssa.Value); ok && val.Name() != "" { if val, ok := instr.(ssa.Value); ok && val.Name() != "" {
@ -2369,6 +2371,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
prevBlock := c.builder.GetInsertBlock() prevBlock := c.builder.GetInsertBlock()
okBlock := c.ctx.AddBasicBlock(frame.fn.llvmFn, "typeassert.ok") okBlock := c.ctx.AddBasicBlock(frame.fn.llvmFn, "typeassert.ok")
nextBlock := c.ctx.AddBasicBlock(frame.fn.llvmFn, "typeassert.next") nextBlock := c.ctx.AddBasicBlock(frame.fn.llvmFn, "typeassert.next")
frame.blocks[frame.currentBlock] = nextBlock // adjust outgoing block for phi nodes
c.builder.CreateCondBr(commaOk, okBlock, nextBlock) c.builder.CreateCondBr(commaOk, okBlock, nextBlock)
// Retrieve the value from the interface if the type assert was // Retrieve the value from the interface if the type assert was