blob: a4e6dc6cf87532ed130d75c425b91b56df50109a [file] [log] [blame]
Peter Collingbournead9841e2014-11-27 00:06:42 +00001//===- errors.go - IR generation for run-time panics ----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements IR generation for triggering run-time panics.
11//
12//===----------------------------------------------------------------------===//
13
14package irgen
15
16import (
17 "llvm.org/llvm/bindings/go/llvm"
18)
19
20const (
21 // From go-runtime-error.c
22 gccgoRuntimeErrorSLICE_INDEX_OUT_OF_BOUNDS = 0
23 gccgoRuntimeErrorARRAY_INDEX_OUT_OF_BOUNDS = 1
24 gccgoRuntimeErrorSTRING_INDEX_OUT_OF_BOUNDS = 2
25 gccgoRuntimeErrorSLICE_SLICE_OUT_OF_BOUNDS = 3
26 gccgoRuntimeErrorARRAY_SLICE_OUT_OF_BOUNDS = 4
27 gccgoRuntimeErrorSTRING_SLICE_OUT_OF_BOUNDS = 5
28 gccgoRuntimeErrorNIL_DEREFERENCE = 6
29 gccgoRuntimeErrorMAKE_SLICE_OUT_OF_BOUNDS = 7
30 gccgoRuntimeErrorMAKE_MAP_OUT_OF_BOUNDS = 8
31 gccgoRuntimeErrorMAKE_CHAN_OUT_OF_BOUNDS = 9
32 gccgoRuntimeErrorDIVISION_BY_ZERO = 10
33 gccgoRuntimeErrorCount = 11
34)
35
36func (fr *frame) setBranchWeightMetadata(br llvm.Value, trueweight, falseweight uint64) {
37 mdprof := llvm.MDKindID("prof")
38
Peter Collingbourne8bcc05d2014-12-13 02:26:00 +000039 mdnode := llvm.GlobalContext().MDNode([]llvm.Metadata{
40 llvm.GlobalContext().MDString("branch_weights"),
41 llvm.ConstInt(llvm.Int32Type(), trueweight, false).ConstantAsMetadata(),
42 llvm.ConstInt(llvm.Int32Type(), falseweight, false).ConstantAsMetadata(),
Peter Collingbournead9841e2014-11-27 00:06:42 +000043 })
44
45 br.SetMetadata(mdprof, mdnode)
46}
47
48func (fr *frame) condBrRuntimeError(cond llvm.Value, errcode uint64) {
49 if cond.IsNull() {
50 return
51 }
52
53 errorbb := fr.runtimeErrorBlocks[errcode]
54 newbb := errorbb.C == nil
55 if newbb {
56 errorbb = llvm.AddBasicBlock(fr.function, "")
57 fr.runtimeErrorBlocks[errcode] = errorbb
58 }
59
60 contbb := llvm.AddBasicBlock(fr.function, "")
61
62 br := fr.builder.CreateCondBr(cond, errorbb, contbb)
63 fr.setBranchWeightMetadata(br, 1, 1000)
64
65 if newbb {
66 fr.builder.SetInsertPointAtEnd(errorbb)
67 fr.runtime.runtimeError.call(fr, llvm.ConstInt(llvm.Int32Type(), errcode, false))
68 fr.builder.CreateUnreachable()
69 }
70
71 fr.builder.SetInsertPointAtEnd(contbb)
72}