diff options
author | Ayke van Laethem <[email protected]> | 2021-07-09 14:01:37 +0200 |
---|---|---|
committer | Ron Evans <[email protected]> | 2021-11-02 22:16:15 +0100 |
commit | f24a93c51d8b565aedfa6edebd3c638c9125f468 (patch) | |
tree | e465b75aaf7877e84f635959f5f43bfc406ea237 | |
parent | c454568688b1d31c36b8805da47e5ae8d4617707 (diff) | |
download | tinygo-f24a93c51d8b565aedfa6edebd3c638c9125f468.tar.gz tinygo-f24a93c51d8b565aedfa6edebd3c638c9125f468.zip |
compiler, runtime: add layout parameter to runtime.alloc
This layout parameter is currently always nil and ignored, but will
eventually contain a pointer to a memory layout.
This commit also adds module verification to the transform tests, as I
found out that it didn't (and therefore didn't initially catch all
bugs).
38 files changed, 99 insertions, 89 deletions
diff --git a/compiler/compiler.go b/compiler/compiler.go index afc8eb9d1..c42e40c42 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1524,7 +1524,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { return llvm.Value{}, b.makeError(expr.Pos(), fmt.Sprintf("value is too big (%v bytes)", size)) } sizeValue := llvm.ConstInt(b.uintptrType, size, false) - buf := b.createRuntimeCall("alloc", []llvm.Value{sizeValue}, expr.Comment) + nilPtr := llvm.ConstNull(b.i8ptrType) + buf := b.createRuntimeCall("alloc", []llvm.Value{sizeValue, nilPtr}, expr.Comment) buf = b.CreateBitCast(buf, llvm.PointerType(typ, 0), "") return buf, nil } else { @@ -1736,7 +1737,8 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) { return llvm.Value{}, err } sliceSize := b.CreateBinOp(llvm.Mul, elemSizeValue, sliceCapCast, "makeslice.cap") - slicePtr := b.createRuntimeCall("alloc", []llvm.Value{sliceSize}, "makeslice.buf") + nilPtr := llvm.ConstNull(b.i8ptrType) + slicePtr := b.createRuntimeCall("alloc", []llvm.Value{sliceSize, nilPtr}, "makeslice.buf") slicePtr = b.CreateBitCast(slicePtr, llvm.PointerType(llvmElemType, 0), "makeslice.array") // Extend or truncate if necessary. This is safe as we've already done diff --git a/compiler/defer.go b/compiler/defer.go index 0687f4d1a..6edcc1423 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -217,7 +217,8 @@ func (b *builder) createDefer(instr *ssa.Defer) { // This may be hit a variable number of times, so use a heap allocation. size := b.targetData.TypeAllocSize(deferFrameType) sizeValue := llvm.ConstInt(b.uintptrType, size, false) - allocCall := b.createRuntimeCall("alloc", []llvm.Value{sizeValue}, "defer.alloc.call") + nilPtr := llvm.ConstNull(b.i8ptrType) + allocCall := b.createRuntimeCall("alloc", []llvm.Value{sizeValue, nilPtr}, "defer.alloc.call") alloca = b.CreateBitCast(allocCall, llvm.PointerType(deferFrameType, 0), "defer.alloc") } if b.NeedsStackObjects { diff --git a/compiler/llvmutil/wordpack.go b/compiler/llvmutil/wordpack.go index 05fc4ee89..e2b6c7d9f 100644 --- a/compiler/llvmutil/wordpack.go +++ b/compiler/llvmutil/wordpack.go @@ -97,6 +97,7 @@ func EmitPointerPack(builder llvm.Builder, mod llvm.Module, needsStackObjects bo alloc := mod.NamedFunction("runtime.alloc") packedHeapAlloc := builder.CreateCall(alloc, []llvm.Value{ sizeValue, + llvm.ConstNull(i8ptrType), llvm.Undef(i8ptrType), // unused context parameter llvm.ConstPointerNull(i8ptrType), // coroutine handle }, "") diff --git a/compiler/testdata/basic.ll b/compiler/testdata/basic.ll index 2ac982c97..56baf3a77 100644 --- a/compiler/testdata/basic.ll +++ b/compiler/testdata/basic.ll @@ -6,7 +6,7 @@ target triple = "wasm32-unknown-wasi" %main.kv = type { float } %main.kv.0 = type { i8 } -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll index ffe6bf2d6..2d4f1475b 100644 --- a/compiler/testdata/channel.ll +++ b/compiler/testdata/channel.ll @@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi" %"internal/task.state" = type { i8* } %runtime.chanSelectState = type { %runtime.channel*, i8* } -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll index a83def94f..c69640584 100644 --- a/compiler/testdata/float.ll +++ b/compiler/testdata/float.ll @@ -3,7 +3,7 @@ source_filename = "float.go" target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-wasi" -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/func.ll b/compiler/testdata/func.ll index 86345b8dd..eeefa43cf 100644 --- a/compiler/testdata/func.ll +++ b/compiler/testdata/func.ll @@ -8,7 +8,7 @@ target triple = "wasm32-unknown-wasi" @"reflect/types.funcid:func:{basic:int}{}" = external constant i8 @"main.someFunc$withSignature" = linkonce_odr constant %runtime.funcValueWithSignature { i32 ptrtoint (void (i32, i8*, i8*)* @main.someFunc to i32), i8* @"reflect/types.funcid:func:{basic:int}{}" } -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/go1.17.ll b/compiler/testdata/go1.17.ll index ea758a9d8..3e1312365 100644 --- a/compiler/testdata/go1.17.ll +++ b/compiler/testdata/go1.17.ll @@ -3,7 +3,7 @@ source_filename = "go1.17.go" target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-wasi" -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { @@ -46,7 +46,7 @@ declare void @runtime.sliceToArrayPointerPanic(i8*, i8*) ; Function Attrs: nounwind define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %makeslice = call i8* @runtime.alloc(i32 24, i8* undef, i8* null) #0 + %makeslice = call i8* @runtime.alloc(i32 24, i8* null, i8* undef, i8* null) #0 br i1 false, label %slicetoarray.throw, label %slicetoarray.next slicetoarray.throw: ; preds = %entry diff --git a/compiler/testdata/goroutine-cortex-m-qemu.ll b/compiler/testdata/goroutine-cortex-m-qemu.ll index 064a5fd85..efc518615 100644 --- a/compiler/testdata/goroutine-cortex-m-qemu.ll +++ b/compiler/testdata/goroutine-cortex-m-qemu.ll @@ -11,7 +11,7 @@ target triple = "armv7m-unknown-unknown-eabi" @"main.startInterfaceMethod$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { @@ -66,10 +66,10 @@ entry: ; Function Attrs: nounwind define hidden void @main.closureFunctionGoroutine(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %n = call i8* @runtime.alloc(i32 4, i8* undef, i8* null) #0 + %n = call i8* @runtime.alloc(i32 4, i8* null, i8* undef, i8* null) #0 %0 = bitcast i8* %n to i32* store i32 3, i32* %0, align 4 - %1 = call i8* @runtime.alloc(i32 8, i8* undef, i8* null) #0 + %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 %2 = bitcast i8* %1 to i32* store i32 5, i32* %2, align 4 %3 = getelementptr inbounds i8, i8* %1, i32 4 @@ -107,7 +107,7 @@ declare void @runtime.printint32(i32, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.funcGoroutine(i8* %fn.context, void ()* %fn.funcptr, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %0 = call i8* @runtime.alloc(i32 12, i8* undef, i8* null) #0 + %0 = call i8* @runtime.alloc(i32 12, i8* null, i8* undef, i8* null) #0 %1 = bitcast i8* %0 to i32* store i32 5, i32* %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 @@ -163,7 +163,7 @@ declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i ; Function Attrs: nounwind define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %0 = call i8* @runtime.alloc(i32 16, i8* undef, i8* null) #0 + %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef, i8* null) #0 %1 = bitcast i8* %0 to i8** store i8* %itf.value, i8** %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 diff --git a/compiler/testdata/goroutine-wasm.ll b/compiler/testdata/goroutine-wasm.ll index ab628148c..4a346c11b 100644 --- a/compiler/testdata/goroutine-wasm.ll +++ b/compiler/testdata/goroutine-wasm.ll @@ -16,7 +16,7 @@ target triple = "wasm32-unknown-wasi" @"main.closureFunctionGoroutine$1$withSignature" = linkonce_odr constant %runtime.funcValueWithSignature { i32 ptrtoint (void (i32, i8*, i8*)* @"main.closureFunctionGoroutine$1" to i32), i8* @"reflect/types.funcid:func:{basic:int}{}" } @"main.startInterfaceMethod$string" = internal unnamed_addr constant [4 x i8] c"test", align 1 -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { @@ -51,10 +51,10 @@ entry: ; Function Attrs: nounwind define hidden void @main.closureFunctionGoroutine(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %n = call i8* @runtime.alloc(i32 4, i8* undef, i8* null) #0 + %n = call i8* @runtime.alloc(i32 4, i8* null, i8* undef, i8* null) #0 %0 = bitcast i8* %n to i32* store i32 3, i32* %0, align 4 - %1 = call i8* @runtime.alloc(i32 8, i8* undef, i8* null) #0 + %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 %2 = bitcast i8* %1 to i32* store i32 5, i32* %2, align 4 %3 = getelementptr inbounds i8, i8* %1, i32 4 @@ -80,7 +80,7 @@ declare void @runtime.printint32(i32, i8*, i8*) define hidden void @main.funcGoroutine(i8* %fn.context, i32 %fn.funcptr, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call i32 @runtime.getFuncPtr(i8* %fn.context, i32 %fn.funcptr, i8* nonnull @"reflect/types.funcid:func:{basic:int}{}", i8* undef, i8* null) #0 - %1 = call i8* @runtime.alloc(i32 8, i8* undef, i8* null) #0 + %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 %2 = bitcast i8* %1 to i32* store i32 5, i32* %2, align 4 %3 = getelementptr inbounds i8, i8* %1, i32 4 @@ -119,7 +119,7 @@ declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i ; Function Attrs: nounwind define hidden void @main.startInterfaceMethod(i32 %itf.typecode, i8* %itf.value, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %0 = call i8* @runtime.alloc(i32 16, i8* undef, i8* null) #0 + %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef, i8* null) #0 %1 = bitcast i8* %0 to i8** store i8* %itf.value, i8** %1, align 4 %2 = getelementptr inbounds i8, i8* %0, i32 4 diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll index 21d00fdb8..f5afb0f38 100644 --- a/compiler/testdata/interface.ll +++ b/compiler/testdata/interface.ll @@ -22,7 +22,7 @@ target triple = "wasm32-unknown-wasi" @"reflect/types.interface:interface{String() string}$interface" = linkonce_odr constant [1 x i8*] [i8* @"reflect/methods.String() string"] @"reflect/types.typeid:basic:int" = external constant i8 -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/intrinsics-cortex-m-qemu.ll b/compiler/testdata/intrinsics-cortex-m-qemu.ll index f5f00e9e8..bf767bf9e 100644 --- a/compiler/testdata/intrinsics-cortex-m-qemu.ll +++ b/compiler/testdata/intrinsics-cortex-m-qemu.ll @@ -3,7 +3,7 @@ source_filename = "intrinsics.go" target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" target triple = "armv7m-unknown-unknown-eabi" -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/intrinsics-wasm.ll b/compiler/testdata/intrinsics-wasm.ll index 96e1bcb85..bebadb08a 100644 --- a/compiler/testdata/intrinsics-wasm.ll +++ b/compiler/testdata/intrinsics-wasm.ll @@ -3,7 +3,7 @@ source_filename = "intrinsics.go" target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-wasi" -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll index 20dfadf3d..4072816bb 100644 --- a/compiler/testdata/pointer.ll +++ b/compiler/testdata/pointer.ll @@ -3,7 +3,7 @@ source_filename = "pointer.go" target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-wasi" -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index 4d51748e7..31fe6236b 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -10,7 +10,7 @@ target triple = "wasm32-unknown-wasi" @undefinedGlobalNotInSection = external global i32, align 4 @main.multipleGlobalPragmas = hidden global i32 0, section ".global_section", align 1024 -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll index 234aea33b..da257c4ca 100644 --- a/compiler/testdata/slice.ll +++ b/compiler/testdata/slice.ll @@ -3,7 +3,7 @@ source_filename = "slice.go" target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" target triple = "wasm32-unknown-wasi" -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { @@ -44,7 +44,7 @@ declare void @runtime.lookupPanic(i8*, i8*) ; Function Attrs: nounwind define hidden { i32*, i32, i32 } @main.sliceAppendValues(i32* %ints.data, i32 %ints.len, i32 %ints.cap, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %varargs = call i8* @runtime.alloc(i32 12, i8* undef, i8* null) #0 + %varargs = call i8* @runtime.alloc(i32 12, i8* null, i8* undef, i8* null) #0 %0 = bitcast i8* %varargs to i32* store i32 1, i32* %0, align 4 %1 = getelementptr inbounds i8, i8* %varargs, i32 4 @@ -105,7 +105,7 @@ slice.throw: ; preds = %entry unreachable slice.next: ; preds = %entry - %makeslice.buf = call i8* @runtime.alloc(i32 %len, i8* undef, i8* null) #0 + %makeslice.buf = call i8* @runtime.alloc(i32 %len, i8* null, i8* undef, i8* null) #0 %0 = insertvalue { i8*, i32, i32 } undef, i8* %makeslice.buf, 0 %1 = insertvalue { i8*, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { i8*, i32, i32 } %1, i32 %len, 2 @@ -126,7 +126,7 @@ slice.throw: ; preds = %entry slice.next: ; preds = %entry %makeslice.cap = shl i32 %len, 1 - %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* undef, i8* null) #0 + %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* null, i8* undef, i8* null) #0 %makeslice.array = bitcast i8* %makeslice.buf to i16* %0 = insertvalue { i16*, i32, i32 } undef, i16* %makeslice.array, 0 %1 = insertvalue { i16*, i32, i32 } %0, i32 %len, 1 @@ -146,7 +146,7 @@ slice.throw: ; preds = %entry slice.next: ; preds = %entry %makeslice.cap = mul i32 %len, 3 - %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* undef, i8* null) #0 + %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* null, i8* undef, i8* null) #0 %makeslice.array = bitcast i8* %makeslice.buf to [3 x i8]* %0 = insertvalue { [3 x i8]*, i32, i32 } undef, [3 x i8]* %makeslice.array, 0 %1 = insertvalue { [3 x i8]*, i32, i32 } %0, i32 %len, 1 @@ -166,7 +166,7 @@ slice.throw: ; preds = %entry slice.next: ; preds = %entry %makeslice.cap = shl i32 %len, 2 - %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* undef, i8* null) #0 + %makeslice.buf = call i8* @runtime.alloc(i32 %makeslice.cap, i8* null, i8* undef, i8* null) #0 %makeslice.array = bitcast i8* %makeslice.buf to i32* %0 = insertvalue { i32*, i32, i32 } undef, i32* %makeslice.array, 0 %1 = insertvalue { i32*, i32, i32 } %0, i32 %len, 1 diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll index a4a819ca8..cdc8619ad 100644 --- a/compiler/testdata/string.ll +++ b/compiler/testdata/string.ll @@ -7,7 +7,7 @@ target triple = "wasm32-unknown-wasi" @"main.someString$string" = internal unnamed_addr constant [3 x i8] c"foo", align 1 -declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) +declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { diff --git a/interp/testdata/slice-copy.ll b/interp/testdata/slice-copy.ll index ae5cda6c4..52cbb372e 100644 --- a/interp/testdata/slice-copy.ll +++ b/interp/testdata/slice-copy.ll @@ -10,7 +10,7 @@ target triple = "x86_64--linux" declare i64 @runtime.sliceCopy(i8* %dst, i8* %src, i64 %dstLen, i64 %srcLen, i64 %elemSize) unnamed_addr -declare i8* @runtime.alloc(i64) unnamed_addr +declare i8* @runtime.alloc(i64, i8*) unnamed_addr declare void @runtime.printuint8(i8) @@ -52,7 +52,7 @@ entry: ; uint8SliceDst = make([]uint8, len(uint8SliceSrc)) %uint8SliceSrc = load { i8*, i64, i64 }, { i8*, i64, i64 }* @main.uint8SliceSrc %uint8SliceSrc.len = extractvalue { i8*, i64, i64 } %uint8SliceSrc, 1 - %uint8SliceDst.buf = call i8* @runtime.alloc(i64 %uint8SliceSrc.len) + %uint8SliceDst.buf = call i8* @runtime.alloc(i64 %uint8SliceSrc.len, i8* null) %0 = insertvalue { i8*, i64, i64 } undef, i8* %uint8SliceDst.buf, 0 %1 = insertvalue { i8*, i64, i64 } %0, i64 %uint8SliceSrc.len, 1 %2 = insertvalue { i8*, i64, i64 } %1, i64 %uint8SliceSrc.len, 2 @@ -68,7 +68,7 @@ entry: %int16SliceSrc = load { i16*, i64, i64 }, { i16*, i64, i64 }* @main.int16SliceSrc %int16SliceSrc.len = extractvalue { i16*, i64, i64 } %int16SliceSrc, 1 %int16SliceSrc.len.bytes = mul i64 %int16SliceSrc.len, 2 - %int16SliceDst.buf.raw = call i8* @runtime.alloc(i64 %int16SliceSrc.len.bytes) + %int16SliceDst.buf.raw = call i8* @runtime.alloc(i64 %int16SliceSrc.len.bytes, i8* null) %int16SliceDst.buf = bitcast i8* %int16SliceDst.buf.raw to i16* %3 = insertvalue { i16*, i64, i64 } undef, i16* %int16SliceDst.buf, 0 %4 = insertvalue { i16*, i64, i64 } %3, i64 %int16SliceSrc.len, 1 diff --git a/src/reflect/value.go b/src/reflect/value.go index 88f8137af..f5f0132db 100644 --- a/src/reflect/value.go +++ b/src/reflect/value.go @@ -729,7 +729,7 @@ func Zero(typ Type) Value { func New(typ Type) Value { return Value{ typecode: PtrTo(typ).(rawType), - value: alloc(typ.Size()), + value: alloc(typ.Size(), nil), flags: valueFlagExported, } } @@ -778,7 +778,7 @@ func (e *ValueError) Error() string { func memcpy(dst, src unsafe.Pointer, size uintptr) //go:linkname alloc runtime.alloc -func alloc(size uintptr) unsafe.Pointer +func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer //go:linkname sliceAppend runtime.sliceAppend func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen uintptr, elemSize uintptr) (unsafe.Pointer, uintptr, uintptr) diff --git a/src/runtime/arch_tinygowasm.go b/src/runtime/arch_tinygowasm.go index a19a14487..7dc04f07b 100644 --- a/src/runtime/arch_tinygowasm.go +++ b/src/runtime/arch_tinygowasm.go @@ -66,7 +66,7 @@ func growHeap() bool { //export malloc func libc_malloc(size uintptr) unsafe.Pointer { - return alloc(size) + return alloc(size, nil) } //export free @@ -79,7 +79,7 @@ func libc_calloc(nmemb, size uintptr) unsafe.Pointer { // Note: we could be even more correct here and check that nmemb * size // doesn't overflow. However the current implementation should normally work // fine. - return alloc(nmemb * size) + return alloc(nmemb*size, nil) } //export realloc diff --git a/src/runtime/baremetal.go b/src/runtime/baremetal.go index 6b9fbcc3c..e17edcbfa 100644 --- a/src/runtime/baremetal.go +++ b/src/runtime/baremetal.go @@ -38,7 +38,7 @@ func growHeap() bool { //export malloc func libc_malloc(size uintptr) unsafe.Pointer { - return alloc(size) + return alloc(size, nil) } //export free diff --git a/src/runtime/chan.go b/src/runtime/chan.go index c2da4f05c..a5229f0ea 100644 --- a/src/runtime/chan.go +++ b/src/runtime/chan.go @@ -133,7 +133,7 @@ func chanMake(elementSize uintptr, bufSize uintptr) *channel { return &channel{ elementSize: elementSize, bufSize: bufSize, - buf: alloc(elementSize * bufSize), + buf: alloc(elementSize*bufSize, nil), } } diff --git a/src/runtime/gc_conservative.go b/src/runtime/gc_conservative.go index 67fbfdb2c..ea142be93 100644 --- a/src/runtime/gc_conservative.go +++ b/src/runtime/gc_conservative.go @@ -263,7 +263,7 @@ func calculateHeapAddresses() { // alloc tries to find some free space on the heap, possibly doing a garbage // collection cycle if needed. If no space is free, it panics. //go:noinline -func alloc(size uintptr) unsafe.Pointer { +func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer { if size == 0 { return unsafe.Pointer(&zeroSizedAlloc) } diff --git a/src/runtime/gc_extalloc.go b/src/runtime/gc_extalloc.go index 7272d34ca..7fbeec110 100644 --- a/src/runtime/gc_extalloc.go +++ b/src/runtime/gc_extalloc.go @@ -527,7 +527,7 @@ var zeroSizedAlloc uint8 // alloc tries to find some free space on the heap, possibly doing a garbage // collection cycle if needed. If no space is free, it panics. //go:noinline -func alloc(size uintptr) unsafe.Pointer { +func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer { if size == 0 { return unsafe.Pointer(&zeroSizedAlloc) } diff --git a/src/runtime/gc_leaking.go b/src/runtime/gc_leaking.go index 60340c645..345539d68 100644 --- a/src/runtime/gc_leaking.go +++ b/src/runtime/gc_leaking.go @@ -13,7 +13,7 @@ import ( // Ever-incrementing pointer: no memory is freed. var heapptr = heapStart -func alloc(size uintptr) unsafe.Pointer { +func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer { // TODO: this can be optimized by not casting between pointers and ints so // much. And by using platform-native data types (e.g. *uint8 for 8-bit // systems). diff --git a/src/runtime/gc_none.go b/src/runtime/gc_none.go index 6528261b3..403675f82 100644 --- a/src/runtime/gc_none.go +++ b/src/runtime/gc_none.go @@ -10,7 +10,7 @@ import ( "unsafe" ) -func alloc(size uintptr) unsafe.Pointer +func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer func free(ptr unsafe.Pointer) { // Nothing to free when nothing gets allocated. diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index fdfbcfde3..17299c49b 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -69,7 +69,7 @@ func hashmapMake(keySize, valueSize uint8, sizeHint uintptr) *hashmap { bucketBits++ } bucketBufSize := unsafe.Sizeof(hashmapBucket{}) + uintptr(keySize)*8 + uintptr(valueSize)*8 - buckets := alloc(bucketBufSize * (1 << bucketBits)) + buckets := alloc(bucketBufSize*(1<<bucketBits), nil) return &hashmap{ buckets: buckets, keySize: keySize, @@ -157,7 +157,7 @@ func hashmapSet(m *hashmap, key unsafe.Pointer, value unsafe.Pointer, hash uint3 // value into the bucket, and returns a pointer to this bucket. func hashmapInsertIntoNewBucket(m *hashmap, key, value unsafe.Pointer, tophash uint8) *hashmapBucket { bucketBufSize := unsafe.Sizeof(hashmapBucket{}) + uintptr(m.keySize)*8 + uintptr(m.valueSize)*8 - bucketBuf := alloc(bucketBufSize) + bucketBuf := alloc(bucketBufSize, nil) // Insert into the first slot, which is empty as it has just been allocated. slotKeyOffset := unsafe.Sizeof(hashmapBucket{}) slotKey := unsafe.Pointer(uintptr(bucketBuf) + slotKeyOffset) diff --git a/src/runtime/slice.go b/src/runtime/slice.go index 923e30bdc..b58fab360 100644 --- a/src/runtime/slice.go +++ b/src/runtime/slice.go @@ -27,7 +27,7 @@ func sliceAppend(srcBuf, elemsBuf unsafe.Pointer, srcLen, srcCap, elemsLen uintp // programs). srcCap *= 2 } - buf := alloc(srcCap * elemSize) + buf := alloc(srcCap*elemSize, nil) // Copy the old slice to the new slice. if srcLen != 0 { diff --git a/src/runtime/string.go b/src/runtime/string.go index 74e16e028..72037d3d3 100644 --- a/src/runtime/string.go +++ b/src/runtime/string.go @@ -57,7 +57,7 @@ func stringConcat(x, y _string) _string { return x } else { length := x.length + y.length - buf := alloc(length) + buf := alloc(length, nil) memcpy(buf, unsafe.Pointer(x.ptr), x.length) memcpy(unsafe.Pointer(uintptr(buf)+x.length), unsafe.Pointer(y.ptr), y.length) return _string{ptr: (*byte)(buf), length: length} @@ -70,7 +70,7 @@ func stringFromBytes(x struct { len uintptr cap uintptr }) _string { - buf := alloc(x.len) + buf := alloc(x.len, nil) memcpy(buf, unsafe.Pointer(x.ptr), x.len) return _string{ptr: (*byte)(buf), length: x.len} } @@ -81,7 +81,7 @@ func stringToBytes(x _string) (slice struct { len uintptr cap uintptr }) { - buf := alloc(x.length) + buf := alloc(x.length, nil) memcpy(buf, unsafe.Pointer(x.ptr), x.length) slice.ptr = (*byte)(buf) slice.len = x.length @@ -98,7 +98,7 @@ func stringFromRunes(runeSlice []rune) (s _string) { } // Allocate memory for the string. - s.ptr = (*byte)(alloc(s.length)) + s.ptr = (*byte)(alloc(s.length, nil)) // Encode runes to UTF-8 and store the resulting bytes in the string. index := uintptr(0) diff --git a/transform/allocs.go b/transform/allocs.go index 00d318310..8bc81783e 100644 --- a/transform/allocs.go +++ b/transform/allocs.go @@ -70,7 +70,7 @@ func OptimizeAllocs(mod llvm.Module, printAllocs *regexp.Regexp, logger func(tok } // In general the pattern is: - // %0 = call i8* @runtime.alloc(i32 %size) + // %0 = call i8* @runtime.alloc(i32 %size, i8* null) // %1 = bitcast i8* %0 to type* // (use %1 only) // But the bitcast might sometimes be dropped when allocating an *i8. diff --git a/transform/coroutines.go b/transform/coroutines.go index e1f109b1b..b737fec4d 100644 --- a/transform/coroutines.go +++ b/transform/coroutines.go @@ -627,7 +627,7 @@ func (async *asyncFunc) hasValueStoreReturn() bool { func (c *coroutineLoweringPass) heapAlloc(t llvm.Type, name string) llvm.Value { sizeT := c.alloc.FirstParam().Type() size := llvm.ConstInt(sizeT, c.target.TypeAllocSize(t), false) - return c.builder.CreateCall(c.alloc, []llvm.Value{size, llvm.Undef(c.i8ptr), llvm.Undef(c.i8ptr)}, name) + return c.builder.CreateCall(c.alloc, []llvm.Value{size, llvm.ConstNull(c.i8ptr), llvm.Undef(c.i8ptr), llvm.Undef(c.i8ptr)}, name) } // lowerFuncFast lowers an async function that has no suspend points. @@ -798,7 +798,7 @@ func (c *coroutineLoweringPass) lowerFuncCoro(fn *asyncFunc) { // %coro.size = call i32 @llvm.coro.size.i32() coroSize := c.builder.CreateCall(c.coroSize, []llvm.Value{}, "coro.size") // %coro.alloc = call i8* runtime.alloc(i32 %coro.size) - coroAlloc := c.builder.CreateCall(c.alloc, []llvm.Value{coroSize, llvm.Undef(c.i8ptr), llvm.Undef(c.i8ptr)}, "coro.alloc") + coroAlloc := c.builder.CreateCall(c.alloc, []llvm.Value{coroSize, llvm.ConstNull(c.i8ptr), llvm.Undef(c.i8ptr), llvm.Undef(c.i8ptr)}, "coro.alloc") // %coro.state = call noalias i8* @llvm.coro.begin(token %coro.id, i8* %coro.alloc) coroState := c.builder.CreateCall(c.coroBegin, []llvm.Value{coroId, coroAlloc}, "coro.state") c.track(coroState) diff --git a/transform/testdata/allocs.ll b/transform/testdata/allocs.ll index 42932f4fe..58af2ea82 100644 --- a/transform/testdata/allocs.ll +++ b/transform/testdata/allocs.ll @@ -3,11 +3,11 @@ target triple = "armv7m-none-eabi" @runtime.zeroSizedAlloc = internal global i8 0, align 1 -declare nonnull i8* @runtime.alloc(i32) +declare nonnull i8* @runtime.alloc(i32, i8*) ; Test allocating a single int (i32) that should be allocated on the stack. define void @testInt() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* store i32 5, i32* %2 ret void @@ -16,7 +16,7 @@ define void @testInt() { ; Test allocating an array of 3 i16 values that should be allocated on the ; stack. define i16 @testArray() { - %1 = call i8* @runtime.alloc(i32 6) + %1 = call i8* @runtime.alloc(i32 6, i8* null) %2 = bitcast i8* %1 to i16* %3 = getelementptr i16, i16* %2, i32 1 store i16 5, i16* %3 @@ -28,14 +28,14 @@ define i16 @testArray() { ; Call a function that will let the pointer escape, so the heap-to-stack ; transform shouldn't be applied. define void @testEscapingCall() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* %3 = call i32* @escapeIntPtr(i32* %2) ret void } define void @testEscapingCall2() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* %3 = call i32* @escapeIntPtrSometimes(i32* %2, i32* %2) ret void @@ -43,7 +43,7 @@ define void @testEscapingCall2() { ; Call a function that doesn't let the pointer escape. define void @testNonEscapingCall() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* %3 = call i32* @noescapeIntPtr(i32* %2) ret void @@ -51,7 +51,7 @@ define void @testNonEscapingCall() { ; Return the allocated value, which lets it escape. define i32* @testEscapingReturn() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* ret i32* %2 } @@ -61,7 +61,7 @@ define void @testNonEscapingLoop() { entry: br label %loop loop: - %0 = call i8* @runtime.alloc(i32 4) + %0 = call i8* @runtime.alloc(i32 4, i8* null) %1 = bitcast i8* %0 to i32* %2 = call i32* @noescapeIntPtr(i32* %1) %3 = icmp eq i32* null, %2 @@ -72,7 +72,7 @@ end: ; Test a zero-sized allocation. define void @testZeroSizedAlloc() { - %1 = call i8* @runtime.alloc(i32 0) + %1 = call i8* @runtime.alloc(i32 0, i8* null) %2 = bitcast i8* %1 to i32* %3 = call i32* @noescapeIntPtr(i32* %2) ret void diff --git a/transform/testdata/allocs.out.ll b/transform/testdata/allocs.out.ll index 4543ac177..ec7c4c59b 100644 --- a/transform/testdata/allocs.out.ll +++ b/transform/testdata/allocs.out.ll @@ -3,7 +3,7 @@ target triple = "armv7m-none-eabi" @runtime.zeroSizedAlloc = internal global i8 0, align 1 -declare nonnull i8* @runtime.alloc(i32) +declare nonnull i8* @runtime.alloc(i32, i8*) define void @testInt() { %stackalloc.alloca = alloca [1 x i32], align 4 @@ -25,14 +25,14 @@ define i16 @testArray() { } define void @testEscapingCall() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* %3 = call i32* @escapeIntPtr(i32* %2) ret void } define void @testEscapingCall2() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* %3 = call i32* @escapeIntPtrSometimes(i32* %2, i32* %2) ret void @@ -47,7 +47,7 @@ define void @testNonEscapingCall() { } define i32* @testEscapingReturn() { - %1 = call i8* @runtime.alloc(i32 4) + %1 = call i8* @runtime.alloc(i32 4, i8* null) %2 = bitcast i8* %1 to i32* ret i32* %2 } diff --git a/transform/testdata/coroutines.ll b/transform/testdata/coroutines.ll index 94462bbcb..c5f711d25 100644 --- a/transform/testdata/coroutines.ll +++ b/transform/testdata/coroutines.ll @@ -9,7 +9,7 @@ declare void @"internal/task.Pause"(i8*, i8*) declare void @runtime.scheduler(i8*, i8*) -declare i8* @runtime.alloc(i32, i8*, i8*) +declare i8* @runtime.alloc(i32, i8*, i8*, i8*) declare void @runtime.free(i8*, i8*, i8*) declare %"internal/task.Task"* @"internal/task.Current"(i8*, i8*) diff --git a/transform/testdata/coroutines.out.ll b/transform/testdata/coroutines.out.ll index fa6eb287d..d4a49a5e4 100644 --- a/transform/testdata/coroutines.out.ll +++ b/transform/testdata/coroutines.out.ll @@ -10,7 +10,7 @@ declare void @"internal/task.Pause"(i8*, i8*) declare void @runtime.scheduler(i8*, i8*) -declare i8* @runtime.alloc(i32, i8*, i8*) +declare i8* @runtime.alloc(i32, i8*, i8*, i8*) declare void @runtime.free(i8*, i8*, i8*) @@ -66,7 +66,7 @@ entry: define void @ditchTail(i32 %0, i64 %1, i8* %2, i8* %parentHandle) { entry: %task.current = bitcast i8* %parentHandle to %"internal/task.Task"* - %ret.ditch = call i8* @runtime.alloc(i32 4, i8* undef, i8* undef) + %ret.ditch = call i8* @runtime.alloc(i32 4, i8* null, i8* undef, i8* undef) call void @"(*internal/task.Task).setReturnPtr"(%"internal/task.Task"* %task.current, i8* %ret.ditch, i8* undef, i8* undef) %3 = call i32 @delayedValue(i32 %0, i64 %1, i8* undef, i8* %parentHandle) ret void @@ -85,7 +85,7 @@ entry: %ret.ptr = call i8* @"(*internal/task.Task).getReturnPtr"(%"internal/task.Task"* %task.current, i8* undef, i8* undef) %ret.ptr.bitcast = bitcast i8* %ret.ptr to i32* store i32 %0, i32* %ret.ptr.bitcast, align 4 - %ret.alternate = call i8* @runtime.alloc(i32 4, i8* undef, i8* undef) + %ret.alternate = call i8* @runtime.alloc(i32 4, i8* null, i8* undef, i8* undef) call void @"(*internal/task.Task).setReturnPtr"(%"internal/task.Task"* %task.current, i8* %ret.alternate, i8* undef, i8* undef) %4 = call i32 @delayedValue(i32 %1, i64 %2, i8* undef, i8* %parentHandle) ret i32 undef @@ -96,7 +96,7 @@ entry: %call.return = alloca i32, align 4 %coro.id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %coro.size = call i32 @llvm.coro.size.i32() - %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* undef, i8* undef) + %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* null, i8* undef, i8* undef) %coro.state = call i8* @llvm.coro.begin(token %coro.id, i8* %coro.alloc) %task.current2 = bitcast i8* %parentHandle to %"internal/task.Task"* %task.state.parent = call i8* @"(*internal/task.Task).setState"(%"internal/task.Task"* %task.current2, i8* %coro.state, i8* undef, i8* undef) @@ -143,7 +143,7 @@ entry: %a = alloca i8, align 1 %coro.id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %coro.size = call i32 @llvm.coro.size.i32() - %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* undef, i8* undef) + %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* null, i8* undef, i8* undef) %coro.state = call i8* @llvm.coro.begin(token %coro.id, i8* %coro.alloc) %task.current = bitcast i8* %parentHandle to %"internal/task.Task"* %task.state.parent = call i8* @"(*internal/task.Task).setState"(%"internal/task.Task"* %task.current, i8* %coro.state, i8* undef, i8* undef) @@ -180,7 +180,7 @@ entry: %a = alloca i8, align 1 %coro.id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %coro.size = call i32 @llvm.coro.size.i32() - %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* undef, i8* undef) + %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* null, i8* undef, i8* undef) %coro.state = call i8* @llvm.coro.begin(token %coro.id, i8* %coro.alloc) %task.current = bitcast i8* %parentHandle to %"internal/task.Task"* %task.state.parent = call i8* @"(*internal/task.Task).setState"(%"internal/task.Task"* %task.current, i8* %coro.state, i8* undef, i8* undef) @@ -225,7 +225,7 @@ define i8 @usePtr(i8* %0, i8* %1, i8* %parentHandle) { entry: %coro.id = call token @llvm.coro.id(i32 0, i8* null, i8* null, i8* null) %coro.size = call i32 @llvm.coro.size.i32() - %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* undef, i8* undef) + %coro.alloc = call i8* @runtime.alloc(i32 %coro.size, i8* null, i8* undef, i8* undef) %coro.state = call i8* @llvm.coro.begin(token %coro.id, i8* %coro.alloc) %task.current = bitcast i8* %parentHandle to %"internal/task.Task"* %task.state.parent = call i8* @"(*internal/task.Task).setState"(%"internal/task.Task"* %task.current, i8* %coro.state, i8* undef, i8* undef) diff --git a/transform/testdata/gc-stackslots.ll b/transform/testdata/gc-stackslots.ll index 8b43a83e8..130b0c990 100644 --- a/transform/testdata/gc-stackslots.ll +++ b/transform/testdata/gc-stackslots.ll @@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown-wasm" declare void @runtime.trackPointer(i8* nocapture readonly) -declare noalias nonnull i8* @runtime.alloc(i32) +declare noalias nonnull i8* @runtime.alloc(i32, i8*) ; Generic function that returns a pointer (that must be tracked). define i8* @getPointer() { @@ -18,7 +18,7 @@ define i8* @getPointer() { define i8* @needsStackSlots() { ; Tracked pointer. Although, in this case the value is immediately returned ; so tracking it is not really necessary. - %ptr = call i8* @runtime.alloc(i32 4) + %ptr = call i8* @runtime.alloc(i32 4, i8* null) call void @runtime.trackPointer(i8* %ptr) ; Restoring the stack pointer can happen at this position, before the return. ; This avoids issues with tail calls. @@ -41,7 +41,7 @@ define i8* @needsStackSlots2() { call void @runtime.trackPointer(i8* %ptr2) ; Here is finally the point where an allocation happens. - %unused = call i8* @runtime.alloc(i32 4) + %unused = call i8* @runtime.alloc(i32 4, i8* null) call void @runtime.trackPointer(i8* %unused) ret i8* %ptr1 @@ -59,7 +59,7 @@ define i8* @fibNext(i8* %x, i8* %y) { %x.val = load i8, i8* %x %y.val = load i8, i8* %y %out.val = add i8 %x.val, %y.val - %out.alloc = call i8* @runtime.alloc(i32 1) + %out.alloc = call i8* @runtime.alloc(i32 1, i8* null) call void @runtime.trackPointer(i8* %out.alloc) store i8 %out.val, i8* %out.alloc ret i8* %out.alloc @@ -67,9 +67,9 @@ define i8* @fibNext(i8* %x, i8* %y) { define i8* @allocLoop() { entry: - %entry.x = call i8* @runtime.alloc(i32 1) + %entry.x = call i8* @runtime.alloc(i32 1, i8* null) call void @runtime.trackPointer(i8* %entry.x) - %entry.y = call i8* @runtime.alloc(i32 1) + %entry.y = call i8* @runtime.alloc(i32 1, i8* null) call void @runtime.trackPointer(i8* %entry.y) store i8 1, i8* %entry.y br label %loop @@ -95,7 +95,7 @@ define void @testGEPBitcast() { %arr = call [32 x i8]* @arrayAlloc() %arr.bitcast = getelementptr [32 x i8], [32 x i8]* %arr, i32 0, i32 0 call void @runtime.trackPointer(i8* %arr.bitcast) - %other = call i8* @runtime.alloc(i32 1) + %other = call i8* @runtime.alloc(i32 1, i8* null) call void @runtime.trackPointer(i8* %other) ret void } diff --git a/transform/testdata/gc-stackslots.out.ll b/transform/testdata/gc-stackslots.out.ll index af474534c..15fab17ed 100644 --- a/transform/testdata/gc-stackslots.out.ll +++ b/transform/testdata/gc-stackslots.out.ll @@ -8,7 +8,7 @@ target triple = "wasm32-unknown-unknown-wasm" declare void @runtime.trackPointer(i8* nocapture readonly) -declare noalias nonnull i8* @runtime.alloc(i32) +declare noalias nonnull i8* @runtime.alloc(i32, i8*) define i8* @getPointer() { ret i8* @someGlobal @@ -22,7 +22,7 @@ define i8* @needsStackSlots() { store %runtime.stackChainObject* %1, %runtime.stackChainObject** %2, align 4 %3 = bitcast { %runtime.stackChainObject*, i32, i8* }* %gc.stackobject to %runtime.stackChainObject* store %runtime.stackChainObject* %3, %runtime.stackChainObject** @runtime.stackChainStart, align 4 - %ptr = call i8* @runtime.alloc(i32 4) + %ptr = call i8* @runtime.alloc(i32 4, i8* null) %4 = getelementptr { %runtime.stackChainObject*, i32, i8* }, { %runtime.stackChainObject*, i32, i8* }* %gc.stackobject, i32 0, i32 2 store i8* %ptr, i8** %4, align 4 store %runtime.stackChainObject* %1, %runtime.stackChainObject** @runtime.stackChainStart, align 4 @@ -49,7 +49,7 @@ define i8* @needsStackSlots2() { %ptr2 = getelementptr i8, i8* @someGlobal, i32 0 %7 = getelementptr { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }, { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }* %gc.stackobject, i32 0, i32 5 store i8* %ptr2, i8** %7, align 4 - %unused = call i8* @runtime.alloc(i32 4) + %unused = call i8* @runtime.alloc(i32 4, i8* null) %8 = getelementptr { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }, { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }* %gc.stackobject, i32 0, i32 6 store i8* %unused, i8** %8, align 4 store %runtime.stackChainObject* %1, %runtime.stackChainObject** @runtime.stackChainStart, align 4 @@ -72,7 +72,7 @@ define i8* @fibNext(i8* %x, i8* %y) { %x.val = load i8, i8* %x, align 1 %y.val = load i8, i8* %y, align 1 %out.val = add i8 %x.val, %y.val - %out.alloc = call i8* @runtime.alloc(i32 1) + %out.alloc = call i8* @runtime.alloc(i32 1, i8* null) %4 = getelementptr { %runtime.stackChainObject*, i32, i8* }, { %runtime.stackChainObject*, i32, i8* }* %gc.stackobject, i32 0, i32 2 store i8* %out.alloc, i8** %4, align 4 store %runtime.stackChainObject* %1, %runtime.stackChainObject** @runtime.stackChainStart, align 4 @@ -89,10 +89,10 @@ entry: store %runtime.stackChainObject* %0, %runtime.stackChainObject** %1, align 4 %2 = bitcast { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }* %gc.stackobject to %runtime.stackChainObject* store %runtime.stackChainObject* %2, %runtime.stackChainObject** @runtime.stackChainStart, align 4 - %entry.x = call i8* @runtime.alloc(i32 1) + %entry.x = call i8* @runtime.alloc(i32 1, i8* null) %3 = getelementptr { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }, { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }* %gc.stackobject, i32 0, i32 2 store i8* %entry.x, i8** %3, align 4 - %entry.y = call i8* @runtime.alloc(i32 1) + %entry.y = call i8* @runtime.alloc(i32 1, i8* null) %4 = getelementptr { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }, { %runtime.stackChainObject*, i32, i8*, i8*, i8*, i8*, i8* }* %gc.stackobject, i32 0, i32 3 store i8* %entry.y, i8** %4, align 4 store i8 1, i8* %entry.y, align 1 @@ -131,7 +131,7 @@ define void @testGEPBitcast() { %arr.bitcast = getelementptr [32 x i8], [32 x i8]* %arr, i32 0, i32 0 %4 = getelementptr { %runtime.stackChainObject*, i32, i8*, i8* }, { %runtime.stackChainObject*, i32, i8*, i8* }* %gc.stackobject, i32 0, i32 2 store i8* %arr.bitcast, i8** %4, align 4 - %other = call i8* @runtime.alloc(i32 1) + %other = call i8* @runtime.alloc(i32 1, i8* null) %5 = getelementptr { %runtime.stackChainObject*, i32, i8*, i8* }, { %runtime.stackChainObject*, i32, i8*, i8* }* %gc.stackobject, i32 0, i32 3 store i8* %other, i8** %5, align 4 store %runtime.stackChainObject* %1, %runtime.stackChainObject** @runtime.stackChainStart, align 4 diff --git a/transform/transform_test.go b/transform/transform_test.go index 9689a063a..a578c3963 100644 --- a/transform/transform_test.go +++ b/transform/transform_test.go @@ -41,6 +41,12 @@ func testTransform(t *testing.T, pathPrefix string, transform func(mod llvm.Modu // Perform the transform. transform(mod) + // Check for any incorrect IR. + err = llvm.VerifyModule(mod, llvm.PrintMessageAction) + if err != nil { + t.Fatal("IR verification failed") + } + // Get the output from the test and filter some irrelevant lines. actual := mod.String() actual = actual[strings.Index(actual, "\ntarget datalayout = ")+1:] |