aboutsummaryrefslogtreecommitdiffhomepage
path: root/compiler
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2019-09-15 16:42:31 +0200
committerRon Evans <[email protected]>2019-09-15 19:09:10 +0200
commit10ed3decb076c88077ccd849029357e1c2c33f7c (patch)
tree8c78d0c16530e61ff3315f1051f9315ea915d1fa /compiler
parent8d959b7c636a392046558046e9b423efb2c288bb (diff)
downloadtinygo-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.go2
-rw-r--r--compiler/channel.go2
-rw-r--r--compiler/compiler.go50
-rw-r--r--compiler/defer.go2
-rw-r--r--compiler/gc.go6
-rw-r--r--compiler/interface.go8
-rw-r--r--compiler/optimizer.go2
-rw-r--r--compiler/symbol.go2
-rw-r--r--compiler/wordpack.go2
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{