//===- channels.go - IR generation for channels ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements IR generation for channels.
//
//===----------------------------------------------------------------------===//

package irgen

import (
	"llvm.org/llgo/third_party/gotools/go/ssa"
	"llvm.org/llgo/third_party/gotools/go/types"
	"llvm.org/llvm/bindings/go/llvm"
)

// makeChan implements make(chantype[, size])
func (fr *frame) makeChan(chantyp types.Type, size *govalue) *govalue {
	// TODO(pcc): call __go_new_channel_big here if needed
	dyntyp := fr.types.ToRuntime(chantyp)
	size = fr.convert(size, types.Typ[types.Uintptr])
	ch := fr.runtime.newChannel.call(fr, dyntyp, size.value)[0]
	return newValue(ch, chantyp)
}

// chanSend implements ch<- x
func (fr *frame) chanSend(ch *govalue, elem *govalue) {
	elemtyp := ch.Type().Underlying().(*types.Chan).Elem()
	elem = fr.convert(elem, elemtyp)
	elemptr := fr.allocaBuilder.CreateAlloca(elem.value.Type(), "")
	fr.builder.CreateStore(elem.value, elemptr)
	elemptr = fr.builder.CreateBitCast(elemptr, llvm.PointerType(llvm.Int8Type(), 0), "")
	chantyp := fr.types.ToRuntime(ch.Type())
	fr.runtime.sendBig.call(fr, chantyp, ch.value, elemptr)
}

// chanRecv implements x[, ok] = <-ch
func (fr *frame) chanRecv(ch *govalue, commaOk bool) (x, ok *govalue) {
	elemtyp := ch.Type().Underlying().(*types.Chan).Elem()
	ptr := fr.allocaBuilder.CreateAlloca(fr.types.ToLLVM(elemtyp), "")
	ptri8 := fr.builder.CreateBitCast(ptr, llvm.PointerType(llvm.Int8Type(), 0), "")
	chantyp := fr.types.ToRuntime(ch.Type())

	if commaOk {
		okval := fr.runtime.chanrecv2.call(fr, chantyp, ch.value, ptri8)[0]
		ok = newValue(okval, types.Typ[types.Bool])
	} else {
		fr.runtime.receive.call(fr, chantyp, ch.value, ptri8)
	}
	x = newValue(fr.builder.CreateLoad(ptr, ""), elemtyp)
	return
}

// chanClose implements close(ch)
func (fr *frame) chanClose(ch *govalue) {
	fr.runtime.builtinClose.call(fr, ch.value)
}

func (fr *frame) chanSelect(sel *ssa.Select) (index, recvOk *govalue, recvElems []*govalue) {
	n := uint64(len(sel.States))
	if !sel.Blocking {
		// non-blocking means there's a default case
		n++
	}
	size := llvm.ConstInt(llvm.Int32Type(), n, false)
	selectp := fr.runtime.newSelect.call(fr, size)[0]

	// Allocate stack for the values to send and receive.
	ptrs := make([]llvm.Value, len(sel.States))
	for i, state := range sel.States {
		chantyp := state.Chan.Type().Underlying().(*types.Chan)
		elemtyp := fr.types.ToLLVM(chantyp.Elem())
		if state.Dir == types.SendOnly {
			ptrs[i] = fr.allocaBuilder.CreateAlloca(elemtyp, "")
			fr.builder.CreateStore(fr.llvmvalue(state.Send), ptrs[i])
		} else {
			// Only allocate stack space if the received value is used.
			used := chanSelectStateUsed(sel, len(recvElems))
			if used {
				ptrs[i] = fr.allocaBuilder.CreateAlloca(elemtyp, "")
			} else {
				ptrs[i] = llvm.ConstNull(llvm.PointerType(llvm.Int8Type(), 0))
			}
			recvElems = append(recvElems, newValue(ptrs[i], chantyp.Elem()))
		}
	}

	// Create select{send,recv2} calls.
	var receivedp llvm.Value
	if len(recvElems) > 0 {
		receivedp = fr.allocaBuilder.CreateAlloca(fr.types.ToLLVM(types.Typ[types.Bool]), "")
	}
	if !sel.Blocking {
		// If the default case is chosen, the index must be -1.
		fr.runtime.selectdefault.call(fr, selectp, llvm.ConstAllOnes(llvm.Int32Type()))
	}
	for i, state := range sel.States {
		ch := fr.llvmvalue(state.Chan)
		index := llvm.ConstInt(llvm.Int32Type(), uint64(i), false)
		if state.Dir == types.SendOnly {
			fr.runtime.selectsend.call(fr, selectp, ch, ptrs[i], index)
		} else {
			fr.runtime.selectrecv2.call(fr, selectp, ch, ptrs[i], receivedp, index)
		}
	}

	// Fire off the select.
	index = newValue(fr.runtime.selectgo.call(fr, selectp)[0], types.Typ[types.Int])
	if len(recvElems) > 0 {
		recvOk = newValue(fr.builder.CreateLoad(receivedp, ""), types.Typ[types.Bool])
		for _, recvElem := range recvElems {
			recvElem.value = fr.builder.CreateLoad(recvElem.value, "")
		}
	}
	return index, recvOk, recvElems
}

func chanSelectStateUsed(sel *ssa.Select, recvIndex int) bool {
	for _, instr := range *sel.Referrers() {
		extract, ok := instr.(*ssa.Extract)
		if !ok || extract.Index != (recvIndex+2) {
			continue
		}
		if len(*extract.Referrers()) > 0 {
			return true
		}
	}
	return false
}
