diff options
-rw-r--r-- | compiler/calls.go | 2 | ||||
-rw-r--r-- | compiler/channel.go | 2 | ||||
-rw-r--r-- | compiler/compiler.go | 50 | ||||
-rw-r--r-- | compiler/defer.go | 2 | ||||
-rw-r--r-- | compiler/gc.go | 6 | ||||
-rw-r--r-- | compiler/interface.go | 8 | ||||
-rw-r--r-- | compiler/optimizer.go | 2 | ||||
-rw-r--r-- | compiler/symbol.go | 2 | ||||
-rw-r--r-- | compiler/wordpack.go | 2 | ||||
-rw-r--r-- | interp/frame.go | 8 | ||||
-rw-r--r-- | interp/utils.go | 44 | ||||
-rw-r--r-- | interp/values.go | 4 |
12 files changed, 26 insertions, 106 deletions
diff --git a/compiler/calls.go b/compiler/calls.go index 406122f53..3cb4c12c7 100644 --- a/compiler/calls.go +++ b/compiler/calls.go @@ -163,7 +163,7 @@ func (c *Compiler) collapseFormalParamInternal(t llvm.Type, fields []llvm.Value) switch t.TypeKind() { case llvm.StructTypeKind: if len(c.flattenAggregateType(t)) <= MaxFieldsPerParam { - value := c.getZeroValue(t) + value := llvm.ConstNull(t) for i, subtyp := range t.StructElementTypes() { structField, remaining := c.collapseFormalParamInternal(subtyp, fields) fields = remaining diff --git a/compiler/channel.go b/compiler/channel.go index e04d58969..55fb6920d 100644 --- a/compiler/channel.go +++ b/compiler/channel.go @@ -124,7 +124,7 @@ func (c *Compiler) emitSelect(frame *Frame, expr *ssa.Select) llvm.Value { chanSelectStateType := c.getLLVMRuntimeType("chanSelectState") for _, state := range expr.States { ch := c.getValue(frame, state.Chan) - selectState := c.getZeroValue(chanSelectStateType) + selectState := llvm.ConstNull(chanSelectStateType) selectState = c.builder.CreateInsertValue(selectState, ch, 0, "") switch state.Dir { case types.RecvOnly: diff --git a/compiler/compiler.go b/compiler/compiler.go index f64b67901..050e7107a 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -563,42 +563,6 @@ func (c *Compiler) getLLVMType(goType types.Type) llvm.Type { } } -// Return a zero LLVM value for any LLVM type. Setting this value as an -// initializer has the same effect as setting 'zeroinitializer' on a value. -// Sadly, I haven't found a way to do it directly with the Go API but this works -// just fine. -func (c *Compiler) getZeroValue(typ llvm.Type) llvm.Value { - switch typ.TypeKind() { - case llvm.ArrayTypeKind: - subTyp := typ.ElementType() - subVal := c.getZeroValue(subTyp) - vals := make([]llvm.Value, typ.ArrayLength()) - for i := range vals { - vals[i] = subVal - } - return llvm.ConstArray(subTyp, vals) - case llvm.FloatTypeKind, llvm.DoubleTypeKind: - return llvm.ConstFloat(typ, 0.0) - case llvm.IntegerTypeKind: - return llvm.ConstInt(typ, 0, false) - case llvm.PointerTypeKind: - return llvm.ConstPointerNull(typ) - case llvm.StructTypeKind: - types := typ.StructElementTypes() - vals := make([]llvm.Value, len(types)) - for i, subTyp := range types { - vals[i] = c.getZeroValue(subTyp) - } - if typ.StructName() != "" { - return llvm.ConstNamedStruct(typ, vals) - } else { - return c.ctx.ConstStruct(vals, false) - } - default: - panic("unknown LLVM zero inititializer: " + typ.String()) - } -} - // Is this a pointer type of some sort? Can be unsafe.Pointer or any *T pointer. func isPointer(typ types.Type) bool { if _, ok := typ.(*types.Pointer); ok { @@ -1132,7 +1096,7 @@ func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) { c.builder.CreateRet(c.getValue(frame, instr.Results[0])) } else { // Multiple return values. Put them all in a struct. - retVal := c.getZeroValue(frame.fn.LLVMFn.Type().ElementType().ReturnType()) + retVal := llvm.ConstNull(frame.fn.LLVMFn.Type().ElementType().ReturnType()) for i, result := range instr.Results { val := c.getValue(frame, result) retVal = c.builder.CreateInsertValue(retVal, val, i, "") @@ -1460,7 +1424,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { } else { buf := c.createEntryBlockAlloca(typ, expr.Comment) if c.targetData.TypeAllocSize(typ) != 0 { - c.builder.CreateStore(c.getZeroValue(typ), buf) // zero-initialize var + c.builder.CreateStore(llvm.ConstNull(typ), buf) // zero-initialize var } return buf, nil } @@ -1767,7 +1731,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { panic("unknown type in range: " + typ.String()) } it, _, _ := c.createTemporaryAlloca(iteratorType, "range.it") - c.builder.CreateStore(c.getZeroValue(iteratorType), it) + c.builder.CreateStore(llvm.ConstNull(iteratorType), it) return it, nil case *ssa.Select: return c.emitSelect(frame, expr), nil @@ -2349,12 +2313,12 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) llvm.Value { if expr.Value != nil { panic("expected nil chan constant") } - return c.getZeroValue(c.getLLVMType(expr.Type())) + return llvm.ConstNull(c.getLLVMType(expr.Type())) case *types.Signature: if expr.Value != nil { panic("expected nil signature constant") } - return c.getZeroValue(c.getLLVMType(expr.Type())) + return llvm.ConstNull(c.getLLVMType(expr.Type())) case *types.Interface: if expr.Value != nil { panic("expected nil interface constant") @@ -2389,7 +2353,7 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) llvm.Value { panic("non-nil map constant") } llvmType := c.getLLVMType(typ) - return c.getZeroValue(llvmType) + return llvm.ConstNull(llvmType) default: panic("unknown constant: " + expr.String()) } @@ -2581,7 +2545,7 @@ func (c *Compiler) parseUnOp(frame *Frame, unop *ssa.UnOp) (llvm.Value, error) { unop.X.Type().Underlying().(*types.Pointer).Elem() if c.targetData.TypeAllocSize(x.Type().ElementType()) == 0 { // zero-length data - return c.getZeroValue(x.Type().ElementType()), nil + return llvm.ConstNull(x.Type().ElementType()), nil } else if strings.HasSuffix(unop.X.String(), "$funcaddr") { // CGo function pointer. The cgo part has rewritten CGo function // pointers as stub global variables of the form: diff --git a/compiler/defer.go b/compiler/defer.go index d929ea576..c408b6e78 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -122,7 +122,7 @@ func (c *Compiler) emitDefer(frame *Frame, instr *ssa.Defer) { // Make a struct out of the collected values to put in the defer frame. deferFrameType := c.ctx.StructType(valueTypes, false) - deferFrame := c.getZeroValue(deferFrameType) + deferFrame := llvm.ConstNull(deferFrameType) for i, value := range values { deferFrame = c.builder.CreateInsertValue(deferFrame, value, i, "") } diff --git a/compiler/gc.go b/compiler/gc.go index d9679efca..87fed6b16 100644 --- a/compiler/gc.go +++ b/compiler/gc.go @@ -134,7 +134,7 @@ func (c *Compiler) makeGCStackSlots() bool { } stackChainStart := c.mod.NamedGlobal("runtime.stackChainStart") if !stackChainStart.IsNil() { - stackChainStart.SetInitializer(c.getZeroValue(stackChainStart.Type().ElementType())) + stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.Type().ElementType())) stackChainStart.SetGlobalConstant(true) } } @@ -198,7 +198,7 @@ func (c *Compiler) makeGCStackSlots() bool { panic("stack chain start not found!") } stackChainStartType := stackChainStart.Type().ElementType() - stackChainStart.SetInitializer(c.getZeroValue(stackChainStartType)) + stackChainStart.SetInitializer(llvm.ConstNull(stackChainStartType)) // Iterate until runtime.trackPointer has no uses left. for use := trackPointer.FirstUse(); !use.IsNil(); use = trackPointer.FirstUse() { @@ -303,7 +303,7 @@ func (c *Compiler) makeGCStackSlots() bool { // Create the stack object at the function entry. c.builder.SetInsertPointBefore(fn.EntryBasicBlock().FirstInstruction()) stackObject := c.builder.CreateAlloca(stackObjectType, "gc.stackobject") - initialStackObject := c.getZeroValue(stackObjectType) + initialStackObject := llvm.ConstNull(stackObjectType) numSlots := (c.targetData.TypeAllocSize(stackObjectType) - c.targetData.TypeAllocSize(c.i8ptrType)*2) / uint64(c.targetData.ABITypeAlignment(c.uintptrType)) numSlotsValue := llvm.ConstInt(c.uintptrType, numSlots, false) initialStackObject = llvm.ConstInsertValue(initialStackObject, numSlotsValue, []uint32{1}) diff --git a/compiler/interface.go b/compiler/interface.go index 4d2995ba6..672f7a17b 100644 --- a/compiler/interface.go +++ b/compiler/interface.go @@ -74,7 +74,7 @@ func (c *Compiler) getTypeCode(typ types.Type) llvm.Value { } if !references.IsNil() { // Set the 'references' field of the runtime.typecodeID struct. - globalValue := c.getZeroValue(global.Type().ElementType()) + globalValue := llvm.ConstNull(global.Type().ElementType()) globalValue = llvm.ConstInsertValue(globalValue, references, []uint32{0}) if length != 0 { lengthValue := llvm.ConstInt(c.uintptrType, uint64(length), false) @@ -96,9 +96,9 @@ func (c *Compiler) makeStructTypeFields(typ *types.Struct) llvm.Value { runtimeStructField := c.getLLVMRuntimeType("structField") structGlobalType := llvm.ArrayType(runtimeStructField, typ.NumFields()) structGlobal := llvm.AddGlobal(c.mod, structGlobalType, "reflect/types.structFields") - structGlobalValue := c.getZeroValue(structGlobalType) + structGlobalValue := llvm.ConstNull(structGlobalType) for i := 0; i < typ.NumFields(); i++ { - fieldGlobalValue := c.getZeroValue(runtimeStructField) + fieldGlobalValue := llvm.ConstNull(runtimeStructField) fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), []uint32{0}) fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type()) fieldName.SetLinkage(llvm.PrivateLinkage) @@ -380,7 +380,7 @@ func (c *Compiler) parseTypeAssert(frame *Frame, expr *ssa.TypeAssert) llvm.Valu // Continue after the if statement. c.builder.SetInsertPointAtEnd(nextBlock) phi := c.builder.CreatePHI(assertedType, "typeassert.value") - phi.AddIncoming([]llvm.Value{c.getZeroValue(assertedType), valueOk}, []llvm.BasicBlock{prevBlock, okBlock}) + phi.AddIncoming([]llvm.Value{llvm.ConstNull(assertedType), valueOk}, []llvm.BasicBlock{prevBlock, okBlock}) if expr.CommaOk { tuple := c.ctx.ConstStruct([]llvm.Value{llvm.Undef(assertedType), llvm.Undef(c.ctx.Int1Type())}, false) // create empty tuple diff --git a/compiler/optimizer.go b/compiler/optimizer.go index d06ce489c..00c2c56fb 100644 --- a/compiler/optimizer.go +++ b/compiler/optimizer.go @@ -289,7 +289,7 @@ func (c *Compiler) OptimizeAllocs() { sizeInWords := (size + uint64(alignment) - 1) / uint64(alignment) allocaType := llvm.ArrayType(c.ctx.IntType(alignment*8), int(sizeInWords)) alloca := c.builder.CreateAlloca(allocaType, "stackalloc.alloca") - zero := c.getZeroValue(alloca.Type().ElementType()) + zero := llvm.ConstNull(alloca.Type().ElementType()) c.builder.CreateStore(zero, alloca) stackalloc := c.builder.CreateBitCast(alloca, bitcast.Type(), "stackalloc") bitcast.ReplaceAllUsesWith(stackalloc) diff --git a/compiler/symbol.go b/compiler/symbol.go index 0df2ab6e4..4b8fb08bf 100644 --- a/compiler/symbol.go +++ b/compiler/symbol.go @@ -61,7 +61,7 @@ func (c *Compiler) getGlobal(g *ssa.Global) llvm.Value { llvmType := c.getLLVMType(g.Type().(*types.Pointer).Elem()) llvmGlobal = llvm.AddGlobal(c.mod, llvmType, info.linkName) if !info.extern { - llvmGlobal.SetInitializer(c.getZeroValue(llvmType)) + llvmGlobal.SetInitializer(llvm.ConstNull(llvmType)) llvmGlobal.SetLinkage(llvm.InternalLinkage) } } diff --git a/compiler/wordpack.go b/compiler/wordpack.go index e553cb9c4..513970a1e 100644 --- a/compiler/wordpack.go +++ b/compiler/wordpack.go @@ -101,7 +101,7 @@ func (c *Compiler) emitPointerUnpack(ptr llvm.Value, valueTypes []llvm.Type) []l for i, valueType := range valueTypes { if c.targetData.TypeAllocSize(valueType) == 0 { // This value has length zero, so there's nothing to load. - values[i] = c.getZeroValue(valueType) + values[i] = llvm.ConstNull(valueType) continue } indices := []llvm.Value{ diff --git a/interp/frame.go b/interp/frame.go index 81432ef34..47c59f57e 100644 --- a/interp/frame.go +++ b/interp/frame.go @@ -86,7 +86,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re case !inst.IsAAllocaInst().IsNil(): allocType := inst.Type().ElementType() alloca := llvm.AddGlobal(fr.Mod, allocType, fr.pkgName+"$alloca") - alloca.SetInitializer(getZeroValue(allocType)) + alloca.SetInitializer(llvm.ConstNull(allocType)) alloca.SetLinkage(llvm.InternalLinkage) fr.locals[inst] = &LocalValue{ Underlying: alloca, @@ -253,7 +253,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re allocType = llvm.ArrayType(allocType, elementCount) } alloc := llvm.AddGlobal(fr.Mod, allocType, fr.pkgName+"$alloc") - alloc.SetInitializer(getZeroValue(allocType)) + alloc.SetInitializer(llvm.ConstNull(allocType)) alloc.SetLinkage(llvm.InternalLinkage) result := &LocalValue{ Underlying: alloc, @@ -312,7 +312,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re stringType := fr.Mod.GetTypeByName("runtime._string") retPtr := llvm.ConstGEP(global, getLLVMIndices(fr.Mod.Context().Int32Type(), []uint32{0, 0})) retLen := llvm.ConstInt(stringType.StructElementTypes()[1], uint64(len(result)), false) - ret := getZeroValue(stringType) + ret := llvm.ConstNull(stringType) ret = llvm.ConstInsertValue(ret, retPtr, []uint32{0}) ret = llvm.ConstInsertValue(ret, retLen, []uint32{1}) fr.locals[inst] = &LocalValue{fr.Eval, ret} @@ -335,7 +335,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re sliceType := inst.Type() retPtr := llvm.ConstGEP(global, getLLVMIndices(fr.Mod.Context().Int32Type(), []uint32{0, 0})) retLen := llvm.ConstInt(sliceType.StructElementTypes()[1], uint64(len(result)), false) - ret := getZeroValue(sliceType) + ret := llvm.ConstNull(sliceType) ret = llvm.ConstInsertValue(ret, retPtr, []uint32{0}) // ptr ret = llvm.ConstInsertValue(ret, retLen, []uint32{1}) // len ret = llvm.ConstInsertValue(ret, retLen, []uint32{2}) // cap diff --git a/interp/utils.go b/interp/utils.go index 7910ea8a7..3131e819b 100644 --- a/interp/utils.go +++ b/interp/utils.go @@ -16,50 +16,6 @@ func getUses(value llvm.Value) []llvm.Value { return uses } -// Return a zero LLVM value for any LLVM type. Setting this value as an -// initializer has the same effect as setting 'zeroinitializer' on a value. -// Sadly, I haven't found a way to do it directly with the Go API but this works -// just fine. -func getZeroValue(typ llvm.Type) llvm.Value { - switch typ.TypeKind() { - case llvm.ArrayTypeKind: - subTyp := typ.ElementType() - subVal := getZeroValue(subTyp) - vals := make([]llvm.Value, typ.ArrayLength()) - for i := range vals { - vals[i] = subVal - } - return llvm.ConstArray(subTyp, vals) - case llvm.FloatTypeKind, llvm.DoubleTypeKind: - return llvm.ConstFloat(typ, 0.0) - case llvm.IntegerTypeKind: - return llvm.ConstInt(typ, 0, false) - case llvm.PointerTypeKind: - return llvm.ConstPointerNull(typ) - case llvm.StructTypeKind: - types := typ.StructElementTypes() - vals := make([]llvm.Value, len(types)) - for i, subTyp := range types { - val := getZeroValue(subTyp) - vals[i] = val - } - if typ.StructName() != "" { - return llvm.ConstNamedStruct(typ, vals) - } else { - return typ.Context().ConstStruct(vals, false) - } - case llvm.VectorTypeKind: - zero := getZeroValue(typ.ElementType()) - vals := make([]llvm.Value, typ.VectorSize()) - for i := range vals { - vals[i] = zero - } - return llvm.ConstVector(vals, false) - default: - panic("interp: unknown LLVM type: " + typ.String()) - } -} - // getStringBytes loads the byte slice of a Go string represented as a // {ptr, len} pair. func getStringBytes(strPtr Value, strLen llvm.Value) []byte { diff --git a/interp/values.go b/interp/values.go index 4a1b9739e..ae62f3ffe 100644 --- a/interp/values.go +++ b/interp/values.go @@ -162,7 +162,7 @@ func (v *MapValue) newBucket() llvm.Value { llvm.ArrayType(v.KeyType, 8), // key type llvm.ArrayType(v.ValueType, 8), // value type }, false) - bucketValue := getZeroValue(bucketType) + bucketValue := llvm.ConstNull(bucketType) bucket := llvm.AddGlobal(v.Eval.Mod, bucketType, v.PkgName+"$mapbucket") bucket.SetInitializer(bucketValue) bucket.SetLinkage(llvm.InternalLinkage) @@ -311,7 +311,7 @@ func (v *MapValue) PutString(keyBuf, keyLen, valPtr *LocalValue) { keyType := v.Eval.Mod.GetTypeByName("runtime._string") v.KeyType = keyType - key := getZeroValue(keyType) + key := llvm.ConstNull(keyType) key = llvm.ConstInsertValue(key, keyBuf.Value(), []uint32{0}) key = llvm.ConstInsertValue(key, keyLen.Value(), []uint32{1}) |