diff --git a/compiler/channel.go b/compiler/channel.go index 05973ecb..4a18f064 100644 --- a/compiler/channel.go +++ b/compiler/channel.go @@ -12,10 +12,7 @@ import ( // emitMakeChan returns a new channel value for the given channel type. func (c *Compiler) emitMakeChan(expr *ssa.MakeChan) (llvm.Value, error) { - valueType, err := c.getLLVMType(expr.Type().(*types.Chan).Elem()) - if err != nil { - return llvm.Value{}, err - } + valueType := c.getLLVMType(expr.Type().(*types.Chan).Elem()) if c.targetData.TypeAllocSize(valueType) > c.targetData.TypeAllocSize(c.intType) { // Values bigger than int overflow the data part of the coroutine. // TODO: make the coroutine data part big enough to hold these bigger @@ -33,10 +30,7 @@ func (c *Compiler) emitMakeChan(expr *ssa.MakeChan) (llvm.Value, error) { // emitChanSend emits a pseudo chan send operation. It is lowered to the actual // channel send operation during goroutine lowering. func (c *Compiler) emitChanSend(frame *Frame, instr *ssa.Send) error { - valueType, err := c.getLLVMType(instr.Chan.Type().(*types.Chan).Elem()) - if err != nil { - return err - } + valueType := c.getLLVMType(instr.Chan.Type().(*types.Chan).Elem()) ch, err := c.parseExpr(frame, instr.Chan) if err != nil { return err @@ -56,10 +50,7 @@ func (c *Compiler) emitChanSend(frame *Frame, instr *ssa.Send) error { // emitChanRecv emits a pseudo chan receive operation. It is lowered to the // actual channel receive operation during goroutine lowering. func (c *Compiler) emitChanRecv(frame *Frame, unop *ssa.UnOp) (llvm.Value, error) { - valueType, err := c.getLLVMType(unop.X.Type().(*types.Chan).Elem()) - if err != nil { - return llvm.Value{}, err - } + valueType := c.getLLVMType(unop.X.Type().(*types.Chan).Elem()) valueSize := llvm.ConstInt(c.uintptrType, c.targetData.TypeAllocSize(valueType), false) ch, err := c.parseExpr(frame, unop.X) if err != nil { @@ -83,11 +74,8 @@ func (c *Compiler) emitChanRecv(frame *Frame, unop *ssa.UnOp) (llvm.Value, error // emitChanClose closes the given channel. func (c *Compiler) emitChanClose(frame *Frame, param ssa.Value) error { - valueType, err := c.getLLVMType(param.Type().(*types.Chan).Elem()) + valueType := c.getLLVMType(param.Type().(*types.Chan).Elem()) valueSize := llvm.ConstInt(c.uintptrType, c.targetData.TypeAllocSize(valueType), false) - if err != nil { - return err - } ch, err := c.parseExpr(frame, param) if err != nil { return err diff --git a/compiler/compiler.go b/compiler/compiler.go index 094568c5..c52e20c1 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -274,10 +274,7 @@ func (c *Compiler) Compile(mainPath string) error { for _, t := range c.ir.NamedTypes { if named, ok := t.Type.Type().(*types.Named); ok { if st, ok := named.Underlying().(*types.Struct); ok { - llvmType, err := c.getLLVMType(st) - if err != nil { - return err - } + llvmType := c.getLLVMType(st) t.LLVMType.StructSetBody(llvmType.StructElementTypes(), false) } } @@ -286,10 +283,7 @@ func (c *Compiler) Compile(mainPath string) error { // Declare all globals. for _, g := range c.ir.Globals { typ := g.Type().(*types.Pointer).Elem() - llvmType, err := c.getLLVMType(typ) - if err != nil { - return err - } + llvmType := c.getLLVMType(typ) global := c.mod.NamedGlobal(g.LinkName()) if global.IsNil() { global = llvm.AddGlobal(c.mod, llvmType, g.LinkName()) @@ -303,11 +297,7 @@ func (c *Compiler) Compile(mainPath string) error { // Declare all functions. for _, f := range c.ir.Functions { - frame, err := c.parseFuncDecl(f) - if err != nil { - return err - } - frames = append(frames, frame) + frames = append(frames, c.parseFuncDecl(f)) } // Add definitions to declarations. @@ -330,10 +320,7 @@ func (c *Compiler) Compile(mainPath string) error { // Define the already declared functions that wrap methods for use in // interfaces. for _, state := range c.interfaceInvokeWrappers { - err = c.createInterfaceInvokeWrapper(state) - if err != nil { - return err - } + c.createInterfaceInvokeWrapper(state) } // After all packages are imported, add a synthetic initializer function @@ -342,10 +329,7 @@ func (c *Compiler) Compile(mainPath string) error { initFn.LLVMFn.SetLinkage(llvm.InternalLinkage) initFn.LLVMFn.SetUnnamedAddr(true) if c.Debug { - difunc, err := c.attachDebugInfo(initFn) - if err != nil { - return err - } + difunc := c.attachDebugInfo(initFn) pos := c.ir.Program.Fset.Position(initFn.Pos()) c.builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{}) } @@ -411,87 +395,74 @@ func (c *Compiler) Compile(mainPath string) error { return nil } -func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) { +func (c *Compiler) getLLVMType(goType types.Type) llvm.Type { switch typ := goType.(type) { case *types.Array: - elemType, err := c.getLLVMType(typ.Elem()) - if err != nil { - return llvm.Type{}, err - } - return llvm.ArrayType(elemType, int(typ.Len())), nil + elemType := c.getLLVMType(typ.Elem()) + return llvm.ArrayType(elemType, int(typ.Len())) case *types.Basic: switch typ.Kind() { case types.Bool, types.UntypedBool: - return c.ctx.Int1Type(), nil + return c.ctx.Int1Type() case types.Int8, types.Uint8: - return c.ctx.Int8Type(), nil + return c.ctx.Int8Type() case types.Int16, types.Uint16: - return c.ctx.Int16Type(), nil + return c.ctx.Int16Type() case types.Int32, types.Uint32: - return c.ctx.Int32Type(), nil + return c.ctx.Int32Type() case types.Int, types.Uint: - return c.intType, nil + return c.intType case types.Int64, types.Uint64: - return c.ctx.Int64Type(), nil + return c.ctx.Int64Type() case types.Float32: - return c.ctx.FloatType(), nil + return c.ctx.FloatType() case types.Float64: - return c.ctx.DoubleType(), nil + return c.ctx.DoubleType() case types.Complex64: - return c.ctx.StructType([]llvm.Type{c.ctx.FloatType(), c.ctx.FloatType()}, false), nil + return c.ctx.StructType([]llvm.Type{c.ctx.FloatType(), c.ctx.FloatType()}, false) case types.Complex128: - return c.ctx.StructType([]llvm.Type{c.ctx.DoubleType(), c.ctx.DoubleType()}, false), nil + return c.ctx.StructType([]llvm.Type{c.ctx.DoubleType(), c.ctx.DoubleType()}, false) case types.String, types.UntypedString: - return c.mod.GetTypeByName("runtime._string"), nil + return c.mod.GetTypeByName("runtime._string") case types.Uintptr: - return c.uintptrType, nil + return c.uintptrType case types.UnsafePointer: - return c.i8ptrType, nil + return c.i8ptrType default: - return llvm.Type{}, errors.New("todo: unknown basic type: " + typ.String()) + panic("unknown basic type: " + typ.String()) } case *types.Chan: - return llvm.PointerType(c.mod.GetTypeByName("runtime.channel"), 0), nil + return llvm.PointerType(c.mod.GetTypeByName("runtime.channel"), 0) case *types.Interface: - return c.mod.GetTypeByName("runtime._interface"), nil + return c.mod.GetTypeByName("runtime._interface") case *types.Map: - return llvm.PointerType(c.mod.GetTypeByName("runtime.hashmap"), 0), nil + return llvm.PointerType(c.mod.GetTypeByName("runtime.hashmap"), 0) case *types.Named: if _, ok := typ.Underlying().(*types.Struct); ok { llvmType := c.mod.GetTypeByName(typ.Obj().Pkg().Path() + "." + typ.Obj().Name()) if llvmType.IsNil() { - return llvm.Type{}, errors.New("type not found: " + typ.Obj().Pkg().Path() + "." + typ.Obj().Name()) + panic("underlying type not found: " + typ.Obj().Pkg().Path() + "." + typ.Obj().Name()) } - return llvmType, nil + return llvmType } return c.getLLVMType(typ.Underlying()) case *types.Pointer: - ptrTo, err := c.getLLVMType(typ.Elem()) - if err != nil { - return llvm.Type{}, err - } - return llvm.PointerType(ptrTo, 0), nil + ptrTo := c.getLLVMType(typ.Elem()) + return llvm.PointerType(ptrTo, 0) case *types.Signature: // function value return c.getFuncType(typ) case *types.Slice: - elemType, err := c.getLLVMType(typ.Elem()) - if err != nil { - return llvm.Type{}, err - } + elemType := c.getLLVMType(typ.Elem()) members := []llvm.Type{ llvm.PointerType(elemType, 0), c.uintptrType, // len c.uintptrType, // cap } - return c.ctx.StructType(members, false), nil + return c.ctx.StructType(members, false) case *types.Struct: members := make([]llvm.Type, typ.NumFields()) for i := 0; i < typ.NumFields(); i++ { - member, err := c.getLLVMType(typ.Field(i).Type()) - if err != nil { - return llvm.Type{}, err - } - members[i] = member + members[i] = c.getLLVMType(typ.Field(i).Type()) } if len(members) > 2 && typ.Field(0).Name() == "C union" { // Not a normal struct but a C union emitted by cgo. @@ -520,19 +491,15 @@ func (c *Compiler) getLLVMType(goType types.Type) (llvm.Type, error) { members = append(members, llvm.ArrayType(c.ctx.Int8Type(), int(maxSize-mainTypeSize))) } } - return c.ctx.StructType(members, false), nil + return c.ctx.StructType(members, false) case *types.Tuple: members := make([]llvm.Type, typ.Len()) for i := 0; i < typ.Len(); i++ { - member, err := c.getLLVMType(typ.At(i).Type()) - if err != nil { - return llvm.Type{}, err - } - members[i] = member + members[i] = c.getLLVMType(typ.At(i).Type()) } - return c.ctx.StructType(members, false), nil + return c.ctx.StructType(members, false) default: - return llvm.Type{}, errors.New("todo: unknown type: " + goType.String()) + panic("unknown type: " + goType.String()) } } @@ -584,15 +551,12 @@ func isPointer(typ types.Type) bool { } // Get the DWARF type for this Go type. -func (c *Compiler) getDIType(typ types.Type) (llvm.Metadata, error) { +func (c *Compiler) getDIType(typ types.Type) llvm.Metadata { name := typ.String() if dityp, ok := c.ditypes[name]; ok { - return dityp, nil + return dityp } else { - llvmType, err := c.getLLVMType(typ) - if err != nil { - return llvm.Metadata{}, err - } + llvmType := c.getLLVMType(typ) sizeInBytes := c.targetData.TypeAllocSize(llvmType) var encoding llvm.DwarfTypeEncoding switch typ := typ.(type) { @@ -620,11 +584,11 @@ func (c *Compiler) getDIType(typ types.Type) (llvm.Metadata, error) { Encoding: encoding, }) c.ditypes[name] = dityp - return dityp, nil + return dityp } } -func (c *Compiler) parseFuncDecl(f *ir.Function) (*Frame, error) { +func (c *Compiler) parseFuncDecl(f *ir.Function) *Frame { frame := &Frame{ fn: f, locals: make(map[ssa.Value]llvm.Value), @@ -636,29 +600,18 @@ func (c *Compiler) parseFuncDecl(f *ir.Function) (*Frame, error) { if f.Signature.Results() == nil { retType = c.ctx.VoidType() } else if f.Signature.Results().Len() == 1 { - var err error - retType, err = c.getLLVMType(f.Signature.Results().At(0).Type()) - if err != nil { - return nil, err - } + retType = c.getLLVMType(f.Signature.Results().At(0).Type()) } else { results := make([]llvm.Type, 0, f.Signature.Results().Len()) for i := 0; i < f.Signature.Results().Len(); i++ { - typ, err := c.getLLVMType(f.Signature.Results().At(i).Type()) - if err != nil { - return nil, err - } - results = append(results, typ) + results = append(results, c.getLLVMType(f.Signature.Results().At(i).Type())) } retType = c.ctx.StructType(results, false) } var paramTypes []llvm.Type for _, param := range f.Params { - paramType, err := c.getLLVMType(param.Type()) - if err != nil { - return nil, err - } + paramType := c.getLLVMType(param.Type()) paramTypeFragments := c.expandFormalParamType(paramType) paramTypes = append(paramTypes, paramTypeFragments...) } @@ -678,15 +631,15 @@ func (c *Compiler) parseFuncDecl(f *ir.Function) (*Frame, error) { frame.fn.LLVMFn = llvm.AddFunction(c.mod, name, fnType) } - return frame, nil + return frame } -func (c *Compiler) attachDebugInfo(f *ir.Function) (llvm.Metadata, error) { +func (c *Compiler) attachDebugInfo(f *ir.Function) llvm.Metadata { pos := c.ir.Program.Fset.Position(f.Syntax().Pos()) return c.attachDebugInfoRaw(f, f.LLVMFn, "", pos.Filename, pos.Line) } -func (c *Compiler) attachDebugInfoRaw(f *ir.Function, llvmFn llvm.Value, suffix, filename string, line int) (llvm.Metadata, error) { +func (c *Compiler) attachDebugInfoRaw(f *ir.Function, llvmFn llvm.Value, suffix, filename string, line int) llvm.Metadata { if _, ok := c.difiles[filename]; !ok { dir, file := filepath.Split(filename) if dir != "" { @@ -698,11 +651,7 @@ func (c *Compiler) attachDebugInfoRaw(f *ir.Function, llvmFn llvm.Value, suffix, // Debug info for this function. diparams := make([]llvm.Metadata, 0, len(f.Params)) for _, param := range f.Params { - ditype, err := c.getDIType(param.Type()) - if err != nil { - return llvm.Metadata{}, err - } - diparams = append(diparams, ditype) + diparams = append(diparams, c.getDIType(param.Type())) } diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{ File: c.difiles[filename], @@ -722,7 +671,7 @@ func (c *Compiler) attachDebugInfoRaw(f *ir.Function, llvmFn llvm.Value, suffix, Optimized: true, }) llvmFn.SetSubprogram(difunc) - return difunc, nil + return difunc } func (c *Compiler) parseFunc(frame *Frame) error { @@ -742,18 +691,10 @@ func (c *Compiler) parseFunc(frame *Frame) error { if frame.fn.Synthetic == "package initializer" { // Package initializers have no debug info. Create some fake debug // info to at least have *something*. - difunc, err := c.attachDebugInfoRaw(frame.fn, frame.fn.LLVMFn, "", "", 0) - if err != nil { - return err - } - frame.difunc = difunc + frame.difunc = c.attachDebugInfoRaw(frame.fn, frame.fn.LLVMFn, "", "", 0) } else if frame.fn.Syntax() != nil { // Create debug info file if needed. - difunc, err := c.attachDebugInfo(frame.fn) - if err != nil { - return err - } - frame.difunc = difunc + frame.difunc = c.attachDebugInfo(frame.fn) } pos := c.ir.Program.Fset.Position(frame.fn.Pos()) c.builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), frame.difunc, llvm.Metadata{}) @@ -771,10 +712,7 @@ func (c *Compiler) parseFunc(frame *Frame) error { // Load function parameters llvmParamIndex := 0 for i, param := range frame.fn.Params { - llvmType, err := c.getLLVMType(param.Type()) - if err != nil { - return err - } + llvmType := c.getLLVMType(param.Type()) fields := make([]llvm.Value, 0, 1) for range c.expandFormalParamType(llvmType) { fields = append(fields, frame.fn.LLVMFn.Param(llvmParamIndex)) @@ -785,15 +723,11 @@ func (c *Compiler) parseFunc(frame *Frame) error { // Add debug information to this parameter (if available) if c.Debug && frame.fn.Syntax() != nil { pos := c.ir.Program.Fset.Position(frame.fn.Syntax().Pos()) - dityp, err := c.getDIType(param.Type()) - if err != nil { - return err - } c.dibuilder.CreateParameterVariable(frame.difunc, llvm.DIParameterVariable{ Name: param.Name(), File: c.difiles[pos.Filename], Line: pos.Line, - Type: dityp, + Type: c.getDIType(param.Type()), AlwaysPreserve: true, ArgNo: i + 1, }) @@ -814,11 +748,7 @@ func (c *Compiler) parseFunc(frame *Frame) error { // Determine the context type. It's a struct containing all variables. freeVarTypes := make([]llvm.Type, 0, len(frame.fn.FreeVars)) for _, freeVar := range frame.fn.FreeVars { - typ, err := c.getLLVMType(freeVar.Type()) - if err != nil { - return err - } - freeVarTypes = append(freeVarTypes, typ) + freeVarTypes = append(freeVarTypes, c.getLLVMType(freeVar.Type())) } contextType := c.ctx.StructType(freeVarTypes, false) @@ -1346,10 +1276,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { switch expr := expr.(type) { case *ssa.Alloc: - typ, err := c.getLLVMType(expr.Type().Underlying().(*types.Pointer).Elem()) - if err != nil { - return llvm.Value{}, err - } + typ := c.getLLVMType(expr.Type().Underlying().(*types.Pointer).Elem()) var buf llvm.Value if expr.Heap { size := c.targetData.TypeAllocSize(typ) @@ -1400,10 +1327,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { if err != nil { return llvm.Value{}, err } - llvmType, err := c.getLLVMType(expr.Type()) - if err != nil { - return llvm.Value{}, err - } + llvmType := c.getLLVMType(expr.Type()) if x.Type() == llvmType { // Different Go type but same LLVM type (for example, named int). // This is the common case. @@ -1452,10 +1376,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { // Extract a field from a CGo union. // This could be done directly, but as this is a very infrequent // operation it's much easier to bitcast it through an alloca. - resultType, err := c.getLLVMType(expr.Type()) - if err != nil { - return llvm.Value{}, err - } + resultType := c.getLLVMType(expr.Type()) alloca := c.builder.CreateAlloca(value.Type(), "") c.builder.CreateStore(value, alloca) bitcast := c.builder.CreateBitCast(alloca, llvm.PointerType(resultType, 0), "") @@ -1477,10 +1398,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { // This is not a regular struct but actually an union. // That simplifies things, as we can just bitcast the pointer to the // right type. - ptrType, err := c.getLLVMType(expr.Type()) - if err != nil { - return llvm.Value{}, nil - } + ptrType := c.getLLVMType(expr.Type()) return c.builder.CreateBitCast(val, ptrType, ""), nil } else { // Do a GEP on the pointer to get the field address. @@ -1495,7 +1413,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { if fn.IsExported() { return llvm.Value{}, c.makeError(expr.Pos(), "cannot use an exported function as value") } - return c.createFuncValue(fn.LLVMFn, llvm.Undef(c.i8ptrType), fn.Signature) + return c.createFuncValue(fn.LLVMFn, llvm.Undef(c.i8ptrType), fn.Signature), nil case *ssa.Global: value := c.ir.GetGlobal(expr).LLVMGlobal if value.IsNil() { @@ -1620,14 +1538,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { return c.parseMakeInterface(val, expr.X.Type(), expr.Pos()) case *ssa.MakeMap: mapType := expr.Type().Underlying().(*types.Map) - llvmKeyType, err := c.getLLVMType(mapType.Key().Underlying()) - if err != nil { - return llvm.Value{}, err - } - llvmValueType, err := c.getLLVMType(mapType.Elem().Underlying()) - if err != nil { - return llvm.Value{}, err - } + llvmKeyType := c.getLLVMType(mapType.Key().Underlying()) + llvmValueType := c.getLLVMType(mapType.Elem().Underlying()) keySize := c.targetData.TypeAllocSize(llvmKeyType) valueSize := c.targetData.TypeAllocSize(llvmValueType) llvmKeySize := llvm.ConstInt(c.ctx.Int8Type(), keySize, false) @@ -1644,10 +1556,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { return llvm.Value{}, nil } sliceType := expr.Type().Underlying().(*types.Slice) - llvmElemType, err := c.getLLVMType(sliceType.Elem()) - if err != nil { - return llvm.Value{}, nil - } + llvmElemType := c.getLLVMType(sliceType.Elem()) elemSize := c.targetData.TypeAllocSize(llvmElemType) elemSizeValue := llvm.ConstInt(c.uintptrType, elemSize, false) @@ -1707,14 +1616,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { if expr.IsString { return c.createRuntimeCall("stringNext", []llvm.Value{llvmRangeVal, it}, "range.next"), nil } else { // map - llvmKeyType, err := c.getLLVMType(rangeVal.Type().Underlying().(*types.Map).Key()) - if err != nil { - return llvm.Value{}, err - } - llvmValueType, err := c.getLLVMType(rangeVal.Type().Underlying().(*types.Map).Elem()) - if err != nil { - return llvm.Value{}, err - } + llvmKeyType := c.getLLVMType(rangeVal.Type().Underlying().(*types.Map).Key()) + llvmValueType := c.getLLVMType(rangeVal.Type().Underlying().(*types.Map).Elem()) mapKeyAlloca := c.builder.CreateAlloca(llvmKeyType, "range.key") mapKeyPtr := c.builder.CreateBitCast(mapKeyAlloca, c.i8ptrType, "range.keyptr") @@ -1729,11 +1632,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { return tuple, nil } case *ssa.Phi: - t, err := c.getLLVMType(expr.Type()) - if err != nil { - return llvm.Value{}, err - } - phi := c.builder.CreatePHI(t, "") + phi := c.builder.CreatePHI(c.getLLVMType(expr.Type()), "") frame.phis = append(frame.phis, Phi{expr, phi}) return phi, nil case *ssa.Range: @@ -1752,10 +1651,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { case *ssa.Select: if len(expr.States) == 0 { // Shortcuts for some simple selects. - llvmType, err := c.getLLVMType(expr.Type()) - if err != nil { - return llvm.Value{}, err - } + llvmType := c.getLLVMType(expr.Type()) if expr.Blocking { // Blocks forever: // select {} @@ -2225,10 +2121,7 @@ func (c *Compiler) parseBinOp(op token.Token, typ types.Type, x, y llvm.Value, p func (c *Compiler) parseConst(prefix string, expr *ssa.Const) (llvm.Value, error) { switch typ := expr.Type().Underlying().(type) { case *types.Basic: - llvmType, err := c.getLLVMType(typ) - if err != nil { - return llvm.Value{}, err - } + llvmType := c.getLLVMType(typ) if typ.Info()&types.IsBoolean != 0 { b := constant.BoolVal(expr.Value) n := uint64(0) @@ -2294,20 +2187,12 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) (llvm.Value, error return llvm.Value{}, errors.New("todo: unknown constant: " + expr.String()) } case *types.Chan: - sig, err := c.getLLVMType(expr.Type()) - if err != nil { - return llvm.Value{}, err - } - return c.getZeroValue(sig), nil + return c.getZeroValue(c.getLLVMType(expr.Type())), nil case *types.Signature: if expr.Value != nil { return llvm.Value{}, errors.New("non-nil signature constant") } - sig, err := c.getLLVMType(expr.Type()) - if err != nil { - return llvm.Value{}, err - } - return c.getZeroValue(sig), nil + return c.getZeroValue(c.getLLVMType(expr.Type())), nil case *types.Interface: if expr.Value != nil { return llvm.Value{}, errors.New("non-nil interface constant") @@ -2323,19 +2208,12 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) (llvm.Value, error if expr.Value != nil { return llvm.Value{}, errors.New("non-nil pointer constant") } - llvmType, err := c.getLLVMType(typ) - if err != nil { - return llvm.Value{}, err - } - return llvm.ConstPointerNull(llvmType), nil + return llvm.ConstPointerNull(c.getLLVMType(typ)), nil case *types.Slice: if expr.Value != nil { return llvm.Value{}, errors.New("non-nil slice constant") } - elemType, err := c.getLLVMType(typ.Elem()) - if err != nil { - return llvm.Value{}, err - } + elemType := c.getLLVMType(typ.Elem()) llvmPtr := llvm.ConstPointerNull(llvm.PointerType(elemType, 0)) llvmLen := llvm.ConstInt(c.uintptrType, 0, false) slice := c.ctx.ConstStruct([]llvm.Value{ @@ -2349,10 +2227,7 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) (llvm.Value, error // I believe this is not allowed by the Go spec. panic("non-nil map constant") } - llvmType, err := c.getLLVMType(typ) - if err != nil { - return llvm.Value{}, err - } + llvmType := c.getLLVMType(typ) return c.getZeroValue(llvmType), nil default: return llvm.Value{}, errors.New("todo: unknown constant: " + expr.String()) @@ -2361,10 +2236,7 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) (llvm.Value, error func (c *Compiler) parseConvert(typeFrom, typeTo types.Type, value llvm.Value, pos token.Pos) (llvm.Value, error) { llvmTypeFrom := value.Type() - llvmTypeTo, err := c.getLLVMType(typeTo) - if err != nil { - return llvm.Value{}, err - } + llvmTypeTo := c.getLLVMType(typeTo) // Conversion between unsafe.Pointer and uintptr. isPtrFrom := isPointer(typeFrom.Underlying()) diff --git a/compiler/defer.go b/compiler/defer.go index 0bdd5d09..35408a07 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -217,11 +217,7 @@ func (c *Compiler) emitRunDefers(frame *Frame) error { // Get the real defer struct type and cast to it. valueTypes := []llvm.Type{c.uintptrType, llvm.PointerType(c.mod.GetTypeByName("runtime._defer"), 0), c.i8ptrType} for _, arg := range callback.Args { - llvmType, err := c.getLLVMType(arg.Type()) - if err != nil { - return err - } - valueTypes = append(valueTypes, llvmType) + valueTypes = append(valueTypes, c.getLLVMType(arg.Type())) } deferFrameType := c.ctx.StructType(valueTypes, false) deferFramePtr := c.builder.CreateBitCast(deferData, llvm.PointerType(deferFrameType, 0), "deferFrame") @@ -255,11 +251,7 @@ func (c *Compiler) emitRunDefers(frame *Frame) error { // Get the real defer struct type and cast to it. valueTypes := []llvm.Type{c.uintptrType, llvm.PointerType(c.mod.GetTypeByName("runtime._defer"), 0)} for _, param := range callback.Params { - llvmType, err := c.getLLVMType(param.Type()) - if err != nil { - return err - } - valueTypes = append(valueTypes, llvmType) + valueTypes = append(valueTypes, c.getLLVMType(param.Type())) } deferFrameType := c.ctx.StructType(valueTypes, false) deferFramePtr := c.builder.CreateBitCast(deferData, llvm.PointerType(deferFrameType, 0), "deferFrame") @@ -289,11 +281,7 @@ func (c *Compiler) emitRunDefers(frame *Frame) error { valueTypes := []llvm.Type{c.uintptrType, llvm.PointerType(c.mod.GetTypeByName("runtime._defer"), 0)} params := fn.Signature.Params() for i := 0; i < params.Len(); i++ { - llvmType, err := c.getLLVMType(params.At(i).Type()) - if err != nil { - return err - } - valueTypes = append(valueTypes, llvmType) + valueTypes = append(valueTypes, c.getLLVMType(params.At(i).Type())) } valueTypes = append(valueTypes, c.i8ptrType) // closure deferFrameType := c.ctx.StructType(valueTypes, false) diff --git a/compiler/func.go b/compiler/func.go index 29ceb613..f10da115 100644 --- a/compiler/func.go +++ b/compiler/func.go @@ -41,7 +41,7 @@ func (c *Compiler) funcImplementation() funcValueImplementation { // createFuncValue creates a function value from a raw function pointer with no // context. -func (c *Compiler) createFuncValue(funcPtr, context llvm.Value, sig *types.Signature) (llvm.Value, error) { +func (c *Compiler) createFuncValue(funcPtr, context llvm.Value, sig *types.Signature) llvm.Value { var funcValueScalar llvm.Value switch c.funcImplementation() { case funcValueDoubleword: @@ -66,14 +66,11 @@ func (c *Compiler) createFuncValue(funcPtr, context llvm.Value, sig *types.Signa default: panic("unimplemented func value variant") } - funcValueType, err := c.getFuncType(sig) - if err != nil { - return llvm.Value{}, err - } + funcValueType := c.getFuncType(sig) funcValue := llvm.Undef(funcValueType) funcValue = c.builder.CreateInsertValue(funcValue, context, 0, "") funcValue = c.builder.CreateInsertValue(funcValue, funcValueScalar, 1, "") - return funcValue, nil + return funcValue } // getFuncSignature returns a global for identification of a particular function @@ -112,10 +109,7 @@ func (c *Compiler) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) ( case funcValueDoubleword: funcPtr = c.builder.CreateExtractValue(funcValue, 1, "") case funcValueSwitch: - llvmSig, err := c.getRawFuncType(sig) - if err != nil { - return llvm.Value{}, llvm.Value{}, err - } + llvmSig := c.getRawFuncType(sig) sigGlobal := c.getFuncSignature(sig) funcPtr = c.createRuntimeCall("getFuncPtr", []llvm.Value{funcValue, sigGlobal}, "") funcPtr = c.builder.CreateIntToPtr(funcPtr, llvmSig, "") @@ -126,25 +120,21 @@ func (c *Compiler) decodeFuncValue(funcValue llvm.Value, sig *types.Signature) ( } // getFuncType returns the type of a func value given a signature. -func (c *Compiler) getFuncType(typ *types.Signature) (llvm.Type, error) { +func (c *Compiler) getFuncType(typ *types.Signature) llvm.Type { switch c.funcImplementation() { case funcValueDoubleword: - rawPtr, err := c.getRawFuncType(typ) - if err != nil { - return llvm.Type{}, err - } - return c.ctx.StructType([]llvm.Type{c.i8ptrType, rawPtr}, false), nil + rawPtr := c.getRawFuncType(typ) + return c.ctx.StructType([]llvm.Type{c.i8ptrType, rawPtr}, false) case funcValueSwitch: - return c.mod.GetTypeByName("runtime.funcValue"), nil + return c.mod.GetTypeByName("runtime.funcValue") default: panic("unimplemented func value variant") } } // getRawFuncType returns a LLVM function pointer type for a given signature. -func (c *Compiler) getRawFuncType(typ *types.Signature) (llvm.Type, error) { +func (c *Compiler) getRawFuncType(typ *types.Signature) llvm.Type { // Get the return type. - var err error var returnType llvm.Type switch typ.Results().Len() { case 0: @@ -152,21 +142,14 @@ func (c *Compiler) getRawFuncType(typ *types.Signature) (llvm.Type, error) { returnType = c.ctx.VoidType() case 1: // Just one return value. - returnType, err = c.getLLVMType(typ.Results().At(0).Type()) - if err != nil { - return llvm.Type{}, err - } + returnType = c.getLLVMType(typ.Results().At(0).Type()) default: // Multiple return values. Put them together in a struct. // This appears to be the common way to handle multiple return values in // LLVM. members := make([]llvm.Type, typ.Results().Len()) for i := 0; i < typ.Results().Len(); i++ { - returnType, err := c.getLLVMType(typ.Results().At(i).Type()) - if err != nil { - return llvm.Type{}, err - } - members[i] = returnType + members[i] = c.getLLVMType(typ.Results().At(i).Type()) } returnType = c.ctx.StructType(members, false) } @@ -174,10 +157,7 @@ func (c *Compiler) getRawFuncType(typ *types.Signature) (llvm.Type, error) { // Get the parameter types. var paramTypes []llvm.Type if typ.Recv() != nil { - recv, err := c.getLLVMType(typ.Recv().Type()) - if err != nil { - return llvm.Type{}, err - } + recv := c.getLLVMType(typ.Recv().Type()) if recv.StructName() == "runtime._interface" { // This is a call on an interface, not a concrete type. // The receiver is not an interface, but a i8* type. @@ -186,10 +166,7 @@ func (c *Compiler) getRawFuncType(typ *types.Signature) (llvm.Type, error) { paramTypes = append(paramTypes, c.expandFormalParamType(recv)...) } for i := 0; i < typ.Params().Len(); i++ { - subType, err := c.getLLVMType(typ.Params().At(i).Type()) - if err != nil { - return llvm.Type{}, err - } + subType := c.getLLVMType(typ.Params().At(i).Type()) paramTypes = append(paramTypes, c.expandFormalParamType(subType)...) } // All functions take these parameters at the end. @@ -197,7 +174,7 @@ func (c *Compiler) getRawFuncType(typ *types.Signature) (llvm.Type, error) { paramTypes = append(paramTypes, c.i8ptrType) // parent coroutine // Make a func type out of the signature. - return llvm.PointerType(llvm.FunctionType(returnType, paramTypes, false), c.funcPtrAddrSpace), nil + return llvm.PointerType(llvm.FunctionType(returnType, paramTypes, false), c.funcPtrAddrSpace) } // parseMakeClosure makes a function value (with context) from the given @@ -261,5 +238,5 @@ func (c *Compiler) parseMakeClosure(frame *Frame, expr *ssa.MakeClosure) (llvm.V } // Create the closure. - return c.createFuncValue(f.LLVMFn, context, f.Signature) + return c.createFuncValue(f.LLVMFn, context, f.Signature), nil } diff --git a/compiler/interface.go b/compiler/interface.go index 94299a91..999ce30b 100644 --- a/compiler/interface.go +++ b/compiler/interface.go @@ -279,10 +279,7 @@ func (c *Compiler) parseTypeAssert(frame *Frame, expr *ssa.TypeAssert) (llvm.Val if err != nil { return llvm.Value{}, err } - assertedType, err := c.getLLVMType(expr.AssertedType) - if err != nil { - return llvm.Value{}, err - } + assertedType := c.getLLVMType(expr.AssertedType) actualTypeNum := c.builder.CreateExtractValue(itf, 0, "interface.type") commaOk := llvm.Value{} @@ -389,10 +386,7 @@ func (c *Compiler) getInvokeCall(frame *Frame, instr *ssa.CallCommon) (llvm.Valu return llvm.Value{}, nil, err } - llvmFnType, err := c.getRawFuncType(instr.Method.Type().(*types.Signature)) - if err != nil { - return llvm.Value{}, nil, err - } + llvmFnType := c.getRawFuncType(instr.Method.Type().(*types.Signature)) typecode := c.builder.CreateExtractValue(itf, 0, "invoke.typecode") values := []llvm.Value{ @@ -443,10 +437,7 @@ func (c *Compiler) getInterfaceInvokeWrapper(f *ir.Function) (llvm.Value, error) } // Get the expanded receiver type. - receiverType, err := c.getLLVMType(f.Params[0].Type()) - if err != nil { - return llvm.Value{}, err - } + receiverType := c.getLLVMType(f.Params[0].Type()) expandedReceiverType := c.expandFormalParamType(receiverType) // Does this method even need any wrapping? @@ -473,7 +464,7 @@ func (c *Compiler) getInterfaceInvokeWrapper(f *ir.Function) (llvm.Value, error) // createInterfaceInvokeWrapper finishes the work of getInterfaceInvokeWrapper, // see that function for details. -func (c *Compiler) createInterfaceInvokeWrapper(state interfaceInvokeWrapper) error { +func (c *Compiler) createInterfaceInvokeWrapper(state interfaceInvokeWrapper) { wrapper := state.wrapper fn := state.fn receiverType := state.receiverType @@ -483,10 +474,7 @@ func (c *Compiler) createInterfaceInvokeWrapper(state interfaceInvokeWrapper) er // add debug info if needed if c.Debug { pos := c.ir.Program.Fset.Position(fn.Pos()) - difunc, err := c.attachDebugInfoRaw(fn, wrapper, "$invoke", pos.Filename, pos.Line) - if err != nil { - return err - } + difunc := c.attachDebugInfoRaw(fn, wrapper, "$invoke", pos.Filename, pos.Line) c.builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{}) } @@ -524,6 +512,4 @@ func (c *Compiler) createInterfaceInvokeWrapper(state interfaceInvokeWrapper) er ret := c.builder.CreateCall(fn.LLVMFn, params, "ret") c.builder.CreateRet(ret) } - - return nil } diff --git a/compiler/map.go b/compiler/map.go index dc5ddead..f8531191 100644 --- a/compiler/map.go +++ b/compiler/map.go @@ -10,10 +10,7 @@ import ( ) func (c *Compiler) emitMapLookup(keyType, valueType types.Type, m, key llvm.Value, commaOk bool, pos token.Pos) (llvm.Value, error) { - llvmValueType, err := c.getLLVMType(valueType) - if err != nil { - return llvm.Value{}, err - } + llvmValueType := c.getLLVMType(valueType) mapValueAlloca := c.builder.CreateAlloca(llvmValueType, "hashmap.value") mapValuePtr := c.builder.CreateBitCast(mapValueAlloca, c.i8ptrType, "hashmap.valueptr") var commaOkValue llvm.Value