blob: a4e6dc6cf87532ed130d75c425b91b56df50109a [file] [log] [blame]
//===- errors.go - IR generation for run-time panics ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements IR generation for triggering run-time panics.
//
//===----------------------------------------------------------------------===//
package irgen
import (
"llvm.org/llvm/bindings/go/llvm"
)
const (
// From go-runtime-error.c
gccgoRuntimeErrorSLICE_INDEX_OUT_OF_BOUNDS = 0
gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS = 1
gccgoRuntimeErrorSTRING_INDEX_OUT_OF_BOUNDS = 2
gccgoRuntimeErrorSLICE_SLICE_OUT_OF_BOUNDS = 3
gccgoRuntimeErrorARRAY_SLICE_OUT_OF_BOUNDS = 4
gccgoRuntimeErrorSTRING_SLICE_OUT_OF_BOUNDS = 5
gccgoRuntimeErrorNIL_DEREFERENCE = 6
gccgoRuntimeErrorMAKE_SLICE_OUT_OF_BOUNDS = 7
gccgoRuntimeErrorMAKE_MAP_OUT_OF_BOUNDS = 8
gccgoRuntimeErrorMAKE_CHAN_OUT_OF_BOUNDS = 9
gccgoRuntimeErrorDIVISION_BY_ZERO = 10
gccgoRuntimeErrorCount = 11
)
func (fr *frame) setBranchWeightMetadata(br llvm.Value, trueweight, falseweight uint64) {
mdprof := llvm.MDKindID("prof")
mdnode := llvm.GlobalContext().MDNode([]llvm.Metadata{
llvm.GlobalContext().MDString("branch_weights"),
llvm.ConstInt(llvm.Int32Type(), trueweight, false).ConstantAsMetadata(),
llvm.ConstInt(llvm.Int32Type(), falseweight, false).ConstantAsMetadata(),
})
br.SetMetadata(mdprof, mdnode)
}
func (fr *frame) condBrRuntimeError(cond llvm.Value, errcode uint64) {
if cond.IsNull() {
return
}
errorbb := fr.runtimeErrorBlocks[errcode]
newbb := errorbb.C == nil
if newbb {
errorbb = llvm.AddBasicBlock(fr.function, "")
fr.runtimeErrorBlocks[errcode] = errorbb
}
contbb := llvm.AddBasicBlock(fr.function, "")
br := fr.builder.CreateCondBr(cond, errorbb, contbb)
fr.setBranchWeightMetadata(br, 1, 1000)
if newbb {
fr.builder.SetInsertPointAtEnd(errorbb)
fr.runtime.runtimeError.call(fr, llvm.ConstInt(llvm.Int32Type(), errcode, false))
fr.builder.CreateUnreachable()
}
fr.builder.SetInsertPointAtEnd(contbb)
}