From 57ff3a5ca0a8b195b4fe500b0a97bafc3e0094dc Mon Sep 17 00:00:00 2001 From: Nia Waldvogel Date: Fri, 14 Jan 2022 11:06:33 -0500 Subject: [PATCH] compiler: predeclare runtime.trackPointer When a package only uses runtime.trackPointer to create interface packs, the compiler fails to find runtime.trackPointer. This change predeclares it alongside runtime.alloc and updates the tests to use runtime.trackPointer when the test's target uses it. --- compiler/compiler.go | 4 ++++ compiler/compiler_test.go | 1 + compiler/testdata/basic.ll | 2 ++ compiler/testdata/channel.ll | 5 +++++ compiler/testdata/float.ll | 2 ++ compiler/testdata/func-coroutines.ll | 2 ++ compiler/testdata/gc.ll | 19 +++++++++++++++++ compiler/testdata/go1.17.ll | 12 +++++++++++ compiler/testdata/goroutine-wasm-asyncify.ll | 8 +++++++ .../testdata/goroutine-wasm-coroutines.ll | 7 +++++++ compiler/testdata/interface.ll | 8 +++++++ compiler/testdata/intrinsics-wasm.ll | 2 ++ compiler/testdata/pointer.ll | 21 +++++++++++++++++-- compiler/testdata/pragma.ll | 2 ++ compiler/testdata/slice.ll | 9 ++++++++ compiler/testdata/string.ll | 2 ++ 16 files changed, 104 insertions(+), 2 deletions(-) diff --git a/compiler/compiler.go b/compiler/compiler.go index 6c0c98b2..86b20306 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -270,6 +270,10 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package, // Predeclare the runtime.alloc function, which is used by the wordpack // functionality. c.getFunction(c.program.ImportedPackage("runtime").Members["alloc"].(*ssa.Function)) + if c.NeedsStackObjects { + // Predeclare trackPointer, which is used everywhere we use runtime.alloc. + c.getFunction(c.program.ImportedPackage("runtime").Members["trackPointer"].(*ssa.Function)) + } // Compile all functions, methods, and global variables in this package. irbuilder := c.ctx.NewBuilder() diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go index 65a1c626..ef22faca 100644 --- a/compiler/compiler_test.go +++ b/compiler/compiler_test.go @@ -109,6 +109,7 @@ func TestCompiler(t *testing.T) { FuncImplementation: config.FuncImplementation(), AutomaticStackSize: config.AutomaticStackSize(), DefaultStackSize: config.Target.DefaultStackSize, + NeedsStackObjects: config.NeedsStackObjects(), } machine, err := NewTargetMachine(compilerConfig) if err != nil { diff --git a/compiler/testdata/basic.ll b/compiler/testdata/basic.ll index 69b72f27..569b2f7f 100644 --- a/compiler/testdata/basic.ll +++ b/compiler/testdata/basic.ll @@ -8,6 +8,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll index fa80db5d..86c6417d 100644 --- a/compiler/testdata/channel.ll +++ b/compiler/testdata/channel.ll @@ -13,6 +13,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -63,7 +65,10 @@ declare i1 @runtime.chanRecv(%runtime.channel* dereferenceable_or_null(32), i8*, ; Function Attrs: nounwind define hidden void @main.chanZeroSend(%runtime.channel* dereferenceable_or_null(32) %ch, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + %complit = alloca {}, align 8 %chan.blockedList = alloca %runtime.channelBlockedList, align 8 + %0 = bitcast {}* %complit to i8* + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 %chan.blockedList.bitcast = bitcast %runtime.channelBlockedList* %chan.blockedList to i8* call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %chan.blockedList.bitcast) call void @runtime.chanSend(%runtime.channel* %ch, i8* null, %runtime.channelBlockedList* nonnull %chan.blockedList, i8* undef, i8* null) #0 diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll index e96f8cd7..15bf39d7 100644 --- a/compiler/testdata/float.ll +++ b/compiler/testdata/float.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/func-coroutines.ll b/compiler/testdata/func-coroutines.ll index b88ce514..d9c5c4d4 100644 --- a/compiler/testdata/func-coroutines.ll +++ b/compiler/testdata/func-coroutines.ll @@ -10,6 +10,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll index 7443c5d4..79f0bce5 100644 --- a/compiler/testdata/gc.ll +++ b/compiler/testdata/gc.ll @@ -28,6 +28,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -38,12 +40,16 @@ entry: define hidden void @main.newScalar(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %new = call i8* @runtime.alloc(i32 1, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 store i8* %new, i8** @main.scalar1, align 4 %new1 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new1, i8* undef, i8* null) #0 store i8* %new1, i8** bitcast (i32** @main.scalar2 to i8**), align 4 %new2 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new2, i8* undef, i8* null) #0 store i8* %new2, i8** bitcast (i64** @main.scalar3 to i8**), align 4 %new3 = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new3, i8* undef, i8* null) #0 store i8* %new3, i8** bitcast (float** @main.scalar4 to i8**), align 4 ret void } @@ -52,10 +58,13 @@ entry: define hidden void @main.newArray(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %new = call i8* @runtime.alloc(i32 3, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 store i8* %new, i8** bitcast ([3 x i8]** @main.array1 to i8**), align 4 %new1 = call i8* @runtime.alloc(i32 71, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new1, i8* undef, i8* null) #0 store i8* %new1, i8** bitcast ([71 x i8]** @main.array2 to i8**), align 4 %new2 = call i8* @runtime.alloc(i32 12, i8* nonnull inttoptr (i32 67 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new2, i8* undef, i8* null) #0 store i8* %new2, i8** bitcast ([3 x i8*]** @main.array3 to i8**), align 4 ret void } @@ -64,12 +73,16 @@ entry: define hidden void @main.newStruct(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %new = call i8* @runtime.alloc(i32 0, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 store i8* %new, i8** bitcast ({}** @main.struct1 to i8**), align 4 %new1 = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new1, i8* undef, i8* null) #0 store i8* %new1, i8** bitcast ({ i32, i32 }** @main.struct2 to i8**), align 4 %new2 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-2000000000000001" to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new2, i8* undef, i8* null) #0 store i8* %new2, i8** bitcast ({ i8*, [60 x i32], i8* }** @main.struct3 to i8**), align 4 %new3 = call i8* @runtime.alloc(i32 248, i8* bitcast ({ i32, [8 x i8] }* @"runtime/gc.layout:62-0001" to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %new3, i8* undef, i8* null) #0 store i8* %new3, i8** bitcast ({ i8*, [61 x i32] }** @main.struct4 to i8**), align 4 ret void } @@ -79,6 +92,7 @@ define hidden { i8*, void ()* }* @main.newFuncValue(i8* %context, i8* %parentHan entry: %new = call i8* @runtime.alloc(i32 8, i8* nonnull inttoptr (i32 197 to i8*), i8* undef, i8* null) #0 %0 = bitcast i8* %new to { i8*, void ()* }* + call void @runtime.trackPointer(i8* nonnull %new, i8* undef, i8* null) #0 ret { i8*, void ()* }* %0 } @@ -86,14 +100,17 @@ entry: define hidden void @main.makeSlice(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %makeslice = call i8* @runtime.alloc(i32 5, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef, i8* null) #0 store i8* %makeslice, i8** getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 0), align 8 store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 1), align 4 store i32 5, i32* getelementptr inbounds ({ i8*, i32, i32 }, { i8*, i32, i32 }* @main.slice1, i32 0, i32 2), align 8 %makeslice1 = call i8* @runtime.alloc(i32 20, i8* nonnull inttoptr (i32 67 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice1, i8* undef, i8* null) #0 store i8* %makeslice1, i8** bitcast ({ i32**, i32, i32 }* @main.slice2 to i8**), align 8 store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 1), align 4 store i32 5, i32* getelementptr inbounds ({ i32**, i32, i32 }, { i32**, i32, i32 }* @main.slice2, i32 0, i32 2), align 8 %makeslice3 = call i8* @runtime.alloc(i32 60, i8* nonnull inttoptr (i32 71 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice3, i8* undef, i8* null) #0 store i8* %makeslice3, i8** bitcast ({ { i8*, i32, i32 }*, i32, i32 }* @main.slice3 to i8**), align 8 store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 1), align 4 store i32 5, i32* getelementptr inbounds ({ { i8*, i32, i32 }*, i32, i32 }, { { i8*, i32, i32 }*, i32, i32 }* @main.slice3, i32 0, i32 2), align 8 @@ -104,12 +121,14 @@ entry: define hidden %runtime._interface @main.makeInterface(double %v.r, double %v.i, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call i8* @runtime.alloc(i32 16, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 %.repack = bitcast i8* %0 to double* store double %v.r, double* %.repack, align 8 %.repack1 = getelementptr inbounds i8, i8* %0, i32 8 %1 = bitcast i8* %.repack1 to double* store double %v.i, double* %1, align 8 %2 = insertvalue %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:complex128" to i32), i8* undef }, i8* %0, 1 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 ret %runtime._interface %2 } diff --git a/compiler/testdata/go1.17.ll b/compiler/testdata/go1.17.ll index 1499547f..5b50cb50 100644 --- a/compiler/testdata/go1.17.ll +++ b/compiler/testdata/go1.17.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -15,6 +17,7 @@ entry: define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = getelementptr i8, i8* %p, i32 %len + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 ret i8* %0 } @@ -23,6 +26,7 @@ define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context, i8* %parentHandle) entry: %0 = trunc i64 %len to i32 %1 = getelementptr i8, i8* %p, i32 %0 + call void @runtime.trackPointer(i8* %1, i8* undef, i8* null) #0 ret i8* %1 } @@ -47,6 +51,7 @@ declare void @runtime.sliceToArrayPointerPanic(i8*, i8*) define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %makeslice = call i8* @runtime.alloc(i32 24, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef, i8* null) #0 br i1 false, label %slicetoarray.throw, label %slicetoarray.next slicetoarray.throw: ; preds = %entry @@ -75,6 +80,8 @@ unsafe.Slice.next: ; preds = %entry %5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 %6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1 %7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2 + %8 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %8, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %7 } @@ -97,6 +104,7 @@ unsafe.Slice.next: ; preds = %entry %4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0 %5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1 %6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2 + call void @runtime.trackPointer(i8* %ptr, i8* undef, i8* null) #0 ret { i8*, i32, i32 } %6 } @@ -119,6 +127,8 @@ unsafe.Slice.next: ; preds = %entry %6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 %7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 %8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 + %9 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %9, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %8 } @@ -141,6 +151,8 @@ unsafe.Slice.next: ; preds = %entry %6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0 %7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1 %8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2 + %9 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %9, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %8 } diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll index aa01d0f4..76473cda 100644 --- a/compiler/testdata/goroutine-wasm-asyncify.ll +++ b/compiler/testdata/goroutine-wasm-asyncify.ll @@ -15,6 +15,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -70,8 +72,12 @@ define hidden void @main.closureFunctionGoroutine(i8* %context, i8* %parentHandl entry: %n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 %0 = bitcast i8* %n to i32* + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 store i32 3, i32* %0, align 4 + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* bitcast (void (i32, i8*, i8*)* @"main.closureFunctionGoroutine$1" to i8*), i8* undef, i8* null) #0 %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %1, 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 @@ -110,6 +116,7 @@ declare void @runtime.printint32(i32, i8*, i8*) 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* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, 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 @@ -166,6 +173,7 @@ declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i 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* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, 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-coroutines.ll b/compiler/testdata/goroutine-wasm-coroutines.ll index fe7b89b5..42a7d6e1 100644 --- a/compiler/testdata/goroutine-wasm-coroutines.ll +++ b/compiler/testdata/goroutine-wasm-coroutines.ll @@ -19,6 +19,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -54,8 +56,11 @@ define hidden void @main.closureFunctionGoroutine(i8* %context, i8* %parentHandl entry: %n = call i8* @runtime.alloc(i32 4, i8* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 %0 = bitcast i8* %n to i32* + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 store i32 3, i32* %0, align 4 + call void @runtime.trackPointer(i8* nonnull %n, i8* undef, i8* null) #0 %1 = call i8* @runtime.alloc(i32 8, i8* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %1, 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 @@ -82,6 +87,7 @@ define hidden void @main.funcGoroutine(i8* %fn.context, i32 %fn.funcptr, i8* %co 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* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %1, 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 @@ -121,6 +127,7 @@ declare void @runtime.chanClose(%runtime.channel* dereferenceable_or_null(32), i 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* null, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, 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 c27142ec..c9ff0a90 100644 --- a/compiler/testdata/interface.ll +++ b/compiler/testdata/interface.ll @@ -24,6 +24,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -33,18 +35,21 @@ entry: ; Function Attrs: nounwind define hidden %runtime._interface @main.simpleType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:basic:int" to i32), i8* null } } ; Function Attrs: nounwind define hidden %runtime._interface @main.pointerType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:basic:int" to i32), i8* null } } ; Function Attrs: nounwind define hidden %runtime._interface @main.interfaceType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:named:error" to i32), i8* null } } @@ -53,6 +58,7 @@ declare i1 @"interface:{Error:func:{}{basic:string}}.$typeassert"(i32) #1 ; Function Attrs: nounwind define hidden %runtime._interface @main.anonymousInterfaceType(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* null, i8* undef, i8* null) #0 ret %runtime._interface { i32 ptrtoint (%runtime.typecodeID* @"reflect/types.type:pointer:interface:{String:func:{}{basic:string}}" to i32), i8* null } } @@ -112,6 +118,8 @@ declare i8 @"interface:{String:func:{}{basic:string},main.foo:func:{basic:int}{b define hidden %runtime._string @main.callErrorMethod(i32 %itf.typecode, i8* %itf.value, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = call %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(i8* %itf.value, i32 %itf.typecode, i8* undef, i8* undef) #0 + %1 = extractvalue %runtime._string %0, 0 + call void @runtime.trackPointer(i8* %1, i8* undef, i8* null) #0 ret %runtime._string %0 } diff --git a/compiler/testdata/intrinsics-wasm.ll b/compiler/testdata/intrinsics-wasm.ll index ce20dfd0..e24e61c3 100644 --- a/compiler/testdata/intrinsics-wasm.ll +++ b/compiler/testdata/intrinsics-wasm.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll index 7020c0fa..e236db83 100644 --- a/compiler/testdata/pointer.ll +++ b/compiler/testdata/pointer.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -21,6 +23,7 @@ entry: define hidden i32* @main.pointerCastFromUnsafe(i8* %x, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = bitcast i8* %x to i32* + call void @runtime.trackPointer(i8* %x, i8* undef, i8* null) #0 ret i32* %0 } @@ -28,34 +31,48 @@ entry: define hidden i8* @main.pointerCastToUnsafe(i32* dereferenceable_or_null(4) %x, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: %0 = bitcast i32* %x to i8* + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 ret i8* %0 } ; Function Attrs: nounwind define hidden i8* @main.pointerCastToUnsafeNoop(i8* dereferenceable_or_null(1) %x, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* %x, i8* undef, i8* null) #0 ret i8* %x } ; Function Attrs: nounwind define hidden i8* @main.pointerUnsafeGEPFixedOffset(i8* dereferenceable_or_null(1) %ptr, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* %ptr, i8* undef, i8* null) #0 %0 = getelementptr inbounds i8, i8* %ptr, i32 10 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %0, i8* undef, i8* null) #0 ret i8* %0 } ; Function Attrs: nounwind define hidden i8* @main.pointerUnsafeGEPByteOffset(i8* dereferenceable_or_null(1) %ptr, i32 %offset, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: + call void @runtime.trackPointer(i8* %ptr, i8* undef, i8* null) #0 %0 = getelementptr inbounds i8, i8* %ptr, i32 %offset + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 ret i8* %0 } ; Function Attrs: nounwind define hidden i32* @main.pointerUnsafeGEPIntOffset(i32* dereferenceable_or_null(4) %ptr, i32 %offset, i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: - %0 = getelementptr i32, i32* %ptr, i32 %offset - ret i32* %0 + %0 = bitcast i32* %ptr to i8* + call void @runtime.trackPointer(i8* %0, i8* undef, i8* null) #0 + %1 = getelementptr i32, i32* %ptr, i32 %offset + %2 = bitcast i32* %1 to i8* + call void @runtime.trackPointer(i8* %2, i8* undef, i8* null) #0 + %3 = bitcast i32* %1 to i8* + call void @runtime.trackPointer(i8* %3, i8* undef, i8* null) #0 + ret i32* %1 } attributes #0 = { nounwind } diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll index 943b574d..ee189c3f 100644 --- a/compiler/testdata/pragma.ll +++ b/compiler/testdata/pragma.ll @@ -12,6 +12,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll index 0cca8970..98d2b128 100644 --- a/compiler/testdata/slice.ll +++ b/compiler/testdata/slice.ll @@ -5,6 +5,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: @@ -45,6 +47,7 @@ declare void @runtime.lookupPanic(i8*, i8*) 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* nonnull inttoptr (i32 3 to i8*), i8* undef, i8* null) #0 + call void @runtime.trackPointer(i8* nonnull %varargs, 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 @@ -62,6 +65,7 @@ entry: %5 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0 %6 = insertvalue { i32*, i32, i32 } %5, i32 %append.newLen, 1 %7 = insertvalue { i32*, i32, i32 } %6, i32 %append.newCap, 2 + call void @runtime.trackPointer(i8* %append.newPtr, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %7 } @@ -80,6 +84,7 @@ entry: %0 = insertvalue { i32*, i32, i32 } undef, i32* %append.newBuf, 0 %1 = insertvalue { i32*, i32, i32 } %0, i32 %append.newLen, 1 %2 = insertvalue { i32*, i32, i32 } %1, i32 %append.newCap, 2 + call void @runtime.trackPointer(i8* %append.newPtr, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %2 } @@ -109,6 +114,7 @@ slice.next: ; preds = %entry %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 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { i8*, i32, i32 } %2 } @@ -131,6 +137,7 @@ slice.next: ; preds = %entry %0 = insertvalue { i16*, i32, i32 } undef, i16* %makeslice.array, 0 %1 = insertvalue { i16*, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { i16*, i32, i32 } %1, i32 %len, 2 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { i16*, i32, i32 } %2 } @@ -151,6 +158,7 @@ slice.next: ; preds = %entry %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 %2 = insertvalue { [3 x i8]*, i32, i32 } %1, i32 %len, 2 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { [3 x i8]*, i32, i32 } %2 } @@ -171,6 +179,7 @@ slice.next: ; preds = %entry %0 = insertvalue { i32*, i32, i32 } undef, i32* %makeslice.array, 0 %1 = insertvalue { i32*, i32, i32 } %0, i32 %len, 1 %2 = insertvalue { i32*, i32, i32 } %1, i32 %len, 2 + call void @runtime.trackPointer(i8* nonnull %makeslice.buf, i8* undef, i8* null) #0 ret { i32*, i32, i32 } %2 } diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll index 93f76059..ecbb6f0f 100644 --- a/compiler/testdata/string.ll +++ b/compiler/testdata/string.ll @@ -9,6 +9,8 @@ target triple = "wasm32-unknown-wasi" declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +declare void @runtime.trackPointer(i8* nocapture readonly, i8*, i8*) + ; Function Attrs: nounwind define hidden void @main.init(i8* %context, i8* %parentHandle) unnamed_addr #0 { entry: