diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 89563e2a..7f8ad77c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -14,7 +14,7 @@ jobs: test: strategy: matrix: - os: [macos-latest, macos-12, macos-13, ubuntu-latest] + os: [macos-latest, ubuntu-latest] llvm: [17] runs-on: ${{ matrix.os }} steps: @@ -63,6 +63,7 @@ jobs: run: go install ./... - name: LLGO tests + if: matrix.os != 'ubuntu-latest' run: | echo "Test result on ${{ matrix.os }} with LLVM ${{ matrix.llvm }}" > result.md LLGOROOT=$PWD bash .github/workflows/test_llgo.sh diff --git a/cl/_testdata/vargs/out.ll b/cl/_testdata/vargs/out.ll index 668d704b..e3e2b1e3 100644 --- a/cl/_testdata/vargs/out.ll +++ b/cl/_testdata/vargs/out.ll @@ -133,7 +133,7 @@ _llgo_5: ; preds = %_llgo_2 %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %21, i32 0, i32 1 store ptr %20, ptr %23, align 8 %24 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %21, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %24) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %24) unreachable } @@ -172,6 +172,6 @@ declare void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") declare i32 @printf(ptr, ...) diff --git a/cl/_testgo/defer1/out.ll b/cl/_testgo/defer1/out.ll index b54874d9..1c8a0e79 100644 --- a/cl/_testgo/defer1/out.ll +++ b/cl/_testgo/defer1/out.ll @@ -1,186 +1 @@ -; ModuleID = 'main' -source_filename = "main" - -%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } -%"github.com/goplus/llgo/internal/runtime.Defer" = type { i64, ptr, i64 } - -@"main.init$guard" = global ptr null -@__llgo_argc = global ptr null -@__llgo_argv = global ptr null -@__llgo_defer = linkonce global ptr null -@0 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@2 = private unnamed_addr constant [4 x i8] c"bye\00", align 1 -@3 = private unnamed_addr constant [6 x i8] c"world\00", align 1 -@4 = private unnamed_addr constant [3 x i8] c"hi\00", align 1 - -define i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %0) { -_llgo_0: - %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1 - %2 = icmp sgt i64 %1, 2 - ret i1 %2 -} - -define void @main.init() { -_llgo_0: - %0 = load i1, ptr @"main.init$guard", align 1 - br i1 %0, label %_llgo_2, label %_llgo_1 - -_llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"main.init$guard", align 1 - call void @"main.init$after"() - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -define i32 @main(i32 %0, ptr %1) { -_llgo_0: - store i32 %0, ptr @__llgo_argc, align 4 - store ptr %1, ptr @__llgo_argv, align 8 - call void @"github.com/goplus/llgo/internal/runtime.init"() - call void @main.init() - %2 = load ptr, ptr @__llgo_defer, align 8 - %3 = call ptr @pthread_getspecific(ptr %2) - %4 = alloca i8, i64 24, align 1 - %5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 0 - store i64 0, ptr %5, align 4 - %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 1 - store ptr %3, ptr %6, align 8 - %7 = call i32 @pthread_setspecific(ptr %2, ptr %4) - %8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 0 - %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, i32 0, i32 2 - %10 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %10, i32 0, i32 0 - store ptr @0, ptr %11, align 8 - %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %10, i32 0, i32 1 - store i64 5, ptr %12, align 4 - %13 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %10, align 8 - %14 = call i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %13) - br i1 %14, label %_llgo_2, label %_llgo_3 - -_llgo_1: ; No predecessors! - ret i32 0 - -_llgo_2: ; preds = %_llgo_0 - %15 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i32 0, i32 0 - store ptr @1, ptr %16, align 8 - %17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i32 0, i32 1 - store i64 5, ptr %17, align 4 - %18 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 - %19 = load i64, ptr %8, align 4 - %20 = or i64 %19, 1 - store i64 %20, ptr %8, align 4 - %21 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %21, i32 0, i32 0 - store ptr @2, ptr %22, align 8 - %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %21, i32 0, i32 1 - store i64 3, ptr %23, align 4 - %24 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %21, align 8 - %25 = load i64, ptr %8, align 4 - %26 = or i64 %25, 2 - store i64 %26, ptr %8, align 4 - store i64 0, ptr %9, align 4 - br label %_llgo_4 - -_llgo_3: ; preds = %_llgo_0 - %27 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %28 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %27, i32 0, i32 0 - store ptr @3, ptr %28, align 8 - %29 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %27, i32 0, i32 1 - store i64 5, ptr %29, align 4 - %30 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %27, align 8 - %31 = load i64, ptr %8, align 4 - %32 = or i64 %31, 4 - store i64 %32, ptr %8, align 4 - store i64 1, ptr %9, align 4 - br label %_llgo_4 - -_llgo_4: ; preds = %_llgo_3, %_llgo_2 - %33 = load i64, ptr %8, align 4 - %34 = and i64 %33, 4 - %35 = icmp ne i64 %34, 0 - br i1 %35, label %_llgo_7, label %_llgo_8 - -_llgo_5: ; preds = %_llgo_12 - ret i32 0 - -_llgo_6: ; preds = %_llgo_12 - ret i32 0 - -_llgo_7: ; preds = %_llgo_4 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %30) - call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) - br label %_llgo_8 - -_llgo_8: ; preds = %_llgo_7, %_llgo_4 - %36 = and i64 %33, 2 - %37 = icmp ne i64 %36, 0 - br i1 %37, label %_llgo_9, label %_llgo_10 - -_llgo_9: ; preds = %_llgo_8 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %24) - call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) - br label %_llgo_10 - -_llgo_10: ; preds = %_llgo_9, %_llgo_8 - %38 = and i64 %33, 1 - %39 = icmp ne i64 %38, 0 - br i1 %39, label %_llgo_11, label %_llgo_12 - -_llgo_11: ; preds = %_llgo_10 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %18) - call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) - br label %_llgo_12 - -_llgo_12: ; preds = %_llgo_11, %_llgo_10 - call void @"main.main$1"() - %40 = load %"github.com/goplus/llgo/internal/runtime.Defer", ptr %4, align 8 - %41 = extractvalue %"github.com/goplus/llgo/internal/runtime.Defer" %40, 2 - %42 = call i32 @pthread_setspecific(ptr %2, i64 %41) - %43 = load i64, ptr %9, align 4 - switch i64 %43, label %_llgo_5 [ - i64 1, label %_llgo_6 - ] -} - -declare void @"github.com/goplus/llgo/internal/runtime.init"() - -define void @"main.main$1"() { -_llgo_0: - %0 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %1 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 0 - store ptr @4, ptr %1, align 8 - %2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %0, i32 0, i32 1 - store i64 2, ptr %2, align 4 - %3 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %0, align 8 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %3) - call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) - ret void -} - -declare ptr @pthread_getspecific(i32) - -declare i32 @pthread_setspecific(i32, ptr) - -declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") - -declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) - -define void @"main.init$after"() { -_llgo_0: - %0 = load ptr, ptr @__llgo_defer, align 8 - %1 = icmp eq ptr %0, null - br i1 %1, label %_llgo_1, label %_llgo_2 - -_llgo_1: ; preds = %_llgo_0 - %2 = call i32 @pthread_key_create(ptr @__llgo_defer, ptr null) - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -declare i32 @pthread_key_create(ptr, ptr) +; \ No newline at end of file diff --git a/cl/_testgo/defer2/out.ll b/cl/_testgo/defer2/out.ll index b76604bb..1c8a0e79 100644 --- a/cl/_testgo/defer2/out.ll +++ b/cl/_testgo/defer2/out.ll @@ -1,171 +1 @@ -; ModuleID = 'main' -source_filename = "main" - -%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } -%"github.com/goplus/llgo/internal/runtime.Defer" = type { i64, ptr, i64 } - -@"main.init$guard" = global ptr null -@__llgo_argc = global ptr null -@__llgo_argv = global ptr null -@0 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@1 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@__llgo_defer = linkonce global ptr null -@2 = private unnamed_addr constant [4 x i8] c"bye\00", align 1 -@3 = private unnamed_addr constant [6 x i8] c"world\00", align 1 - -define i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %0) { -_llgo_0: - %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1 - %2 = icmp sgt i64 %1, 2 - ret i1 %2 -} - -define void @main.init() { -_llgo_0: - %0 = load i1, ptr @"main.init$guard", align 1 - br i1 %0, label %_llgo_2, label %_llgo_1 - -_llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"main.init$guard", align 1 - call void @"main.init$after"() - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -define i32 @main(i32 %0, ptr %1) { -_llgo_0: - store i32 %0, ptr @__llgo_argc, align 4 - store ptr %1, ptr @__llgo_argv, align 8 - call void @"github.com/goplus/llgo/internal/runtime.init"() - call void @main.init() - %2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0 - store ptr @0, ptr %3, align 8 - %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 - store i64 5, ptr %4, align 4 - %5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8 - %6 = call i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %5) - %7 = load ptr, ptr @__llgo_defer, align 8 - %8 = call ptr @pthread_getspecific(ptr %7) - %9 = alloca i8, i64 24, align 1 - %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 0 - store i64 0, ptr %10, align 4 - %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 1 - store ptr %8, ptr %11, align 8 - %12 = call i32 @pthread_setspecific(ptr %7, ptr %9) - %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 0 - %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 2 - br i1 %6, label %_llgo_1, label %_llgo_2 - -_llgo_1: ; preds = %_llgo_0 - %15 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i32 0, i32 0 - store ptr @1, ptr %16, align 8 - %17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i32 0, i32 1 - store i64 5, ptr %17, align 4 - %18 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 - %19 = load i64, ptr %13, align 4 - %20 = or i64 %19, 1 - store i64 %20, ptr %13, align 4 - %21 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %22 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %21, i32 0, i32 0 - store ptr @2, ptr %22, align 8 - %23 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %21, i32 0, i32 1 - store i64 3, ptr %23, align 4 - %24 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %21, align 8 - %25 = load i64, ptr %13, align 4 - %26 = or i64 %25, 2 - store i64 %26, ptr %13, align 4 - store i64 0, ptr %14, align 4 - br label %_llgo_4 - -_llgo_2: ; preds = %_llgo_0 - %27 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %28 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %27, i32 0, i32 0 - store ptr @3, ptr %28, align 8 - %29 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %27, i32 0, i32 1 - store i64 5, ptr %29, align 4 - %30 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %27, align 8 - %31 = load i64, ptr %13, align 4 - %32 = or i64 %31, 4 - store i64 %32, ptr %13, align 4 - store i64 1, ptr %14, align 4 - br label %_llgo_4 - -_llgo_3: ; No predecessors! - ret i32 0 - -_llgo_4: ; preds = %_llgo_2, %_llgo_1 - %33 = load i64, ptr %13, align 4 - %34 = and i64 %33, 4 - %35 = icmp ne i64 %34, 0 - br i1 %35, label %_llgo_7, label %_llgo_8 - -_llgo_5: ; preds = %_llgo_12 - ret i32 0 - -_llgo_6: ; preds = %_llgo_12 - ret i32 0 - -_llgo_7: ; preds = %_llgo_4 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %30) - call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) - br label %_llgo_8 - -_llgo_8: ; preds = %_llgo_7, %_llgo_4 - %36 = and i64 %33, 2 - %37 = icmp ne i64 %36, 0 - br i1 %37, label %_llgo_9, label %_llgo_10 - -_llgo_9: ; preds = %_llgo_8 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %24) - call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) - br label %_llgo_10 - -_llgo_10: ; preds = %_llgo_9, %_llgo_8 - %38 = and i64 %33, 1 - %39 = icmp ne i64 %38, 0 - br i1 %39, label %_llgo_11, label %_llgo_12 - -_llgo_11: ; preds = %_llgo_10 - call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %18) - call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) - br label %_llgo_12 - -_llgo_12: ; preds = %_llgo_11, %_llgo_10 - %40 = load %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, align 8 - %41 = extractvalue %"github.com/goplus/llgo/internal/runtime.Defer" %40, 2 - %42 = call i32 @pthread_setspecific(ptr %7, i64 %41) - %43 = load i64, ptr %14, align 4 - switch i64 %43, label %_llgo_5 [ - i64 1, label %_llgo_6 - ] -} - -declare void @"github.com/goplus/llgo/internal/runtime.init"() - -declare ptr @pthread_getspecific(i32) - -declare i32 @pthread_setspecific(i32, ptr) - -declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") - -declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) - -define void @"main.init$after"() { -_llgo_0: - %0 = load ptr, ptr @__llgo_defer, align 8 - %1 = icmp eq ptr %0, null - br i1 %1, label %_llgo_1, label %_llgo_2 - -_llgo_1: ; preds = %_llgo_0 - %2 = call i32 @pthread_key_create(ptr @__llgo_defer, ptr null) - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -declare i32 @pthread_key_create(ptr, ptr) +; \ No newline at end of file diff --git a/cl/_testgo/defer3/in.go b/cl/_testgo/defer3/in.go new file mode 100644 index 00000000..7398dedd --- /dev/null +++ b/cl/_testgo/defer3/in.go @@ -0,0 +1,23 @@ +package main + +func f(s string) bool { + return len(s) > 2 +} + +func fail() { + defer println("bye") + panic("panic message") +} + +func main() { + defer func() { + println("hi") + }() + if s := "hello"; f(s) { + defer println(s) + } else { + defer println("world") + return + } + fail() +} diff --git a/cl/_testgo/defer3/out.ll b/cl/_testgo/defer3/out.ll new file mode 100644 index 00000000..1c8a0e79 --- /dev/null +++ b/cl/_testgo/defer3/out.ll @@ -0,0 +1 @@ +; \ No newline at end of file diff --git a/cl/_testgo/ifaceconv/out.ll b/cl/_testgo/ifaceconv/out.ll index f65a294c..4f4d7d43 100644 --- a/cl/_testgo/ifaceconv/out.ll +++ b/cl/_testgo/ifaceconv/out.ll @@ -140,7 +140,7 @@ _llgo_1: ; preds = %_llgo_25 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_25 @@ -165,7 +165,7 @@ _llgo_3: ; preds = %_llgo_28 %25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %23, i32 0, i32 1 store ptr %22, ptr %25, align 8 %26 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %23, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %26) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %26) unreachable _llgo_4: ; preds = %_llgo_28 @@ -190,7 +190,7 @@ _llgo_5: ; preds = %_llgo_31 %38 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %36, i32 0, i32 1 store ptr %35, ptr %38, align 8 %39 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %36, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %39) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %39) unreachable _llgo_6: ; preds = %_llgo_31 @@ -249,7 +249,7 @@ _llgo_7: ; preds = %_llgo_34 %76 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, i32 0, i32 1 store ptr %73, ptr %76, align 8 %77 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %77) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %77) unreachable _llgo_8: ; preds = %_llgo_34 @@ -274,7 +274,7 @@ _llgo_9: ; preds = %_llgo_37 %89 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %87, i32 0, i32 1 store ptr %86, ptr %89, align 8 %90 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %87, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %90) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %90) unreachable _llgo_10: ; preds = %_llgo_37 @@ -299,7 +299,7 @@ _llgo_11: ; preds = %_llgo_40 %102 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %100, i32 0, i32 1 store ptr %99, ptr %102, align 8 %103 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %100, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %103) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %103) unreachable _llgo_12: ; preds = %_llgo_40 @@ -335,7 +335,7 @@ _llgo_13: ; preds = %_llgo_43 %123 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %121, i32 0, i32 1 store ptr %120, ptr %123, align 8 %124 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %121, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %124) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %124) unreachable _llgo_14: ; preds = %_llgo_43 @@ -360,7 +360,7 @@ _llgo_15: ; preds = %_llgo_46 %136 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %134, i32 0, i32 1 store ptr %133, ptr %136, align 8 %137 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %134, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %137) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %137) unreachable _llgo_16: ; preds = %_llgo_46 @@ -385,7 +385,7 @@ _llgo_17: ; preds = %_llgo_49 %149 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %147, i32 0, i32 1 store ptr %146, ptr %149, align 8 %150 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %147, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %150) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %150) unreachable _llgo_18: ; preds = %_llgo_49 @@ -427,7 +427,7 @@ _llgo_19: ; preds = %_llgo_18 %174 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %172, i32 0, i32 1 store ptr %171, ptr %174, align 8 %175 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %172, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %175) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %175) unreachable _llgo_20: ; preds = %_llgo_18 @@ -465,7 +465,7 @@ _llgo_21: ; preds = %_llgo_20 %196 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %194, i32 0, i32 1 store ptr %193, ptr %196, align 8 %197 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %194, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %197) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %197) unreachable _llgo_22: ; preds = %_llgo_20 @@ -1282,7 +1282,7 @@ declare i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr, ptr) declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") declare ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface") diff --git a/cl/_testgo/ifaceprom/out.ll b/cl/_testgo/ifaceprom/out.ll index 6a3441d1..a4ca2d09 100644 --- a/cl/_testgo/ifaceprom/out.ll +++ b/cl/_testgo/ifaceprom/out.ll @@ -231,7 +231,7 @@ _llgo_1: ; preds = %_llgo_0 %34 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %32, i32 0, i32 1 store ptr %31, ptr %34, align 8 %35 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %32, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %35) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %35) unreachable _llgo_2: ; preds = %_llgo_0 @@ -266,7 +266,7 @@ _llgo_3: ; preds = %_llgo_2 %57 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %55, i32 0, i32 1 store ptr %54, ptr %57, align 8 %58 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %55, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %58) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %58) unreachable _llgo_4: ; preds = %_llgo_2 @@ -290,7 +290,7 @@ _llgo_5: ; preds = %_llgo_17 %71 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %69, i32 0, i32 1 store ptr %68, ptr %71, align 8 %72 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %69, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %72) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %72) unreachable _llgo_6: ; preds = %_llgo_17 @@ -314,7 +314,7 @@ _llgo_7: ; preds = %_llgo_19 %85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, i32 0, i32 1 store ptr %82, ptr %85, align 8 %86 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %83, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %86) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %86) unreachable _llgo_8: ; preds = %_llgo_19 @@ -353,7 +353,7 @@ _llgo_9: ; preds = %_llgo_8 %110 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %108, i32 0, i32 1 store ptr %107, ptr %110, align 8 %111 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %108, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %111) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %111) unreachable _llgo_10: ; preds = %_llgo_8 @@ -392,7 +392,7 @@ _llgo_11: ; preds = %_llgo_10 %135 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %133, i32 0, i32 1 store ptr %132, ptr %135, align 8 %136 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %133, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %136) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %136) unreachable _llgo_12: ; preds = %_llgo_10 @@ -413,7 +413,7 @@ _llgo_13: ; preds = %_llgo_21 %146 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %144, i32 0, i32 1 store ptr %143, ptr %146, align 8 %147 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %144, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %147) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %147) unreachable _llgo_14: ; preds = %_llgo_21 @@ -434,7 +434,7 @@ _llgo_15: ; preds = %_llgo_23 %157 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %155, i32 0, i32 1 store ptr %154, ptr %157, align 8 %158 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %155, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %158) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %158) unreachable _llgo_16: ; preds = %_llgo_23 @@ -489,7 +489,7 @@ _llgo_18: ; preds = %_llgo_4 %188 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %186, i32 0, i32 1 store ptr %185, ptr %188, align 8 %189 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %186, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %189) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %189) unreachable _llgo_19: ; preds = %_llgo_6 @@ -533,7 +533,7 @@ _llgo_20: ; preds = %_llgo_6 %215 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %213, i32 0, i32 1 store ptr %212, ptr %215, align 8 %216 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %213, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %216) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %216) unreachable _llgo_21: ; preds = %_llgo_12 @@ -584,7 +584,7 @@ _llgo_22: ; preds = %_llgo_12 %247 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %245, i32 0, i32 1 store ptr %244, ptr %247, align 8 %248 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %245, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %248) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %248) unreachable _llgo_23: ; preds = %_llgo_14 @@ -635,7 +635,7 @@ _llgo_24: ; preds = %_llgo_14 %279 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %277, i32 0, i32 1 store ptr %276, ptr %279, align 8 %280 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %277, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %280) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %280) unreachable } @@ -997,7 +997,7 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Interface"(%"github.com/go declare ptr @"github.com/goplus/llgo/internal/runtime.NewItab"(ptr, ptr) -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") declare ptr @"github.com/goplus/llgo/internal/runtime.IfaceType"(%"github.com/goplus/llgo/internal/runtime.iface") diff --git a/cl/_testgo/invoke/out.ll b/cl/_testgo/invoke/out.ll index 8568b521..aca1f8ab 100644 --- a/cl/_testgo/invoke/out.ll +++ b/cl/_testgo/invoke/out.ll @@ -395,7 +395,7 @@ _llgo_2: ; preds = %_llgo_0 %130 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %128, i32 0, i32 1 store ptr %127, ptr %130, align 8 %131 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %128, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %131) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %131) unreachable _llgo_3: ; preds = %_llgo_1 @@ -427,7 +427,7 @@ _llgo_4: ; preds = %_llgo_1 %148 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %146, i32 0, i32 1 store ptr %145, ptr %148, align 8 %149 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %146, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %149) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %149) unreachable _llgo_5: ; preds = %_llgo_3 @@ -460,7 +460,7 @@ _llgo_6: ; preds = %_llgo_3 %165 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %163, i32 0, i32 1 store ptr %162, ptr %165, align 8 %166 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %163, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %166) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %166) unreachable } @@ -1185,4 +1185,4 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/ declare i1 @"github.com/goplus/llgo/internal/runtime.Implements"(ptr, ptr) -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") diff --git a/cl/_testgo/reader/out.ll b/cl/_testgo/reader/out.ll index 85e80b2c..4d129ddd 100644 --- a/cl/_testgo/reader/out.ll +++ b/cl/_testgo/reader/out.ll @@ -647,7 +647,7 @@ _llgo_2: ; preds = %_llgo_0 %37 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %35, i32 0, i32 1 store ptr %34, ptr %37, align 8 %38 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %35, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %38) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %38) unreachable } @@ -1098,7 +1098,7 @@ _llgo_3: ; preds = %_llgo_2 %28 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %26, i32 0, i32 1 store ptr %25, ptr %28, align 8 %29 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %26, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %29) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %29) unreachable _llgo_4: ; preds = %_llgo_2 @@ -2739,7 +2739,7 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) declare void @"github.com/goplus/llgo/internal/runtime.PrintIface"(%"github.com/goplus/llgo/internal/runtime.iface") -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64) diff --git a/cl/_testlibc/defer/in.go b/cl/_testlibc/defer/in.go index 8395a818..ab8362c3 100644 --- a/cl/_testlibc/defer/in.go +++ b/cl/_testlibc/defer/in.go @@ -1,12 +1,13 @@ package main -import "github.com/goplus/llgo/c" +import "github.com/goplus/llgo/internal/runtime/c" func f(s string) bool { return len(s) > 2 } func main() { + c.GoDeferData() if s := "hello"; f(s) { defer c.Printf(c.Str("%s\n"), c.AllocaCStr(s)) } else { diff --git a/cl/_testlibc/defer/out.ll b/cl/_testlibc/defer/out.ll index 07de7a11..1c8a0e79 100644 --- a/cl/_testlibc/defer/out.ll +++ b/cl/_testlibc/defer/out.ll @@ -1,148 +1 @@ -; ModuleID = 'main' -source_filename = "main" - -%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } -%"github.com/goplus/llgo/internal/runtime.Defer" = type { i64, ptr, i64 } - -@"main.init$guard" = global ptr null -@__llgo_argc = global ptr null -@__llgo_argv = global ptr null -@0 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@1 = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1 -@2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 -@__llgo_defer = linkonce global ptr null -@3 = private unnamed_addr constant [7 x i8] c"world\0A\00", align 1 -@4 = private unnamed_addr constant [5 x i8] c"bye\0A\00", align 1 - -define i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %0) { -_llgo_0: - %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %0, 1 - %2 = icmp sgt i64 %1, 2 - ret i1 %2 -} - -define void @main.init() { -_llgo_0: - %0 = load i1, ptr @"main.init$guard", align 1 - br i1 %0, label %_llgo_2, label %_llgo_1 - -_llgo_1: ; preds = %_llgo_0 - store i1 true, ptr @"main.init$guard", align 1 - call void @"main.init$after"() - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -define i32 @main(i32 %0, ptr %1) { -_llgo_0: - store i32 %0, ptr @__llgo_argc, align 4 - store ptr %1, ptr @__llgo_argv, align 8 - call void @"github.com/goplus/llgo/internal/runtime.init"() - call void @main.init() - %2 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %3 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 0 - store ptr @0, ptr %3, align 8 - %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 - store i64 5, ptr %4, align 4 - %5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8 - %6 = call i1 @main.f(%"github.com/goplus/llgo/internal/runtime.String" %5) - %7 = load ptr, ptr @__llgo_defer, align 8 - %8 = call ptr @pthread_getspecific(ptr %7) - %9 = alloca i8, i64 24, align 1 - %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 0 - store i64 0, ptr %10, align 4 - %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 1 - store ptr %8, ptr %11, align 8 - %12 = call i32 @pthread_setspecific(ptr %7, ptr %9) - %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 0 - %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, i32 0, i32 2 - br i1 %6, label %_llgo_1, label %_llgo_3 - -_llgo_1: ; preds = %_llgo_0 - %15 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 - %16 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i32 0, i32 0 - store ptr @2, ptr %16, align 8 - %17 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %15, i32 0, i32 1 - store i64 5, ptr %17, align 4 - %18 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 - %19 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %18, 1 - %20 = add i64 %19, 1 - %21 = alloca i8, i64 %20, align 1 - %22 = call ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr %21, %"github.com/goplus/llgo/internal/runtime.String" %18) - %23 = load i64, ptr %13, align 4 - %24 = or i64 %23, 1 - store i64 %24, ptr %13, align 4 - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_3, %_llgo_1 - store i64 0, ptr %14, align 4 - br label %_llgo_5 - -_llgo_3: ; preds = %_llgo_0 - %25 = load i64, ptr %13, align 4 - %26 = or i64 %25, 2 - store i64 %26, ptr %13, align 4 - br label %_llgo_2 - -_llgo_4: ; No predecessors! - ret i32 0 - -_llgo_5: ; preds = %_llgo_2 - %27 = load i64, ptr %13, align 4 - %28 = call i32 (ptr, ...) @printf(ptr @4) - %29 = and i64 %27, 2 - %30 = icmp ne i64 %29, 0 - br i1 %30, label %_llgo_7, label %_llgo_8 - -_llgo_6: ; preds = %_llgo_10 - ret i32 0 - -_llgo_7: ; preds = %_llgo_5 - %31 = call i32 (ptr, ...) @printf(ptr @3) - br label %_llgo_8 - -_llgo_8: ; preds = %_llgo_7, %_llgo_5 - %32 = and i64 %27, 1 - %33 = icmp ne i64 %32, 0 - br i1 %33, label %_llgo_9, label %_llgo_10 - -_llgo_9: ; preds = %_llgo_8 - %34 = call i32 (ptr, ...) @printf(ptr @1, ptr %22) - br label %_llgo_10 - -_llgo_10: ; preds = %_llgo_9, %_llgo_8 - %35 = load %"github.com/goplus/llgo/internal/runtime.Defer", ptr %9, align 8 - %36 = extractvalue %"github.com/goplus/llgo/internal/runtime.Defer" %35, 2 - %37 = call i32 @pthread_setspecific(ptr %7, i64 %36) - %38 = load i64, ptr %14, align 4 - switch i64 %38, label %_llgo_6 [ - ] -} - -declare void @"github.com/goplus/llgo/internal/runtime.init"() - -declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String") - -declare i32 @printf(ptr, ...) - -declare ptr @pthread_getspecific(i32) - -declare i32 @pthread_setspecific(i32, ptr) - -define void @"main.init$after"() { -_llgo_0: - %0 = load ptr, ptr @__llgo_defer, align 8 - %1 = icmp eq ptr %0, null - br i1 %1, label %_llgo_1, label %_llgo_2 - -_llgo_1: ; preds = %_llgo_0 - %2 = call i32 @pthread_key_create(ptr @__llgo_defer, ptr null) - br label %_llgo_2 - -_llgo_2: ; preds = %_llgo_1, %_llgo_0 - ret void -} - -declare i32 @pthread_key_create(ptr, ptr) +; \ No newline at end of file diff --git a/cl/_testrt/any/out.ll b/cl/_testrt/any/out.ll index b55c4afc..cb94c6b1 100644 --- a/cl/_testrt/any/out.ll +++ b/cl/_testrt/any/out.ll @@ -44,7 +44,7 @@ _llgo_2: ; preds = %_llgo_0 %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, i32 0, i32 1 store ptr %10, ptr %13, align 8 %14 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %11, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %14) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %14) unreachable } @@ -77,7 +77,7 @@ _llgo_2: ; preds = %_llgo_0 %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, i32 0, i32 1 store ptr %12, ptr %15, align 8 %16 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %13, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %16) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %16) unreachable } @@ -177,7 +177,7 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.PointerTo"(ptr) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") declare void @"github.com/goplus/llgo/internal/runtime.init"() diff --git a/cl/_testrt/cast/out.ll b/cl/_testrt/cast/out.ll index 28af826b..0d0cd205 100644 --- a/cl/_testrt/cast/out.ll +++ b/cl/_testrt/cast/out.ll @@ -44,7 +44,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -73,7 +73,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -102,7 +102,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -131,7 +131,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -160,7 +160,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -189,7 +189,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -218,7 +218,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -247,7 +247,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -276,7 +276,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -305,7 +305,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -334,7 +334,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -363,7 +363,7 @@ _llgo_1: ; preds = %_llgo_0 %12 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, i32 0, i32 1 store ptr %9, ptr %12, align 8 %13 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %10, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %13) unreachable _llgo_2: ; preds = %_llgo_0 @@ -387,7 +387,7 @@ _llgo_3: ; preds = %_llgo_2 %24 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %22, i32 0, i32 1 store ptr %21, ptr %24, align 8 %25 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %22, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %25) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %25) unreachable _llgo_4: ; preds = %_llgo_2 @@ -488,6 +488,6 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") declare void @"github.com/goplus/llgo/internal/runtime.init"() diff --git a/cl/_testrt/panic/out.ll b/cl/_testrt/panic/out.ll index ce254403..4cbb32ee 100644 --- a/cl/_testrt/panic/out.ll +++ b/cl/_testrt/panic/out.ll @@ -45,7 +45,7 @@ _llgo_0: %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, i32 0, i32 1 store ptr %7, ptr %10, align 8 %11 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %8, align 8 - call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface" %11) + call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %11) unreachable } @@ -70,4 +70,4 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) -declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.eface") +declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface") diff --git a/cl/builtin_test.go b/cl/builtin_test.go index 13debf7c..abdbb8e4 100644 --- a/cl/builtin_test.go +++ b/cl/builtin_test.go @@ -27,14 +27,14 @@ import ( "golang.org/x/tools/go/ssa" ) -func TestIsVargs(t *testing.T) { - if isVargs(nil, ssaAlloc(&ssa.Return{})) { +func TestIsAllocVargs(t *testing.T) { + if isAllocVargs(nil, ssaAlloc(&ssa.Return{})) { t.Fatal("isVargs?") } - if isVargs(nil, ssaAlloc(ssaSlice(&ssa.Go{}))) { + if isAllocVargs(nil, ssaAlloc(ssaSlice(&ssa.Go{}))) { t.Fatal("isVargs?") } - if isVargs(nil, ssaAlloc(ssaSlice(&ssa.Return{}))) { + if isAllocVargs(nil, ssaAlloc(ssaSlice(&ssa.Return{}))) { t.Fatal("isVargs?") } } diff --git a/cl/compile.go b/cl/compile.go index b67d6b17..970589ce 100644 --- a/cl/compile.go +++ b/cl/compile.go @@ -201,7 +201,7 @@ func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) { } g := pkg.NewVar(name, typ, llssa.Background(vtype)) if vtype == goVar { - g.Init(p.prog.Null(g.Type)) + g.Init(p.prog.Nil(g.Type)) } } @@ -338,6 +338,8 @@ func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObj ftype = llgoSigsetjmp case "siglongjmp": ftype = llgoSiglongjmp + case "deferData": + ftype = llgoDeferData case "unreachable": ftype = llgoUnreachable default: @@ -378,8 +380,8 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do fn := p.fn argc := pkg.NewVar("__llgo_argc", types.NewPointer(types.Typ[types.Int32]), llssa.InC) argv := pkg.NewVar("__llgo_argv", types.NewPointer(argvTy), llssa.InC) - argc.Init(prog.Null(argc.Type)) - argv.Init(prog.Null(argv.Type)) + argc.Init(prog.Nil(argc.Type)) + argv.Init(prog.Nil(argv.Type)) b.Store(argc.Expr, fn.Param(0)) b.Store(argv.Expr, fn.Param(1)) callRuntimeInit(b, pkg) @@ -395,7 +397,7 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do modName := pysymPrefix + modPath modPtr := pkg.PyNewModVar(modName, true).Expr mod := b.Load(modPtr) - cond := b.BinOp(token.NEQ, mod, prog.Null(mod.Type)) + cond := b.BinOp(token.NEQ, mod, prog.Nil(mod.Type)) newBlk := p.fn.MakeBlock() b.If(cond, jumpTo, newBlk) b.SetBlockEx(newBlk, llssa.AtEnd, false) @@ -441,7 +443,7 @@ func (p *context) isVArgs(v ssa.Value) (ret []llssa.Expr, ok bool) { func (p *context) checkVArgs(v *ssa.Alloc, t *types.Pointer) bool { if v.Comment == "varargs" { // this maybe a varargs allocation if arr, ok := t.Elem().(*types.Array); ok { - if isAny(arr.Elem()) && isVargs(p, v) { + if isAny(arr.Elem()) && isAllocVargs(p, v) { p.vargs[v] = make([]llssa.Expr, arr.Len()) return true } @@ -450,7 +452,7 @@ func (p *context) checkVArgs(v *ssa.Alloc, t *types.Pointer) bool { return false } -func isVargs(ctx *context, v *ssa.Alloc) bool { +func isAllocVargs(ctx *context, v *ssa.Alloc) bool { refs := *v.Referrers() n := len(refs) lastref := refs[n-1] @@ -652,6 +654,8 @@ func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon p.siglongjmp(b, args) case llgoSigjmpbuf: // func sigjmpbuf() ret = b.AllocaSigjmpBuf() + case llgoDeferData: // func deferData() *Defer + ret = b.DeferData() case llgoUnreachable: // func unreachable() b.Unreachable() default: diff --git a/cl/import.go b/cl/import.go index 7cd23813..473226c0 100644 --- a/cl/import.go +++ b/cl/import.go @@ -312,6 +312,7 @@ const ( llgoSigjmpbuf = llgoInstrBase + 10 llgoSigsetjmp = llgoInstrBase + 11 llgoSiglongjmp = llgoInstrBase + 12 + llgoDeferData = llgoInstrBase + 13 ) func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) { diff --git a/internal/runtime/c/c.go b/internal/runtime/c/c.go index 63ace390..cea55d8b 100644 --- a/internal/runtime/c/c.go +++ b/internal/runtime/c/c.go @@ -42,15 +42,33 @@ func Alloca(size uintptr) Pointer //go:linkname AllocaCStr llgo.allocaCStr func AllocaCStr(s string) *Char +//go:linkname GoDeferData llgo.deferData +func GoDeferData() Pointer + //go:linkname Unreachable llgo.unreachable func Unreachable() +//go:linkname Exit C.exit +func Exit(Int) + +//go:linkname AllocaSigjmpBuf llgo.sigjmpbuf +func AllocaSigjmpBuf() Pointer + +//go:linkname Sigsetjmp llgo.sigsetjmp +func Sigsetjmp(jb Pointer, savemask Int) Int + +//go:linkname Siglongjmp llgo.siglongjmp +func Siglongjmp(jb Pointer, retval Int) + //go:linkname Rand C.rand func Rand() Int //go:linkname Malloc C.malloc func Malloc(size uintptr) Pointer +//go:linkname Free C.free +func Free(ptr Pointer) + //go:linkname Memcpy C.memcpy func Memcpy(dst, src Pointer, n uintptr) Pointer diff --git a/internal/runtime/z_rt.go b/internal/runtime/z_rt.go index 4d178efe..063bb25a 100644 --- a/internal/runtime/z_rt.go +++ b/internal/runtime/z_rt.go @@ -19,6 +19,7 @@ package runtime import ( "unsafe" + "github.com/goplus/llgo/c/pthread" "github.com/goplus/llgo/internal/abi" "github.com/goplus/llgo/internal/runtime/c" ) @@ -27,18 +28,43 @@ import ( // Defer presents defer statements in a function. type Defer struct { + Addr unsafe.Pointer // sigjmpbuf Bits uintptr Link *Defer - Rund int // index of RunDefers + Rund unsafe.Pointer // block address after RunDefers +} + +// Panic panics with a value. +func Panic(v Eface) { + ptr := c.Malloc(unsafe.Sizeof(v)) + *(*Eface)(ptr) = v + excepKey.Set(ptr) + + Rethrow((*Defer)(c.GoDeferData())) +} + +// Rethrow rethrows a panic. +func Rethrow(link *Defer) { + if link == nil { + ptr := excepKey.Get() + TracePanic(*(*Eface)(ptr)) + c.Free(ptr) + c.Exit(2) + } else { + c.Siglongjmp(link.Addr, 1) + } +} + +var ( + excepKey pthread.Key +) + +func init() { + excepKey.Create(nil) } // ----------------------------------------------------------------------------- -// Zeroinit initializes memory to zero. -func Zeroinit(p unsafe.Pointer, size uintptr) unsafe.Pointer { - return c.Memset(p, 0, size) -} - // TracePanic prints panic message. func TracePanic(v Eface) { kind := v._type.Kind() @@ -55,3 +81,10 @@ func stringTracef(fp c.FilePtr, format *c.Char, s String) { } // ----------------------------------------------------------------------------- + +// Zeroinit initializes memory to zero. +func Zeroinit(p unsafe.Pointer, size uintptr) unsafe.Pointer { + return c.Memset(p, 0, size) +} + +// ----------------------------------------------------------------------------- diff --git a/ssa/abitype.go b/ssa/abitype.go index 1184b385..36c14489 100644 --- a/ssa/abitype.go +++ b/ssa/abitype.go @@ -305,7 +305,7 @@ func (p Package) abiTypeInit(g Global, t types.Type, pub bool) { var eq Expr var blks []BasicBlock if pub { - eq = b.BinOp(token.EQL, b.Load(expr), b.Prog.Null(expr.Type)) + eq = b.BinOp(token.EQL, b.Load(expr), b.Prog.Nil(expr.Type)) blks = b.Func.MakeBlocks(2) b.If(eq, blks[0], blks[1]) b.SetBlockEx(blks[0], AtEnd, false) @@ -345,7 +345,7 @@ func (b Builder) abiType(t types.Type) Expr { if g == nil { prog := b.Prog g = pkg.doNewVar(name, prog.AbiTypePtrPtr()) - g.Init(prog.Null(g.Type)) + g.Init(prog.Nil(g.Type)) if pub { g.impl.SetLinkage(llvm.LinkOnceAnyLinkage) } diff --git a/ssa/cl_test.go b/ssa/cl_test.go index 70f7f455..be5cde02 100644 --- a/ssa/cl_test.go +++ b/ssa/cl_test.go @@ -52,6 +52,7 @@ func TestMakeInterface(t *testing.T) { b := fn.MakeBody(1) b.MakeInterface(prog.Any(), prog.IntVal(100, prog.Int64())) b.MakeInterface(prog.Any(), prog.FloatVal(100, prog.Float64())) + b.DeferData() b.Return() } diff --git a/ssa/eh.go b/ssa/eh.go index 684274f1..e4ade559 100644 --- a/ssa/eh.go +++ b/ssa/eh.go @@ -22,7 +22,6 @@ import "C" import ( "go/token" "go/types" - "log" "unsafe" "github.com/goplus/llvm" @@ -68,8 +67,9 @@ func (b Builder) Sigsetjmp(jb, savemask Expr) Expr { } func (b Builder) Siglongjmp(jb, retval Expr) { - fn := b.Pkg.cFunc("siglongjmp", b.Prog.tySiglongjmp()) + fn := b.Pkg.cFunc("siglongjmp", b.Prog.tySiglongjmp()) // TODO(xsw): mark as noreturn b.Call(fn, jb, retval) + // b.Unreachable() } // ----------------------------------------------------------------------------- @@ -78,75 +78,118 @@ const ( deferKey = "__llgo_defer" ) -func (p Function) deferInitBuilder() Builder { - b := p.NewBuilder() - b.SetBlockEx(p.blks[0], BeforeLast, true) - return b +func (p Function) deferInitBuilder() (b Builder, next BasicBlock) { + b = p.NewBuilder() + next = b.setBlockMoveLast(p.blks[0]) + return } type aDefer struct { - nextBit int // next defer bit - key Expr // pthread TLS key - data Expr // pointer to runtime.Defer - bitsPtr Expr // pointer to defer bits - rundPtr Expr // pointer to RunDefers index - procBlk BasicBlock // deferProc block - stmts []func(bits Expr) + nextBit int // next defer bit + key Expr // pthread TLS key + data Expr // pointer to runtime.Defer + bitsPtr Expr // pointer to defer bits + rundPtr Expr // pointer to RunDefers index + procBlk BasicBlock // deferProc block runsNext []BasicBlock // next blocks of RunDefers + stmts []func(bits Expr) } -func (p Package) deferInit() { - keyVar := p.VarOf(deferKey) +func (p Package) keyInit(name string) { + keyVar := p.VarOf(name) if keyVar == nil { return } prog := p.Prog - keyNil := prog.Null(prog.DeferPtrPtr()) + keyNil := prog.Nil(prog.CIntPtr()) keyVar.Init(keyNil) keyVar.impl.SetLinkage(llvm.LinkOnceAnyLinkage) b := p.afterBuilder() - eq := b.BinOp(token.EQL, b.Load(keyVar.Expr), keyNil) + eq := b.BinOp(token.EQL, b.Load(keyVar.Expr), prog.IntVal(0, prog.CInt())) b.IfThen(eq, func() { - b.pthreadKeyCreate(keyVar.Expr, prog.Null(prog.VoidPtr())) + b.pthreadKeyCreate(keyVar.Expr, prog.Nil(prog.VoidPtr())) }) } -func (p Package) newDeferKey() Global { - return p.NewVarEx(deferKey, p.Prog.DeferPtrPtr()) +func (p Package) newKey(name string) Global { + return p.NewVarEx(name, p.Prog.CIntPtr()) } func (b Builder) deferKey() Expr { - return b.Load(b.Pkg.newDeferKey().Expr) + return b.Load(b.Pkg.newKey(deferKey).Expr) } +const ( + // 0: addr sigjmpbuf + // 1: bits uintptr + // 2: link *Defer + // 3: rund voidptr + deferSigjmpbuf = iota + deferBits + deferLink + deferRund +) + func (b Builder) getDefer(kind DoAction) *aDefer { self := b.Func if self.defer_ == nil { - // 0: bits uintptr - // 1: link *Defer - // 2: rund int + // TODO(xsw): check if in pkg.init + var next, rundBlk BasicBlock if kind != DeferAlways { - b = self.deferInitBuilder() + b, next = self.deferInitBuilder() } prog := b.Prog key := b.deferKey() zero := prog.Val(uintptr(0)) - link := b.pthreadGetspecific(key) - ptr := b.aggregateAlloca(prog.Defer(), zero.impl, link.impl) + link := Expr{b.pthreadGetspecific(key).impl, prog.DeferPtr()} + jb := b.AllocaSigjmpBuf() + ptr := b.aggregateAlloca(prog.Defer(), jb.impl, zero.impl, link.impl) deferData := Expr{ptr, prog.DeferPtr()} b.pthreadSetspecific(key, deferData) + blks := self.MakeBlocks(2) + procBlk, rethrowBlk := blks[0], blks[1] + bitsPtr := b.FieldAddr(deferData, deferBits) + rundPtr := b.FieldAddr(deferData, deferRund) self.defer_ = &aDefer{ - key: key, - data: deferData, - bitsPtr: b.FieldAddr(deferData, 0), - rundPtr: b.FieldAddr(deferData, 2), - procBlk: self.MakeBlock(), + key: key, + data: deferData, + bitsPtr: bitsPtr, + rundPtr: rundPtr, + procBlk: procBlk, + runsNext: []BasicBlock{rethrowBlk}, + } + czero := prog.IntVal(0, prog.CInt()) + retval := b.Sigsetjmp(jb, czero) + if kind != DeferAlways { + rundBlk = self.MakeBlock() + } else { + blks = self.MakeBlocks(2) + next, rundBlk = blks[0], blks[1] + } + b.If(b.BinOp(token.EQL, retval, czero), next, rundBlk) + b.SetBlockEx(rundBlk, AtEnd, false) // exec runDefers and rethrow + b.Store(rundPtr, rethrowBlk.Addr()) + b.Jump(procBlk) + + b.SetBlockEx(rethrowBlk, AtEnd, false) // rethrow + b.Call(b.Pkg.rtFunc("Rethrow"), link) + b.Unreachable() // TODO: func supports noreturn attribute + + if kind == DeferAlways { + b.SetBlockEx(next, AtEnd, false) + b.blk.last = next.last } } return self.defer_ } +// DeferData returns the defer data (*runtime.Defer). +func (b Builder) DeferData() Expr { + key := b.deferKey() + return Expr{b.pthreadGetspecific(key).impl, b.Prog.DeferPtr()} +} + // Defer emits a defer instruction. func (b Builder) Defer(kind DoAction, fn Expr, args ...Expr) { if debugInstr { @@ -184,14 +227,13 @@ func (b Builder) Defer(kind DoAction, fn Expr, args ...Expr) { // RunDefers emits instructions to run deferred instructions. func (b Builder) RunDefers() { - prog := b.Prog self := b.getDefer(DeferInCond) - b.Store(self.rundPtr, prog.Val(len(self.runsNext))) - b.Jump(self.procBlk) - blk := b.Func.MakeBlock() self.runsNext = append(self.runsNext, blk) + b.Store(self.rundPtr, blk.Addr()) + b.Jump(self.procBlk) + b.SetBlockEx(blk, AtEnd, false) b.blk.last = blk.last } @@ -202,8 +244,7 @@ func (p Function) endDefer(b Builder) { return } nexts := self.runsNext - n := len(nexts) - if n == 0 { + if len(nexts) == 0 { return } b.SetBlockEx(self.procBlk, AtEnd, true) @@ -213,19 +254,18 @@ func (p Function) endDefer(b Builder) { stmts[i](bits) } - link := b.getField(b.Load(self.data), 2) + link := b.getField(b.Load(self.data), deferLink) b.pthreadSetspecific(self.key, link) - - prog := b.Prog - rund := b.Load(self.rundPtr) - sw := b.impl.CreateSwitch(rund.impl, nexts[0].first, n-1) - for i := 1; i < n; i++ { - sw.AddCase(prog.Val(i).impl, nexts[i].first) - } + b.IndirectJump(b.Load(self.rundPtr), nexts) } // ----------------------------------------------------------------------------- +// Unreachable emits an unreachable instruction. +func (b Builder) Unreachable() { + b.impl.CreateUnreachable() +} + /* // Recover emits a recover instruction. func (b Builder) Recover() (v Expr) { @@ -233,22 +273,14 @@ func (b Builder) Recover() (v Expr) { log.Println("Recover") } prog := b.Prog - return prog.Zero(prog.Eface()) + return prog.Zero(prog.Any()) } */ // Panic emits a panic instruction. func (b Builder) Panic(v Expr) { - if debugInstr { - log.Printf("Panic %v\n", v.impl) - } - b.Call(b.Pkg.rtFunc("TracePanic"), v) - b.impl.CreateUnreachable() -} - -// Unreachable emits an unreachable instruction. -func (b Builder) Unreachable() { - b.impl.CreateUnreachable() + b.Call(b.Pkg.rtFunc("Panic"), v) + b.Unreachable() // TODO: func supports noreturn attribute } // ----------------------------------------------------------------------------- diff --git a/ssa/expr.go b/ssa/expr.go index 9b200c70..e72283c0 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -83,6 +83,7 @@ func pyVarExpr(mod Expr, name string) Expr { // ----------------------------------------------------------------------------- +// Zero returns a zero constant expression. func (p Program) Zero(t Type) Expr { var ret llvm.Value switch u := t.raw.Type.Underlying().(type) { @@ -127,16 +128,11 @@ func (p Program) Zero(t Type) Expr { return Expr{ret, t} } -// Null returns a null constant expression. -func (p Program) Null(t Type) Expr { +// Nil returns a null constant expression. t should be a pointer type. +func (p Program) Nil(t Type) Expr { return Expr{llvm.ConstNull(t.ll), t} } -// PyNull returns a null *PyObject constant expression. -func (p Program) PyNull() Expr { - return p.Null(p.PyObjectPtr()) -} - // BoolVal returns a boolean constant expression. func (p Program) BoolVal(v bool) Expr { t := p.Bool() @@ -180,7 +176,7 @@ func (p Program) Val(v interface{}) Expr { func (b Builder) Const(v constant.Value, typ Type) Expr { prog := b.Prog if v == nil { - return prog.Null(typ) + return prog.Nil(typ) } raw := typ.raw.Type switch t := raw.Underlying().(type) { diff --git a/ssa/goroutine.go b/ssa/goroutine.go index 389ae8df..d2bf3787 100644 --- a/ssa/goroutine.go +++ b/ssa/goroutine.go @@ -86,7 +86,7 @@ func (b Builder) Go(fn Expr, args ...Expr) { data := Expr{b.aggregateMalloc(t, flds...), voidPtr} size := prog.SizeOf(voidPtr) pthd := b.Alloca(prog.IntVal(uint64(size), prog.Uintptr())) - b.pthreadCreate(pthd, prog.Null(voidPtr), pkg.routine(t, len(args)), data) + b.pthreadCreate(pthd, prog.Nil(voidPtr), pkg.routine(t, len(args)), data) } func (p Package) routineName() string { @@ -107,7 +107,7 @@ func (p Package) routine(t Type, n int) Expr { } b.Call(fn, args...) b.free(param) - b.Return(prog.Null(prog.VoidPtr())) + b.Return(prog.Nil(prog.VoidPtr())) return routine.Expr } diff --git a/ssa/memory.go b/ssa/memory.go index 94cfc7f3..d63df457 100644 --- a/ssa/memory.go +++ b/ssa/memory.go @@ -107,6 +107,17 @@ func aggregateInit(b llvm.Builder, ptr llvm.Value, tll llvm.Type, flds ...llvm.V } } +/* +func (b Builder) dupMalloc(v Expr) Expr { + prog := b.Prog + n := prog.SizeOf(v.Type) + tptr := prog.Pointer(v.Type) + ptr := b.malloc(prog.Val(uintptr(n))).impl + b.Store(Expr{ptr, tptr}, v) + return Expr{ptr, tptr} +} +*/ + // ----------------------------------------------------------------------------- // The Alloc instruction reserves space for a variable of the given type, diff --git a/ssa/package.go b/ssa/package.go index 24171164..253e8195 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -131,14 +131,16 @@ type aProgram struct { rtSliceTy llvm.Type rtMapTy llvm.Type - anyTy Type - voidTy Type - voidPtr Type - voidPPtr Type - boolTy Type - cstrTy Type - cintTy Type - //cintPtr Type + anyTy Type + //anyPtr Type + //anyPPtr Type + voidTy Type + voidPtr Type + voidPPtr Type + boolTy Type + cstrTy Type + cintTy Type + cintPtr Type stringTy Type uintptrTy Type intTy Type @@ -158,7 +160,6 @@ type aProgram struct { abiTyPPtr Type deferTy Type deferPtr Type - deferPPtr Type pyImpTy *types.Signature pyNewList *types.Signature @@ -328,14 +329,6 @@ func (p Program) DeferPtr() Type { return p.deferPtr } -// DeferPtrPtr returns **runtime.Defer type. -func (p Program) DeferPtrPtr() Type { - if p.deferPPtr == nil { - p.deferPPtr = p.Pointer(p.DeferPtr()) - } - return p.deferPPtr -} - // AbiTypePtr returns *abi.Type type. func (p Program) AbiTypePtr() Type { if p.abiTyPtr == nil { @@ -360,6 +353,7 @@ func (p Program) Void() Type { return p.voidTy } +// VoidPtr returns *void type. func (p Program) VoidPtr() Type { if p.voidPtr == nil { p.voidPtr = p.rawType(types.Typ[types.UnsafePointer]) @@ -367,6 +361,7 @@ func (p Program) VoidPtr() Type { return p.voidPtr } +// VoidPtrPtr returns **void type. func (p Program) VoidPtrPtr() Type { if p.voidPPtr == nil { p.voidPPtr = p.rawType(types.NewPointer(types.Typ[types.UnsafePointer])) @@ -382,6 +377,7 @@ func (p Program) Bool() Type { return p.boolTy } +// CStr returns *int8 type. func (p Program) CStr() Type { if p.cstrTy == nil { // *int8 p.cstrTy = p.rawType(types.NewPointer(types.Typ[types.Int8])) @@ -389,6 +385,7 @@ func (p Program) CStr() Type { return p.cstrTy } +// String returns string type. func (p Program) String() Type { if p.stringTy == nil { p.stringTy = p.rawType(types.Typ[types.String]) @@ -396,6 +393,24 @@ func (p Program) String() Type { return p.stringTy } +/* +// AnyPtrPtr returns **any type. +func (p Program) AnyPtrPtr() Type { + if p.anyPPtr == nil { + p.anyPPtr = p.Pointer(p.AnyPtr()) + } + return p.anyPPtr +} + +// AnyPtr returns *any type. +func (p Program) AnyPtr() Type { + if p.anyPtr == nil { + p.anyPtr = p.Pointer(p.Any()) + } + return p.anyPtr +} +*/ + // Any returns the any (empty interface) type. func (p Program) Any() Type { if p.anyTy == nil { @@ -410,6 +425,7 @@ func (p Program) Any() Type { func (p Program) Eface() Type { return p.Any() } +*/ // CIntPtr returns *c.Int type. func (p Program) CIntPtr() Type { @@ -418,7 +434,6 @@ func (p Program) CIntPtr() Type { } return p.cintPtr } -*/ // CInt returns c.Int type. func (p Program) CInt() Type { @@ -550,7 +565,7 @@ func (p Package) cFunc(fullName string, sig *types.Signature) Expr { func (p Package) closureStub(b Builder, t *types.Struct, v Expr) Expr { name := v.impl.Name() prog := b.Prog - nilVal := prog.Null(prog.VoidPtr()).impl + nilVal := prog.Nil(prog.VoidPtr()).impl if fn, ok := p.stubs[name]; ok { v = fn.Expr } else { @@ -605,7 +620,7 @@ func (p Package) afterBuilder() Builder { // AfterInit is called after the package is initialized (init all packages that depends on). func (p Package) AfterInit(b Builder, ret BasicBlock) { - p.deferInit() + p.keyInit(deferKey) doAfterb := p.afterb != nil doPyLoadModSyms := p.pyHasModSyms() if doAfterb || doPyLoadModSyms { diff --git a/ssa/python.go b/ssa/python.go index 1c8a7bf3..b9520bee 100644 --- a/ssa/python.go +++ b/ssa/python.go @@ -200,7 +200,8 @@ func (p Program) tyGetAttrString() *types.Signature { func (p Package) PyInit() bool { if fn := p.FuncOf("main"); fn != nil { b := fn.NewBuilder() - b.SetBlockEx(fn.Block(0), AtStart, false).callPyInit() + b.SetBlockEx(fn.Block(0), AtStart, false) + b.callPyInit() b.Dispose() return true } @@ -216,7 +217,7 @@ func (p Package) PyNewModVar(name string, doInit bool) Global { objPtr := prog.PyObjectPtrPtr().raw.Type g := p.NewVar(name, objPtr, InC) if doInit { - g.Init(prog.Null(g.Type)) + g.Init(prog.Nil(g.Type)) g.impl.SetLinkage(llvm.LinkOnceAnyLinkage) } p.pymods[name] = g @@ -245,7 +246,7 @@ func (b Builder) PyLoadModSyms(modName string, objs ...PyObjRef) Expr { args = append(args, o.Expr) } prog := b.Prog - args = append(args, prog.Null(prog.CStr())) + args = append(args, prog.Nil(prog.CStr())) return b.Call(fnLoad, args...) } @@ -272,7 +273,7 @@ func (b Builder) pyCall(fn Expr, args []Expr) (ret Expr) { callargs := make([]Expr, n+2) callargs[0] = fn copy(callargs[1:], args) - callargs[n+1] = prog.PyNull() + callargs[n+1] = prog.Nil(prog.PyObjectPtr()) ret = b.Call(call, callargs...) } return @@ -371,7 +372,7 @@ func (p Package) PyNewFunc(name string, sig *types.Signature, doInit bool) PyObj obj := p.NewVar(name, prog.PyObjectPtrPtr().RawType(), InC) if doInit { prog.NeedPyInit = true - obj.Init(prog.Null(obj.Type)) + obj.Init(prog.Nil(obj.Type)) obj.impl.SetLinkage(llvm.LinkOnceAnyLinkage) } ty := &aType{obj.ll, rawType{types.NewPointer(sig)}, vkPyFuncRef} diff --git a/ssa/stmt_builder.go b/ssa/stmt_builder.go index 40b58041..ca20e88d 100644 --- a/ssa/stmt_builder.go +++ b/ssa/stmt_builder.go @@ -48,6 +48,12 @@ func (p BasicBlock) Index() int { return p.idx } +// Addr returns the address of the basic block. +func (p BasicBlock) Addr() Expr { + fn := p.fn + return Expr{llvm.BlockAddress(fn.impl, p.first), fn.Prog.VoidPtr()} +} + // ----------------------------------------------------------------------------- type aBuilder struct { @@ -80,6 +86,21 @@ func (b Builder) SetBlock(blk BasicBlock) Builder { return b } +func (b Builder) setBlockMoveLast(blk BasicBlock) (next BasicBlock) { + blkLast := blk.last + last := blkLast.LastInstruction() + last.RemoveFromParentAsInstruction() + + impl := b.impl + + next = b.Func.MakeBlock() + impl.SetInsertPointAtEnd(next.last) + impl.Insert(last) + + impl.SetInsertPointAtEnd(blkLast) + return +} + type InsertPoint int const ( @@ -90,7 +111,7 @@ const ( ) // SetBlockEx sets blk as current basic block and pos as its insert point. -func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint, setBlk bool) Builder { +func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint, setBlk bool) { if b.Func != blk.fn { panic("mismatched function") } @@ -109,7 +130,6 @@ func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint, setBlk bool) Builde if setBlk { b.blk = blk } - return b } func instrAfterInit(blk llvm.BasicBlock) llvm.Value { @@ -188,6 +208,17 @@ func (b Builder) Jump(jmpb BasicBlock) { b.impl.CreateBr(jmpb.first) } +// IndirectJump emits an indirect jump instruction. +func (b Builder) IndirectJump(addr Expr, dests []BasicBlock) { + if debugInstr { + log.Printf("IndirectJump %v\n", addr.impl) + } + ibr := b.impl.CreateIndirectBr(addr.impl, len(dests)) + for _, dest := range dests { + ibr.AddDest(dest.first) + } +} + // If emits an if instruction. func (b Builder) If(cond Expr, thenb, elseb BasicBlock) { if b.Func != thenb.fn || b.Func != elseb.fn { @@ -210,6 +241,46 @@ func (b Builder) IfThen(cond Expr, then func()) { b.blk.last = blks[1].last } +// ----------------------------------------------------------------------------- +/* +type caseStmt struct { + v llvm.Value + blk llvm.BasicBlock +} + +type aSwitch struct { + v llvm.Value + def llvm.BasicBlock + cases []caseStmt +} + +// Switch represents a switch statement. +type Switch = *aSwitch + +// Case emits a case instruction. +func (p Switch) Case(v Expr, blk BasicBlock) { + if debugInstr { + log.Printf("Case %v, _llgo_%v\n", v.impl, blk.idx) + } + p.cases = append(p.cases, caseStmt{v.impl, blk.first}) +} + +// End ends a switch statement. +func (p Switch) End(b Builder) { + sw := b.impl.CreateSwitch(p.v, p.def, len(p.cases)) + for _, c := range p.cases { + sw.AddCase(c.v, c.blk) + } +} + +// Switch starts a switch statement. +func (b Builder) Switch(v Expr, defb BasicBlock) Switch { + if debugInstr { + log.Printf("Switch %v, _llgo_%v\n", v.impl, defb.idx) + } + return &aSwitch{v.impl, defb.first, nil} +} +*/ // ----------------------------------------------------------------------------- // Phi represents a phi node.