aboutsummaryrefslogtreecommitdiffhomepage
path: root/transform
diff options
context:
space:
mode:
Diffstat (limited to 'transform')
-rw-r--r--transform/testdata/allocs.out.ll6
-rw-r--r--transform/testdata/coroutines.out.ll21
-rw-r--r--transform/testdata/func-lowering.out.ll35
-rw-r--r--transform/testdata/interface.out.ll20
-rw-r--r--transform/transform_test.go35
5 files changed, 73 insertions, 44 deletions
diff --git a/transform/testdata/allocs.out.ll b/transform/testdata/allocs.out.ll
index e788beeba..eacf62b24 100644
--- a/transform/testdata/allocs.out.ll
+++ b/transform/testdata/allocs.out.ll
@@ -54,13 +54,15 @@ define void @testNonEscapingLoop() {
entry:
%stackalloc.alloca = alloca [1 x i32]
br label %loop
-loop:
+
+loop: ; preds = %loop, %entry
store [1 x i32] zeroinitializer, [1 x i32]* %stackalloc.alloca
%stackalloc = bitcast [1 x i32]* %stackalloc.alloca to i32*
%0 = call i32* @noescapeIntPtr(i32* %stackalloc)
%1 = icmp eq i32* null, %0
br i1 %1, label %loop, label %end
-end:
+
+end: ; preds = %loop
ret void
}
diff --git a/transform/testdata/coroutines.out.ll b/transform/testdata/coroutines.out.ll
index ec03650bc..b46a414f0 100644
--- a/transform/testdata/coroutines.out.ll
+++ b/transform/testdata/coroutines.out.ll
@@ -5,11 +5,13 @@ target triple = "armv7m-none-eabi"
%"internal/task.state" = type { i8* }
declare void @"internal/task.start"(i32, i8*, i8*, i8*)
+
declare void @"internal/task.Pause"(i8*, i8*)
declare void @runtime.scheduler(i8*, i8*)
declare i8* @runtime.alloc(i32, i8*, i8*)
+
declare void @runtime.free(i8*, i8*, i8*)
declare %"internal/task.Task"* @"internal/task.Current"(i8*, i8*)
@@ -17,9 +19,11 @@ declare %"internal/task.Task"* @"internal/task.Current"(i8*, i8*)
declare i8* @"(*internal/task.Task).setState"(%"internal/task.Task"*, i8*, i8*, i8*)
declare void @"(*internal/task.Task).setReturnPtr"(%"internal/task.Task"*, i8*, i8*, i8*)
+
declare i8* @"(*internal/task.Task).getReturnPtr"(%"internal/task.Task"*, i8*, i8*)
declare void @"(*internal/task.Task).returnTo"(%"internal/task.Task"*, i8*, i8*, i8*)
+
declare void @"(*internal/task.Task).returnCurrent"(%"internal/task.Task"*, i8*, i8*)
declare %"internal/task.Task"* @"internal/task.createTask"(i8*, i8*)
@@ -27,6 +31,7 @@ declare %"internal/task.Task"* @"internal/task.createTask"(i8*, i8*)
declare void @callMain(i8*, i8*)
declare void @enqueueTimer(%"internal/task.Task"*, i64, i8*, i8*)
+
define void @sleep(i64, i8*, i8* %parentHandle) {
entry:
%task.current = bitcast i8* %parentHandle to %"internal/task.Task"*
@@ -159,15 +164,31 @@ entry:
ret void
}
+; Function Attrs: argmemonly nounwind readonly
declare token @llvm.coro.id(i32, i8* readnone, i8* nocapture readonly, i8*) #0
+
+; Function Attrs: nounwind readnone
declare i32 @llvm.coro.size.i32() #1
+
+; Function Attrs: nounwind
declare i8* @llvm.coro.begin(token, i8* writeonly) #2
+
+; Function Attrs: nounwind
declare i8 @llvm.coro.suspend(token, i1) #2
+
+; Function Attrs: nounwind
declare i1 @llvm.coro.end(i8*, i1) #2
+
+; Function Attrs: argmemonly nounwind readonly
declare i8* @llvm.coro.free(token, i8* nocapture readonly) #0
+
+; Function Attrs: nounwind
declare token @llvm.coro.save(i8*) #2
+; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #3
+
+; Function Attrs: argmemonly nounwind
declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #3
attributes #0 = { argmemonly nounwind readonly }
diff --git a/transform/testdata/func-lowering.out.ll b/transform/testdata/func-lowering.out.ll
index 97621730b..747d6e6e7 100644
--- a/transform/testdata/func-lowering.out.ll
+++ b/transform/testdata/func-lowering.out.ll
@@ -29,9 +29,6 @@ declare void @func1Uint8(i8, i8*, i8*)
declare void @func2Uint8(i8, i8*, i8*)
-; Call a function of which only one function with this signature is used as a
-; function value. This means that lowering it to IR is trivial: simply check
-; whether the func value is nil, and if not, call that one function directly.
define void @runFunc1(i8*, i32, i8, i8* %context, i8* %parentHandle) {
entry:
%3 = icmp eq i32 %1, 0
@@ -39,53 +36,49 @@ entry:
%5 = icmp eq void (i8, i8*, i8*)* %4, null
br i1 %5, label %fpcall.nil, label %fpcall.next
-fpcall.nil:
+fpcall.nil: ; preds = %entry
call void @runtime.nilPanic(i8* undef, i8* null)
unreachable
-fpcall.next:
+fpcall.next: ; preds = %entry
call void %4(i8 %2, i8* %0, i8* undef)
ret void
}
-; There are two functions with this signature used in a func value. That means
-; that we'll have to check at runtime which of the two it is (or whether the
-; func value is nil). This call will thus be lowered to a switch statement.
define void @runFunc2(i8*, i32, i8, i8* %context, i8* %parentHandle) {
entry:
br i1 false, label %fpcall.nil, label %fpcall.next
-fpcall.nil:
+fpcall.nil: ; preds = %entry
call void @runtime.nilPanic(i8* undef, i8* null)
unreachable
-fpcall.next:
+fpcall.next: ; preds = %entry
switch i32 %1, label %func.default [
i32 0, label %func.nil
i32 1, label %func.call1
i32 2, label %func.call2
]
-func.nil:
+func.nil: ; preds = %fpcall.next
call void @runtime.nilPanic(i8* undef, i8* null)
unreachable
-func.call1:
+func.call1: ; preds = %fpcall.next
call void @func1Uint8(i8 %2, i8* %0, i8* undef)
br label %func.next
-func.call2:
+func.call2: ; preds = %fpcall.next
call void @func2Uint8(i8 %2, i8* %0, i8* undef)
br label %func.next
-func.next:
+func.next: ; preds = %func.call2, %func.call1
ret void
-func.default:
+func.default: ; preds = %fpcall.next
unreachable
}
-; Special case for runtime.makeGoroutine.
define void @sleepFuncValue(i8*, i32, i8* nocapture readnone %context, i8* nocapture readnone %parentHandle) {
entry:
switch i32 %1, label %func.default [
@@ -94,21 +87,21 @@ entry:
i32 2, label %func.call2
]
-func.nil:
+func.nil: ; preds = %entry
call void @runtime.nilPanic(i8* undef, i8* null)
unreachable
-func.call1:
+func.call1: ; preds = %entry
call void @"internal/task.start"(i32 ptrtoint (void (i32, i8*, i8*)* @"main$1" to i32), i8* null, i8* undef, i8* null)
br label %func.next
-func.call2:
+func.call2: ; preds = %entry
call void @"internal/task.start"(i32 ptrtoint (void (i32, i8*, i8*)* @"main$2" to i32), i8* null, i8* undef, i8* null)
br label %func.next
-func.next:
+func.next: ; preds = %func.call2, %func.call1
ret void
-func.default:
+func.default: ; preds = %entry
unreachable
}
diff --git a/transform/testdata/interface.out.ll b/transform/testdata/interface.out.ll
index 25f47d0c8..9ae8b4886 100644
--- a/transform/testdata/interface.out.ll
+++ b/transform/testdata/interface.out.ll
@@ -36,32 +36,32 @@ define void @printInterface(i32 %typecode, i8* %value) {
%typeassert.ok1 = call i1 @"Unmatched$typeassert"(i32 %typecode)
br i1 %typeassert.ok1, label %typeswitch.Unmatched, label %typeswitch.notUnmatched
-typeswitch.Unmatched:
+typeswitch.Unmatched: ; preds = %0
%unmatched = ptrtoint i8* %value to i32
call void @runtime.printptr(i32 %unmatched)
call void @runtime.printnl()
ret void
-typeswitch.notUnmatched:
+typeswitch.notUnmatched: ; preds = %0
%typeassert.ok = call i1 @"Doubler$typeassert"(i32 %typecode)
br i1 %typeassert.ok, label %typeswitch.Doubler, label %typeswitch.notDoubler
-typeswitch.Doubler:
+typeswitch.Doubler: ; preds = %typeswitch.notUnmatched
%doubler.result = call i32 @"(Number).Double$invoke"(i8* %value, i8* null)
call void @runtime.printint32(i32 %doubler.result)
ret void
-typeswitch.notDoubler:
+typeswitch.notDoubler: ; preds = %typeswitch.notUnmatched
%typeassert.ok2 = icmp eq i32 16, %typecode
br i1 %typeassert.ok2, label %typeswitch.byte, label %typeswitch.notByte
-typeswitch.byte:
+typeswitch.byte: ; preds = %typeswitch.notDoubler
%byte = ptrtoint i8* %value to i8
call void @runtime.printuint8(i8 %byte)
call void @runtime.printnl()
ret void
-typeswitch.notByte:
+typeswitch.notByte: ; preds = %typeswitch.notDoubler
ret void
}
@@ -82,10 +82,10 @@ entry:
i32 68, label %then
]
-then:
+then: ; preds = %entry
ret i1 true
-else:
+else: ; preds = %entry
ret i1 false
}
@@ -94,9 +94,9 @@ entry:
switch i32 %actualType, label %else [
]
-then:
+then: ; No predecessors!
ret i1 true
-else:
+else: ; preds = %entry
ret i1 false
}
diff --git a/transform/transform_test.go b/transform/transform_test.go
index d0f125692..3905293c0 100644
--- a/transform/transform_test.go
+++ b/transform/transform_test.go
@@ -3,6 +3,7 @@ package transform
// This file defines some helper functions for testing transforms.
import (
+ "flag"
"io/ioutil"
"os"
"strings"
@@ -11,6 +12,8 @@ import (
"tinygo.org/x/go-llvm"
)
+var update = flag.Bool("update", false, "update transform package tests")
+
// testTransform runs a transformation pass on an input file (pathPrefix+".ll")
// and checks whether it matches the expected output (pathPrefix+".out.ll"). The
// output is compared with a fuzzy match that ignores some irrelevant lines such
@@ -31,18 +34,28 @@ func testTransform(t *testing.T, pathPrefix string, transform func(mod llvm.Modu
// Perform the transform.
transform(mod)
- // Read the expected output IR.
- out, err := ioutil.ReadFile(pathPrefix + ".out.ll")
- if err != nil {
- t.Fatalf("could not read output file %s: %v", pathPrefix+".out.ll", err)
- }
-
- // See whether the transform output matches with the expected output IR.
- expected := string(out)
+ // Get the output from the test and filter some irrelevant lines.
actual := mod.String()
- if !fuzzyEqualIR(expected, actual) {
- t.Logf("output does not match expected output:\n%s", actual)
- t.Fail()
+ actual = actual[strings.Index(actual, "\ntarget datalayout = ")+1:]
+
+ if *update {
+ err := ioutil.WriteFile(pathPrefix+".out.ll", []byte(actual), 0666)
+ if err != nil {
+ t.Error("failed to write out new output:", err)
+ }
+ } else {
+ // Read the expected output IR.
+ out, err := ioutil.ReadFile(pathPrefix + ".out.ll")
+ if err != nil {
+ t.Fatalf("could not read output file %s: %v", pathPrefix+".out.ll", err)
+ }
+
+ // See whether the transform output matches with the expected output IR.
+ expected := string(out)
+ if !fuzzyEqualIR(expected, actual) {
+ t.Logf("output does not match expected output:\n%s", actual)
+ t.Fail()
+ }
}
}