Skip to content

Commit 10ed3de

Browse files
aykevldeadprogram
authored andcommitted
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).
1 parent 8d959b7 commit 10ed3de

File tree

12 files changed

+26
-106
lines changed

12 files changed

+26
-106
lines changed

compiler/calls.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ func (c *Compiler) collapseFormalParamInternal(t llvm.Type, fields []llvm.Value)
163163
switch t.TypeKind() {
164164
case llvm.StructTypeKind:
165165
if len(c.flattenAggregateType(t)) <= MaxFieldsPerParam {
166-
value := c.getZeroValue(t)
166+
value := llvm.ConstNull(t)
167167
for i, subtyp := range t.StructElementTypes() {
168168
structField, remaining := c.collapseFormalParamInternal(subtyp, fields)
169169
fields = remaining

compiler/channel.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func (c *Compiler) emitSelect(frame *Frame, expr *ssa.Select) llvm.Value {
124124
chanSelectStateType := c.getLLVMRuntimeType("chanSelectState")
125125
for _, state := range expr.States {
126126
ch := c.getValue(frame, state.Chan)
127-
selectState := c.getZeroValue(chanSelectStateType)
127+
selectState := llvm.ConstNull(chanSelectStateType)
128128
selectState = c.builder.CreateInsertValue(selectState, ch, 0, "")
129129
switch state.Dir {
130130
case types.RecvOnly:

compiler/compiler.go

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -563,42 +563,6 @@ func (c *Compiler) getLLVMType(goType types.Type) llvm.Type {
563563
}
564564
}
565565

566-
// Return a zero LLVM value for any LLVM type. Setting this value as an
567-
// initializer has the same effect as setting 'zeroinitializer' on a value.
568-
// Sadly, I haven't found a way to do it directly with the Go API but this works
569-
// just fine.
570-
func (c *Compiler) getZeroValue(typ llvm.Type) llvm.Value {
571-
switch typ.TypeKind() {
572-
case llvm.ArrayTypeKind:
573-
subTyp := typ.ElementType()
574-
subVal := c.getZeroValue(subTyp)
575-
vals := make([]llvm.Value, typ.ArrayLength())
576-
for i := range vals {
577-
vals[i] = subVal
578-
}
579-
return llvm.ConstArray(subTyp, vals)
580-
case llvm.FloatTypeKind, llvm.DoubleTypeKind:
581-
return llvm.ConstFloat(typ, 0.0)
582-
case llvm.IntegerTypeKind:
583-
return llvm.ConstInt(typ, 0, false)
584-
case llvm.PointerTypeKind:
585-
return llvm.ConstPointerNull(typ)
586-
case llvm.StructTypeKind:
587-
types := typ.StructElementTypes()
588-
vals := make([]llvm.Value, len(types))
589-
for i, subTyp := range types {
590-
vals[i] = c.getZeroValue(subTyp)
591-
}
592-
if typ.StructName() != "" {
593-
return llvm.ConstNamedStruct(typ, vals)
594-
} else {
595-
return c.ctx.ConstStruct(vals, false)
596-
}
597-
default:
598-
panic("unknown LLVM zero inititializer: " + typ.String())
599-
}
600-
}
601-
602566
// Is this a pointer type of some sort? Can be unsafe.Pointer or any *T pointer.
603567
func isPointer(typ types.Type) bool {
604568
if _, ok := typ.(*types.Pointer); ok {
@@ -1132,7 +1096,7 @@ func (c *Compiler) parseInstr(frame *Frame, instr ssa.Instruction) {
11321096
c.builder.CreateRet(c.getValue(frame, instr.Results[0]))
11331097
} else {
11341098
// Multiple return values. Put them all in a struct.
1135-
retVal := c.getZeroValue(frame.fn.LLVMFn.Type().ElementType().ReturnType())
1099+
retVal := llvm.ConstNull(frame.fn.LLVMFn.Type().ElementType().ReturnType())
11361100
for i, result := range instr.Results {
11371101
val := c.getValue(frame, result)
11381102
retVal = c.builder.CreateInsertValue(retVal, val, i, "")
@@ -1460,7 +1424,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
14601424
} else {
14611425
buf := c.createEntryBlockAlloca(typ, expr.Comment)
14621426
if c.targetData.TypeAllocSize(typ) != 0 {
1463-
c.builder.CreateStore(c.getZeroValue(typ), buf) // zero-initialize var
1427+
c.builder.CreateStore(llvm.ConstNull(typ), buf) // zero-initialize var
14641428
}
14651429
return buf, nil
14661430
}
@@ -1767,7 +1731,7 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) {
17671731
panic("unknown type in range: " + typ.String())
17681732
}
17691733
it, _, _ := c.createTemporaryAlloca(iteratorType, "range.it")
1770-
c.builder.CreateStore(c.getZeroValue(iteratorType), it)
1734+
c.builder.CreateStore(llvm.ConstNull(iteratorType), it)
17711735
return it, nil
17721736
case *ssa.Select:
17731737
return c.emitSelect(frame, expr), nil
@@ -2349,12 +2313,12 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) llvm.Value {
23492313
if expr.Value != nil {
23502314
panic("expected nil chan constant")
23512315
}
2352-
return c.getZeroValue(c.getLLVMType(expr.Type()))
2316+
return llvm.ConstNull(c.getLLVMType(expr.Type()))
23532317
case *types.Signature:
23542318
if expr.Value != nil {
23552319
panic("expected nil signature constant")
23562320
}
2357-
return c.getZeroValue(c.getLLVMType(expr.Type()))
2321+
return llvm.ConstNull(c.getLLVMType(expr.Type()))
23582322
case *types.Interface:
23592323
if expr.Value != nil {
23602324
panic("expected nil interface constant")
@@ -2389,7 +2353,7 @@ func (c *Compiler) parseConst(prefix string, expr *ssa.Const) llvm.Value {
23892353
panic("non-nil map constant")
23902354
}
23912355
llvmType := c.getLLVMType(typ)
2392-
return c.getZeroValue(llvmType)
2356+
return llvm.ConstNull(llvmType)
23932357
default:
23942358
panic("unknown constant: " + expr.String())
23952359
}
@@ -2581,7 +2545,7 @@ func (c *Compiler) parseUnOp(frame *Frame, unop *ssa.UnOp) (llvm.Value, error) {
25812545
unop.X.Type().Underlying().(*types.Pointer).Elem()
25822546
if c.targetData.TypeAllocSize(x.Type().ElementType()) == 0 {
25832547
// zero-length data
2584-
return c.getZeroValue(x.Type().ElementType()), nil
2548+
return llvm.ConstNull(x.Type().ElementType()), nil
25852549
} else if strings.HasSuffix(unop.X.String(), "$funcaddr") {
25862550
// CGo function pointer. The cgo part has rewritten CGo function
25872551
// pointers as stub global variables of the form:

compiler/defer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func (c *Compiler) emitDefer(frame *Frame, instr *ssa.Defer) {
122122

123123
// Make a struct out of the collected values to put in the defer frame.
124124
deferFrameType := c.ctx.StructType(valueTypes, false)
125-
deferFrame := c.getZeroValue(deferFrameType)
125+
deferFrame := llvm.ConstNull(deferFrameType)
126126
for i, value := range values {
127127
deferFrame = c.builder.CreateInsertValue(deferFrame, value, i, "")
128128
}

compiler/gc.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (c *Compiler) makeGCStackSlots() bool {
134134
}
135135
stackChainStart := c.mod.NamedGlobal("runtime.stackChainStart")
136136
if !stackChainStart.IsNil() {
137-
stackChainStart.SetInitializer(c.getZeroValue(stackChainStart.Type().ElementType()))
137+
stackChainStart.SetInitializer(llvm.ConstNull(stackChainStart.Type().ElementType()))
138138
stackChainStart.SetGlobalConstant(true)
139139
}
140140
}
@@ -198,7 +198,7 @@ func (c *Compiler) makeGCStackSlots() bool {
198198
panic("stack chain start not found!")
199199
}
200200
stackChainStartType := stackChainStart.Type().ElementType()
201-
stackChainStart.SetInitializer(c.getZeroValue(stackChainStartType))
201+
stackChainStart.SetInitializer(llvm.ConstNull(stackChainStartType))
202202

203203
// Iterate until runtime.trackPointer has no uses left.
204204
for use := trackPointer.FirstUse(); !use.IsNil(); use = trackPointer.FirstUse() {
@@ -303,7 +303,7 @@ func (c *Compiler) makeGCStackSlots() bool {
303303
// Create the stack object at the function entry.
304304
c.builder.SetInsertPointBefore(fn.EntryBasicBlock().FirstInstruction())
305305
stackObject := c.builder.CreateAlloca(stackObjectType, "gc.stackobject")
306-
initialStackObject := c.getZeroValue(stackObjectType)
306+
initialStackObject := llvm.ConstNull(stackObjectType)
307307
numSlots := (c.targetData.TypeAllocSize(stackObjectType) - c.targetData.TypeAllocSize(c.i8ptrType)*2) / uint64(c.targetData.ABITypeAlignment(c.uintptrType))
308308
numSlotsValue := llvm.ConstInt(c.uintptrType, numSlots, false)
309309
initialStackObject = llvm.ConstInsertValue(initialStackObject, numSlotsValue, []uint32{1})

compiler/interface.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (c *Compiler) getTypeCode(typ types.Type) llvm.Value {
7474
}
7575
if !references.IsNil() {
7676
// Set the 'references' field of the runtime.typecodeID struct.
77-
globalValue := c.getZeroValue(global.Type().ElementType())
77+
globalValue := llvm.ConstNull(global.Type().ElementType())
7878
globalValue = llvm.ConstInsertValue(globalValue, references, []uint32{0})
7979
if length != 0 {
8080
lengthValue := llvm.ConstInt(c.uintptrType, uint64(length), false)
@@ -96,9 +96,9 @@ func (c *Compiler) makeStructTypeFields(typ *types.Struct) llvm.Value {
9696
runtimeStructField := c.getLLVMRuntimeType("structField")
9797
structGlobalType := llvm.ArrayType(runtimeStructField, typ.NumFields())
9898
structGlobal := llvm.AddGlobal(c.mod, structGlobalType, "reflect/types.structFields")
99-
structGlobalValue := c.getZeroValue(structGlobalType)
99+
structGlobalValue := llvm.ConstNull(structGlobalType)
100100
for i := 0; i < typ.NumFields(); i++ {
101-
fieldGlobalValue := c.getZeroValue(runtimeStructField)
101+
fieldGlobalValue := llvm.ConstNull(runtimeStructField)
102102
fieldGlobalValue = llvm.ConstInsertValue(fieldGlobalValue, c.getTypeCode(typ.Field(i).Type()), []uint32{0})
103103
fieldName := c.makeGlobalArray([]byte(typ.Field(i).Name()), "reflect/types.structFieldName", c.ctx.Int8Type())
104104
fieldName.SetLinkage(llvm.PrivateLinkage)
@@ -380,7 +380,7 @@ func (c *Compiler) parseTypeAssert(frame *Frame, expr *ssa.TypeAssert) llvm.Valu
380380
// Continue after the if statement.
381381
c.builder.SetInsertPointAtEnd(nextBlock)
382382
phi := c.builder.CreatePHI(assertedType, "typeassert.value")
383-
phi.AddIncoming([]llvm.Value{c.getZeroValue(assertedType), valueOk}, []llvm.BasicBlock{prevBlock, okBlock})
383+
phi.AddIncoming([]llvm.Value{llvm.ConstNull(assertedType), valueOk}, []llvm.BasicBlock{prevBlock, okBlock})
384384

385385
if expr.CommaOk {
386386
tuple := c.ctx.ConstStruct([]llvm.Value{llvm.Undef(assertedType), llvm.Undef(c.ctx.Int1Type())}, false) // create empty tuple

compiler/optimizer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ func (c *Compiler) OptimizeAllocs() {
289289
sizeInWords := (size + uint64(alignment) - 1) / uint64(alignment)
290290
allocaType := llvm.ArrayType(c.ctx.IntType(alignment*8), int(sizeInWords))
291291
alloca := c.builder.CreateAlloca(allocaType, "stackalloc.alloca")
292-
zero := c.getZeroValue(alloca.Type().ElementType())
292+
zero := llvm.ConstNull(alloca.Type().ElementType())
293293
c.builder.CreateStore(zero, alloca)
294294
stackalloc := c.builder.CreateBitCast(alloca, bitcast.Type(), "stackalloc")
295295
bitcast.ReplaceAllUsesWith(stackalloc)

compiler/symbol.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func (c *Compiler) getGlobal(g *ssa.Global) llvm.Value {
6161
llvmType := c.getLLVMType(g.Type().(*types.Pointer).Elem())
6262
llvmGlobal = llvm.AddGlobal(c.mod, llvmType, info.linkName)
6363
if !info.extern {
64-
llvmGlobal.SetInitializer(c.getZeroValue(llvmType))
64+
llvmGlobal.SetInitializer(llvm.ConstNull(llvmType))
6565
llvmGlobal.SetLinkage(llvm.InternalLinkage)
6666
}
6767
}

compiler/wordpack.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (c *Compiler) emitPointerUnpack(ptr llvm.Value, valueTypes []llvm.Type) []l
101101
for i, valueType := range valueTypes {
102102
if c.targetData.TypeAllocSize(valueType) == 0 {
103103
// This value has length zero, so there's nothing to load.
104-
values[i] = c.getZeroValue(valueType)
104+
values[i] = llvm.ConstNull(valueType)
105105
continue
106106
}
107107
indices := []llvm.Value{

interp/frame.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
8686
case !inst.IsAAllocaInst().IsNil():
8787
allocType := inst.Type().ElementType()
8888
alloca := llvm.AddGlobal(fr.Mod, allocType, fr.pkgName+"$alloca")
89-
alloca.SetInitializer(getZeroValue(allocType))
89+
alloca.SetInitializer(llvm.ConstNull(allocType))
9090
alloca.SetLinkage(llvm.InternalLinkage)
9191
fr.locals[inst] = &LocalValue{
9292
Underlying: alloca,
@@ -253,7 +253,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
253253
allocType = llvm.ArrayType(allocType, elementCount)
254254
}
255255
alloc := llvm.AddGlobal(fr.Mod, allocType, fr.pkgName+"$alloc")
256-
alloc.SetInitializer(getZeroValue(allocType))
256+
alloc.SetInitializer(llvm.ConstNull(allocType))
257257
alloc.SetLinkage(llvm.InternalLinkage)
258258
result := &LocalValue{
259259
Underlying: alloc,
@@ -312,7 +312,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
312312
stringType := fr.Mod.GetTypeByName("runtime._string")
313313
retPtr := llvm.ConstGEP(global, getLLVMIndices(fr.Mod.Context().Int32Type(), []uint32{0, 0}))
314314
retLen := llvm.ConstInt(stringType.StructElementTypes()[1], uint64(len(result)), false)
315-
ret := getZeroValue(stringType)
315+
ret := llvm.ConstNull(stringType)
316316
ret = llvm.ConstInsertValue(ret, retPtr, []uint32{0})
317317
ret = llvm.ConstInsertValue(ret, retLen, []uint32{1})
318318
fr.locals[inst] = &LocalValue{fr.Eval, ret}
@@ -335,7 +335,7 @@ func (fr *frame) evalBasicBlock(bb, incoming llvm.BasicBlock, indent string) (re
335335
sliceType := inst.Type()
336336
retPtr := llvm.ConstGEP(global, getLLVMIndices(fr.Mod.Context().Int32Type(), []uint32{0, 0}))
337337
retLen := llvm.ConstInt(sliceType.StructElementTypes()[1], uint64(len(result)), false)
338-
ret := getZeroValue(sliceType)
338+
ret := llvm.ConstNull(sliceType)
339339
ret = llvm.ConstInsertValue(ret, retPtr, []uint32{0}) // ptr
340340
ret = llvm.ConstInsertValue(ret, retLen, []uint32{1}) // len
341341
ret = llvm.ConstInsertValue(ret, retLen, []uint32{2}) // cap

0 commit comments

Comments
 (0)