Initial commit of llgo.
llvm-svn: 222857
diff --git a/llgo/irgen/errors.go b/llgo/irgen/errors.go
new file mode 100644
index 0000000..73f498e
--- /dev/null
+++ b/llgo/irgen/errors.go
@@ -0,0 +1,72 @@
+//===- 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.MDNode([]llvm.Value{
+ llvm.MDString("branch_weights"),
+ llvm.ConstInt(llvm.Int32Type(), trueweight, false),
+ llvm.ConstInt(llvm.Int32Type(), falseweight, false),
+ })
+
+ 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)
+}