mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
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).
This commit is contained in:
committed by
Ron Evans
parent
c454568688
commit
f24a93c51d
Vendored
+9
-9
@@ -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
|
||||
|
||||
Vendored
+4
-4
@@ -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
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -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*)
|
||||
|
||||
Vendored
+7
-7
@@ -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)
|
||||
|
||||
Vendored
+7
-7
@@ -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
|
||||
}
|
||||
|
||||
+7
-7
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user