diff options
author | Ayke van Laethem <[email protected]> | 2019-09-15 16:42:31 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2019-09-15 19:09:10 +0200 |
commit | 10ed3decb076c88077ccd849029357e1c2c33f7c (patch) | |
tree | 8c78d0c16530e61ff3315f1051f9315ea915d1fa /compiler | |
parent | 8d959b7c636a392046558046e9b423efb2c288bb (diff) | |
download | tinygo-10ed3decb076c88077ccd849029357e1c2c33f7c.tar.gz tinygo-10ed3decb076c88077ccd849029357e1c2c33f7c.zip |
compiler: rename getZeroValue to llvm.ConstNull
It does the same thing but should be more complete, and it probably is
faster as well (just one CGo call instead of several).
Diffstat (limited to 'compiler')
-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 |
9 files changed, 20 insertions, 56 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{ |