From 7b6a9fab4206bde1a11c3a8d79631a0e8ac71a82 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 21 Sep 2022 13:55:32 +0200 Subject: [PATCH] all: add type parameter to CreateLoad This is needed for LLVM 15. --- compiler/atomic.go | 2 +- compiler/channel.go | 8 ++++---- compiler/compiler.go | 13 +++++++------ compiler/defer.go | 19 +++++++++++-------- compiler/llvmutil/wordpack.go | 4 ++-- compiler/map.go | 6 +++--- compiler/volatile.go | 5 ++++- go.mod | 2 +- go.sum | 4 ++-- interp/interpreter.go | 2 +- transform/gc.go | 2 +- transform/stacksize.go | 13 +++++++++---- transform/wasm-abi.go | 4 ++-- 13 files changed, 48 insertions(+), 36 deletions(-) diff --git a/compiler/atomic.go b/compiler/atomic.go index 6ba3849c..73761be4 100644 --- a/compiler/atomic.go +++ b/compiler/atomic.go @@ -56,7 +56,7 @@ func (b *builder) createAtomicOp(name string) llvm.Value { return swapped case "LoadInt32", "LoadInt64", "LoadUint32", "LoadUint64", "LoadUintptr", "LoadPointer": ptr := b.getValue(b.fn.Params[0]) - val := b.CreateLoad(ptr, "") + val := b.CreateLoad(b.getLLVMType(b.fn.Signature.Results().At(0).Type()), ptr, "") val.SetOrdering(llvm.AtomicOrderingSequentiallyConsistent) val.SetAlignment(b.targetData.PrefTypeAlignment(val.Type())) // required return val diff --git a/compiler/channel.go b/compiler/channel.go index a9886e10..5c3b6c59 100644 --- a/compiler/channel.go +++ b/compiler/channel.go @@ -84,7 +84,7 @@ func (b *builder) createChanRecv(unop *ssa.UnOp) llvm.Value { if isZeroSize { received = llvm.ConstNull(valueType) } else { - received = b.CreateLoad(valueAlloca, "chan.received") + received = b.CreateLoad(valueType, valueAlloca, "chan.received") b.emitLifetimeEnd(valueAllocaCast, valueAllocaSize) } b.emitLifetimeEnd(channelBlockedListAllocaCast, channelBlockedListAllocaSize) @@ -264,8 +264,8 @@ func (b *builder) getChanSelectResult(expr *ssa.Extract) llvm.Value { // receive can proceed at a time) so we'll get that alloca, bitcast // it to the correct type, and dereference it. recvbuf := b.selectRecvBuf[expr.Tuple.(*ssa.Select)] - typ := llvm.PointerType(b.getLLVMType(expr.Type()), 0) - ptr := b.CreateBitCast(recvbuf, typ, "") - return b.CreateLoad(ptr, "") + typ := b.getLLVMType(expr.Type()) + ptr := b.CreateBitCast(recvbuf, llvm.PointerType(typ, 0), "") + return b.CreateLoad(typ, ptr, "") } } diff --git a/compiler/compiler.go b/compiler/compiler.go index b64fddcc..7ab2fe4e 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1931,11 +1931,12 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { // Can't load directly from array (as index is non-constant), so have to // do it using an alloca+gep+load. - alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(array.Type(), "index.alloca") + arrayType := array.Type() + alloca, allocaPtr, allocaSize := b.createTemporaryAlloca(arrayType, "index.alloca") b.CreateStore(array, alloca) zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) ptr := b.CreateInBoundsGEP(alloca, []llvm.Value{zero, index}, "index.gep") - result := b.CreateLoad(ptr, "index.load") + result := b.CreateLoad(arrayType.ElementType(), ptr, "index.load") b.emitLifetimeEnd(allocaPtr, allocaSize) return result, nil case *ssa.IndexAddr: @@ -2012,7 +2013,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { // Lookup byte buf := b.CreateExtractValue(value, 0, "") bufPtr := b.CreateInBoundsGEP(buf, []llvm.Value{index}, "") - return b.CreateLoad(bufPtr, ""), nil + return b.CreateLoad(b.ctx.Int8Type(), bufPtr, ""), nil case *types.Map: valueType := expr.Type() if expr.CommaOk { @@ -3076,10 +3077,10 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) { return llvm.Value{}, b.makeError(unop.Pos(), "todo: unknown type for negate: "+unop.X.Type().Underlying().String()) } case token.MUL: // *x, dereference pointer - unop.X.Type().Underlying().(*types.Pointer).Elem() + valueType := b.getLLVMType(unop.X.Type().Underlying().(*types.Pointer).Elem()) if b.targetData.TypeAllocSize(x.Type().ElementType()) == 0 { // zero-length data - return llvm.ConstNull(x.Type().ElementType()), nil + return llvm.ConstNull(valueType), 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: @@ -3094,7 +3095,7 @@ func (b *builder) createUnOp(unop *ssa.UnOp) (llvm.Value, error) { return b.CreateBitCast(fn, b.i8ptrType, ""), nil } else { b.createNilCheck(unop.X, x, "deref") - load := b.CreateLoad(x, "") + load := b.CreateLoad(valueType, x, "") return load, nil } case token.XOR: // ^x, toggle all bits in integer diff --git a/compiler/defer.go b/compiler/defer.go index e82370fa..1f892e5b 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -249,7 +249,8 @@ func isInLoop(start *ssa.BasicBlock) bool { func (b *builder) createDefer(instr *ssa.Defer) { // The pointer to the previous defer struct, which we will replace to // make a linked list. - next := b.CreateLoad(b.deferPtr, "defer.next") + deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0) + next := b.CreateLoad(deferType, b.deferPtr, "defer.next") var values []llvm.Value valueTypes := []llvm.Type{b.uintptrType, next.Type()} @@ -406,6 +407,8 @@ func (b *builder) createDefer(instr *ssa.Defer) { // createRunDefers emits code to run all deferred functions. func (b *builder) createRunDefers() { + deferType := llvm.PointerType(b.getLLVMRuntimeType("_defer"), 0) + // Add a loop like the following: // for stack != nil { // _stack := stack @@ -431,7 +434,7 @@ func (b *builder) createRunDefers() { // Create loop head: // for stack != nil { b.SetInsertPointAtEnd(loophead) - deferData := b.CreateLoad(b.deferPtr, "") + deferData := b.CreateLoad(deferType, b.deferPtr, "") stackIsNil := b.CreateICmp(llvm.IntEQ, deferData, llvm.ConstPointerNull(deferData.Type()), "stackIsNil") b.CreateCondBr(stackIsNil, end, loop) @@ -444,13 +447,13 @@ func (b *builder) createRunDefers() { llvm.ConstInt(b.ctx.Int32Type(), 0, false), llvm.ConstInt(b.ctx.Int32Type(), 1, false), // .next field }, "stack.next.gep") - nextStack := b.CreateLoad(nextStackGEP, "stack.next") + nextStack := b.CreateLoad(deferType, nextStackGEP, "stack.next") b.CreateStore(nextStack, b.deferPtr) gep := b.CreateInBoundsGEP(deferData, []llvm.Value{ llvm.ConstInt(b.ctx.Int32Type(), 0, false), llvm.ConstInt(b.ctx.Int32Type(), 0, false), // .callback field }, "callback.gep") - callback := b.CreateLoad(gep, "callback") + callback := b.CreateLoad(b.uintptrType, gep, "callback") sw := b.CreateSwitch(callback, unreachable, len(b.allDeferFuncs)) for i, callback := range b.allDeferFuncs { @@ -487,7 +490,7 @@ func (b *builder) createRunDefers() { zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) for i := 2; i < len(valueTypes); i++ { gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "gep") - forwardParam := b.CreateLoad(gep, "param") + forwardParam := b.CreateLoad(valueTypes[i], gep, "param") forwardParams = append(forwardParams, forwardParam) } @@ -536,7 +539,7 @@ func (b *builder) createRunDefers() { zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) for i := range getParams(callback.Signature) { gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") - forwardParam := b.CreateLoad(gep, "param") + forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param") forwardParams = append(forwardParams, forwardParam) } @@ -569,7 +572,7 @@ func (b *builder) createRunDefers() { zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) for i := 2; i < len(valueTypes); i++ { gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i), false)}, "") - forwardParam := b.CreateLoad(gep, "param") + forwardParam := b.CreateLoad(valueTypes[i], gep, "param") forwardParams = append(forwardParams, forwardParam) } @@ -596,7 +599,7 @@ func (b *builder) createRunDefers() { zero := llvm.ConstInt(b.ctx.Int32Type(), 0, false) for i := 0; i < params.Len(); i++ { gep := b.CreateInBoundsGEP(deferredCallPtr, []llvm.Value{zero, llvm.ConstInt(b.ctx.Int32Type(), uint64(i+2), false)}, "gep") - forwardParam := b.CreateLoad(gep, "param") + forwardParam := b.CreateLoad(valueTypes[i+2], gep, "param") argValues = append(argValues, forwardParam) } diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go index 73b1e27e..97b86045 100644 --- a/compiler/llvmutil/wordpack.go +++ b/compiler/llvmutil/wordpack.go @@ -63,7 +63,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, prefix string, needs } // Load value (the *i8) from the alloca. - result := builder.CreateLoad(packedAlloc, "") + result := builder.CreateLoad(i8ptrType, packedAlloc, "") // End the lifetime of the alloca, to help the optimizer. packedPtr := builder.CreateBitCast(packedAlloc, i8ptrType, "") @@ -171,7 +171,7 @@ func EmitPointerUnpack(builder llvm.Builder, mod llvm.Module, ptr llvm.Value, va llvm.ConstInt(ctx.Int32Type(), uint64(i), false), } gep := builder.CreateInBoundsGEP(packedAlloc, indices, "") - values[i] = builder.CreateLoad(gep, "") + values[i] = builder.CreateLoad(valueType, gep, "") } if !packedRawAlloc.IsNil() { allocPtr := builder.CreateBitCast(packedRawAlloc, i8ptrType, "") diff --git a/compiler/map.go b/compiler/map.go index 57a7033a..7655ec70 100644 --- a/compiler/map.go +++ b/compiler/map.go @@ -106,7 +106,7 @@ func (b *builder) createMapLookup(keyType, valueType types.Type, m, key llvm.Val // Load the resulting value from the hashmap. The value is set to the zero // value if the key doesn't exist in the hashmap. - mapValue := b.CreateLoad(mapValueAlloca, "") + mapValue := b.CreateLoad(llvmValueType, mapValueAlloca, "") b.emitLifetimeEnd(mapValuePtr, mapValueAllocaSize) if commaOk { @@ -217,8 +217,8 @@ func (b *builder) createMapIteratorNext(rangeVal ssa.Value, llvmRangeVal, it llv mapKeyAlloca, mapKeyPtr, mapKeySize := b.createTemporaryAlloca(llvmStoredKeyType, "range.key") mapValueAlloca, mapValuePtr, mapValueSize := b.createTemporaryAlloca(llvmValueType, "range.value") ok := b.createRuntimeCall("hashmapNext", []llvm.Value{llvmRangeVal, it, mapKeyPtr, mapValuePtr}, "range.next") - mapKey := b.CreateLoad(mapKeyAlloca, "") - mapValue := b.CreateLoad(mapValueAlloca, "") + mapKey := b.CreateLoad(llvmStoredKeyType, mapKeyAlloca, "") + mapValue := b.CreateLoad(llvmValueType, mapValueAlloca, "") if isKeyStoredAsInterface { // The key is stored as an interface but it isn't of interface type. diff --git a/compiler/volatile.go b/compiler/volatile.go index 143eff28..3d3a67fa 100644 --- a/compiler/volatile.go +++ b/compiler/volatile.go @@ -1,5 +1,7 @@ package compiler +import "go/types" + // This file implements volatile loads/stores in runtime/volatile.LoadT and // runtime/volatile.StoreT as compiler builtins. @@ -9,7 +11,8 @@ func (b *builder) createVolatileLoad() { b.createFunctionStart(true) addr := b.getValue(b.fn.Params[0]) b.createNilCheck(b.fn.Params[0], addr, "deref") - val := b.CreateLoad(addr, "") + valType := b.getLLVMType(b.fn.Params[0].Type().(*types.Pointer).Elem()) + val := b.CreateLoad(valType, addr, "") val.SetVolatile(true) b.CreateRet(val) } diff --git a/go.mod b/go.mod index 4af10427..26707a96 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 golang.org/x/tools v0.1.11 gopkg.in/yaml.v2 v2.4.0 - tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 + tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 ) require ( diff --git a/go.sum b/go.sum index 401de3be..e5c734cd 100644 --- a/go.sum +++ b/go.sum @@ -64,5 +64,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636 h1:JxtI6P/lyWHAcs/4QJWeWIbh4HntxPFONMVWvx7wf8Y= -tinygo.org/x/go-llvm v0.0.0-20220921144613-dcf4836fe636/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= +tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6 h1:bJYUpmJrVm7Uluxh80qSivfeU3d9D4JNg5oJ+h9U+xc= +tinygo.org/x/go-llvm v0.0.0-20220921144624-6c125b0aeda6/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= diff --git a/interp/interpreter.go b/interp/interpreter.go index 4a4553f8..2c7fd8c3 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -983,7 +983,7 @@ func (r *runner) runAtRuntime(fn *function, inst instruction, locals []value, me if err != nil { return r.errorAt(inst, err) } - result = r.builder.CreateLoad(operands[0], inst.name) + result = r.builder.CreateLoad(inst.llvmInst.Type(), operands[0], inst.name) if inst.llvmInst.IsVolatile() { result.SetVolatile(true) } diff --git a/transform/gc.go b/transform/gc.go index 87dc6e88..7a4e99ac 100644 --- a/transform/gc.go +++ b/transform/gc.go @@ -222,7 +222,7 @@ func MakeGCStackSlots(mod llvm.Module) bool { builder.CreateStore(initialStackObject, stackObject) // Update stack start. - parent := builder.CreateLoad(stackChainStart, "") + parent := builder.CreateLoad(stackChainStartType, stackChainStart, "") gep := builder.CreateGEP(stackObject, []llvm.Value{ llvm.ConstInt(ctx.Int32Type(), 0, false), llvm.ConstInt(ctx.Int32Type(), 0, false), diff --git a/transform/stacksize.go b/transform/stacksize.go index 7be49238..f1a3c93d 100644 --- a/transform/stacksize.go +++ b/transform/stacksize.go @@ -34,6 +34,11 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string return nil } + ctx := mod.Context() + targetData := llvm.NewTargetData(mod.DataLayout()) + defer targetData.Dispose() + uintptrType := ctx.IntType(targetData.PointerSize() * 8) + // Create the new global with stack sizes, that will be put in a new section // just for itself. stackSizesGlobalType := llvm.ArrayType(functions[0].Type(), len(functions)) @@ -50,16 +55,16 @@ func CreateStackSizeLoads(mod llvm.Module, config *compileopts.Config) []string appendToUsedGlobals(mod, append([]llvm.Value{stackSizesGlobal}, functionValues...)...) // Replace the calls with loads from the new global with stack sizes. - irbuilder := mod.Context().NewBuilder() + irbuilder := ctx.NewBuilder() defer irbuilder.Dispose() for i, function := range functions { for _, use := range functionMap[function] { ptr := llvm.ConstGEP(stackSizesGlobal, []llvm.Value{ - llvm.ConstInt(mod.Context().Int32Type(), 0, false), - llvm.ConstInt(mod.Context().Int32Type(), uint64(i), false), + llvm.ConstInt(ctx.Int32Type(), 0, false), + llvm.ConstInt(ctx.Int32Type(), uint64(i), false), }) irbuilder.SetInsertPointBefore(use) - stacksize := irbuilder.CreateLoad(ptr, "stacksize") + stacksize := irbuilder.CreateLoad(uintptrType, ptr, "stacksize") use.ReplaceAllUsesWith(stacksize) use.EraseFromParentAsInstruction() } diff --git a/transform/wasm-abi.go b/transform/wasm-abi.go index aedad71d..064e38f4 100644 --- a/transform/wasm-abi.go +++ b/transform/wasm-abi.go @@ -125,7 +125,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { // where the return value should be stored, instead of using // the regular return value. builder.CreateCall(externalFnType, externalFn, callParams, callName) - returnValue := builder.CreateLoad(retvalAlloca, "retval") + returnValue := builder.CreateLoad(int64Type, retvalAlloca, "retval") call.ReplaceAllUsesWith(returnValue) call.EraseFromParentAsInstruction() } else { @@ -152,7 +152,7 @@ func ExternalInt64AsPtr(mod llvm.Module, config *compileopts.Config) error { for i, origParam := range fn.Params() { paramValue := externalFn.Param(i) if origParam.Type() == int64Type { - paramValue = builder.CreateLoad(paramValue, "i64") + paramValue = builder.CreateLoad(int64Type, paramValue, "i64") } callParams = append(callParams, paramValue) }