From 3cc975813da24e5a19f065916959bba2aa14849c Mon Sep 17 00:00:00 2001 From: xushiwei Date: Fri, 24 May 2024 22:47:45 +0800 Subject: [PATCH] abiType: support pointer --- cl/_testgo/strucintf/in.go | 9 +-- cl/_testgo/strucintf/out.ll | 122 +++++++++++++++++------------- cl/_testrt/any/in.go | 6 +- cl/_testrt/any/out.ll | 68 +++++++++++++++-- internal/runtime/llgo_autogen.lla | Bin 5677 -> 5763 bytes internal/runtime/z_type.go | 13 ++++ ssa/interface.go | 87 +++++++++++---------- ssa/stmt_builder.go | 2 +- 8 files changed, 201 insertions(+), 106 deletions(-) diff --git a/cl/_testgo/strucintf/in.go b/cl/_testgo/strucintf/in.go index 1af4b02d..ae87c15d 100644 --- a/cl/_testgo/strucintf/in.go +++ b/cl/_testgo/strucintf/in.go @@ -1,20 +1,19 @@ package main import ( - "github.com/goplus/llgo/c" "github.com/goplus/llgo/cl/internal/foo" ) func main() { bar := foo.Bar() if x, ok := bar.(struct{ V int }); ok { - c.Printf(c.Str("%d\n"), x.V) + println(x.V) } else { - c.Printf(c.Str("Bar: not ok\n")) + println("Bar: not ok") } if x, ok := foo.F().(struct{ v int }); ok { - c.Printf(c.Str("%d\n"), x.v) + println(x.v) } else { - c.Printf(c.Str("F: not ok\n")) + println("F: not ok") } } diff --git a/cl/_testgo/strucintf/out.ll b/cl/_testgo/strucintf/out.ll index 57492612..6872eb18 100644 --- a/cl/_testgo/strucintf/out.ll +++ b/cl/_testgo/strucintf/out.ll @@ -11,17 +11,15 @@ source_filename = "main" @__llgo_argc = global ptr null @__llgo_argv = global ptr null @"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk" = linkonce global ptr null -@0 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88" = global ptr null -@1 = private unnamed_addr constant [13 x i8] c"Bar: not ok\0A\00", align 1 -@2 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 -@3 = private unnamed_addr constant [11 x i8] c"F: not ok\0A\00", align 1 -@4 = private unnamed_addr constant [2 x i8] c"V\00", align 1 -@5 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 -@6 = private unnamed_addr constant [5 x i8] c"main\00", align 1 -@7 = private unnamed_addr constant [2 x i8] c"v\00", align 1 -@8 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 -@9 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@0 = private unnamed_addr constant [12 x i8] c"Bar: not ok\00", align 1 +@1 = private unnamed_addr constant [10 x i8] c"F: not ok\00", align 1 +@2 = private unnamed_addr constant [2 x i8] c"V\00", align 1 +@3 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@4 = private unnamed_addr constant [5 x i8] c"main\00", align 1 +@5 = private unnamed_addr constant [2 x i8] c"v\00", align 1 +@6 = private unnamed_addr constant [1 x i8] zeroinitializer, align 1 +@7 = private unnamed_addr constant [5 x i8] c"main\00", align 1 define void @main.init() { _llgo_0: @@ -77,55 +75,71 @@ _llgo_0: _llgo_1: ; preds = %_llgo_0 %24 = getelementptr inbounds { i64 }, ptr %4, i32 0, i32 0 %25 = load i64, ptr %24, align 4 - %26 = call i32 (ptr, ...) @printf(ptr @0, i64 %25) + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %25) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) br label %_llgo_2 _llgo_2: ; preds = %_llgo_3, %_llgo_1 - %27 = alloca { i64 }, align 8 - %28 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %27, i64 8) - %29 = call %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llgo/cl/internal/foo.F"() - %30 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %29, 0 - %31 = load ptr, ptr @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88", align 8 - %32 = icmp eq ptr %30, %31 - %33 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %29, 1 - %34 = ptrtoint ptr %33 to i64 - %35 = alloca { i64 }, align 8 - %36 = getelementptr inbounds { i64 }, ptr %35, i32 0, i32 0 - store i64 %34, ptr %36, align 4 - %37 = load { i64 }, ptr %35, align 4 - %38 = alloca { { i64 }, i1 }, align 8 - %39 = getelementptr inbounds { { i64 }, i1 }, ptr %38, i32 0, i32 0 - store { i64 } %37, ptr %39, align 4 - %40 = getelementptr inbounds { { i64 }, i1 }, ptr %38, i32 0, i32 1 - store i1 true, ptr %40, align 1 - %41 = load { { i64 }, i1 }, ptr %38, align 4 - %42 = alloca { { i64 }, i1 }, align 8 - %43 = getelementptr inbounds { { i64 }, i1 }, ptr %42, i32 0, i32 0 - store { i64 } zeroinitializer, ptr %43, align 4 - %44 = getelementptr inbounds { { i64 }, i1 }, ptr %42, i32 0, i32 1 - store i1 false, ptr %44, align 1 - %45 = load { { i64 }, i1 }, ptr %42, align 4 - %46 = select i1 %32, { { i64 }, i1 } %41, { { i64 }, i1 } %45 - %47 = extractvalue { { i64 }, i1 } %46, 0 - store { i64 } %47, ptr %28, align 4 - %48 = extractvalue { { i64 }, i1 } %46, 1 - br i1 %48, label %_llgo_4, label %_llgo_6 + %26 = alloca { i64 }, align 8 + %27 = call ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr %26, i64 8) + %28 = call %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llgo/cl/internal/foo.F"() + %29 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %28, 0 + %30 = load ptr, ptr @"main.struct$MYpsoM99ZwFY087IpUOkIw1zjBA_sgFXVodmn1m-G88", align 8 + %31 = icmp eq ptr %29, %30 + %32 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %28, 1 + %33 = ptrtoint ptr %32 to i64 + %34 = alloca { i64 }, align 8 + %35 = getelementptr inbounds { i64 }, ptr %34, i32 0, i32 0 + store i64 %33, ptr %35, align 4 + %36 = load { i64 }, ptr %34, align 4 + %37 = alloca { { i64 }, i1 }, align 8 + %38 = getelementptr inbounds { { i64 }, i1 }, ptr %37, i32 0, i32 0 + store { i64 } %36, ptr %38, align 4 + %39 = getelementptr inbounds { { i64 }, i1 }, ptr %37, i32 0, i32 1 + store i1 true, ptr %39, align 1 + %40 = load { { i64 }, i1 }, ptr %37, align 4 + %41 = alloca { { i64 }, i1 }, align 8 + %42 = getelementptr inbounds { { i64 }, i1 }, ptr %41, i32 0, i32 0 + store { i64 } zeroinitializer, ptr %42, align 4 + %43 = getelementptr inbounds { { i64 }, i1 }, ptr %41, i32 0, i32 1 + store i1 false, ptr %43, align 1 + %44 = load { { i64 }, i1 }, ptr %41, align 4 + %45 = select i1 %31, { { i64 }, i1 } %40, { { i64 }, i1 } %44 + %46 = extractvalue { { i64 }, i1 } %45, 0 + store { i64 } %46, ptr %27, align 4 + %47 = extractvalue { { i64 }, i1 } %45, 1 + br i1 %47, label %_llgo_4, label %_llgo_6 _llgo_3: ; preds = %_llgo_0 - %49 = call i32 (ptr, ...) @printf(ptr @1) + %48 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %49 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %48, i32 0, i32 0 + store ptr @0, ptr %49, align 8 + %50 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %48, i32 0, i32 1 + store i64 11, ptr %50, align 4 + %51 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %48, align 8 + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %51) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) br label %_llgo_2 _llgo_4: ; preds = %_llgo_2 - %50 = getelementptr inbounds { i64 }, ptr %28, i32 0, i32 0 - %51 = load i64, ptr %50, align 4 - %52 = call i32 (ptr, ...) @printf(ptr @2, i64 %51) + %52 = getelementptr inbounds { i64 }, ptr %27, i32 0, i32 0 + %53 = load i64, ptr %52, align 4 + call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %53) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) br label %_llgo_5 _llgo_5: ; preds = %_llgo_6, %_llgo_4 ret i32 0 _llgo_6: ; preds = %_llgo_2 - %53 = call i32 (ptr, ...) @printf(ptr @3) + %54 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %55 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %54, i32 0, i32 0 + store ptr @1, ptr %55, align 8 + %56 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %54, i32 0, i32 1 + store i64 9, ptr %56, align 4 + %57 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %54, align 8 + call void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String" %57) + call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10) br label %_llgo_5 } @@ -137,10 +151,14 @@ declare %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llg declare ptr @"github.com/goplus/llgo/internal/runtime.Zeroinit"(ptr, i64) -declare i32 @printf(ptr, ...) +declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64) + +declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8) declare %"github.com/goplus/llgo/internal/runtime.eface" @"github.com/goplus/llgo/cl/internal/foo.F"() +declare void @"github.com/goplus/llgo/internal/runtime.PrintString"(%"github.com/goplus/llgo/internal/runtime.String") + define void @"main.init$abi"() { _llgo_0: %0 = load ptr, ptr @"_llgo_struct$K-dZ9QotZfVPz2a0YdRa9vmZUuDXPTqZOlMShKEDJtk", align 8 @@ -150,21 +168,21 @@ _llgo_0: _llgo_1: ; preds = %_llgo_0 %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 @4, ptr %3, align 8 + store ptr @2, ptr %3, align 8 %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %2, i32 0, i32 1 store i64 1, ptr %4, align 4 %5 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %2, align 8 %6 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) %7 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 0 - store ptr @5, ptr %8, align 8 + store ptr @3, ptr %8, align 8 %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1 store i64 0, ptr %9, align 4 %10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8 %11 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %5, ptr %6, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %10, i1 true, i1 false) %12 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %13 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %12, i32 0, i32 0 - store ptr @6, ptr %13, align 8 + store ptr @4, ptr %13, align 8 %14 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %12, i32 0, i32 1 store i64 4, ptr %14, align 4 %15 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %12, align 8 @@ -186,21 +204,21 @@ _llgo_1: ; preds = %_llgo_0 _llgo_2: ; preds = %_llgo_1, %_llgo_0 %24 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %25 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 0 - store ptr @7, ptr %25, align 8 + store ptr @5, ptr %25, align 8 %26 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %24, i32 0, i32 1 store i64 1, ptr %26, align 4 %27 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %24, align 8 %28 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) %29 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %30 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %29, i32 0, i32 0 - store ptr @8, ptr %30, align 8 + store ptr @6, ptr %30, align 8 %31 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %29, i32 0, i32 1 store i64 0, ptr %31, align 4 %32 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %29, align 8 %33 = call %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/llgo/internal/runtime.StructField"(%"github.com/goplus/llgo/internal/runtime.String" %27, ptr %28, i64 0, %"github.com/goplus/llgo/internal/runtime.String" %32, i1 false, i1 false) %34 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %35 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %34, i32 0, i32 0 - store ptr @9, ptr %35, align 8 + store ptr @7, ptr %35, align 8 %36 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %34, i32 0, i32 1 store i64 4, ptr %36, align 4 %37 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %34, align 8 diff --git a/cl/_testrt/any/in.go b/cl/_testrt/any/in.go index 4d9300ed..4120c735 100644 --- a/cl/_testrt/any/in.go +++ b/cl/_testrt/any/in.go @@ -4,10 +4,14 @@ import ( "github.com/goplus/llgo/internal/runtime/c" ) +func hi(a any) *c.Char { + return a.(*c.Char) +} + func incVal(a any) int { return a.(int) + 1 } func main() { - c.Printf(c.Str("Hello %d\n"), incVal(100)) + c.Printf(c.Str("%s %d\n"), hi(c.Str("Hello")), incVal(100)) } diff --git a/cl/_testrt/any/out.ll b/cl/_testrt/any/out.ll index 207fc6d3..612c682e 100644 --- a/cl/_testrt/any/out.ll +++ b/cl/_testrt/any/out.ll @@ -5,10 +5,35 @@ source_filename = "main" %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } @"main.init$guard" = global ptr null +@"*_llgo_int8" = linkonce global ptr null @0 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 +@1 = private unnamed_addr constant [22 x i8] c"type assertion failed\00", align 1 @__llgo_argc = global ptr null @__llgo_argv = global ptr null -@1 = private unnamed_addr constant [10 x i8] c"Hello %d\0A\00", align 1 +@2 = private unnamed_addr constant [7 x i8] c"%s %d\0A\00", align 1 +@3 = private unnamed_addr constant [6 x i8] c"Hello\00", align 1 + +define ptr @main.hi(%"github.com/goplus/llgo/internal/runtime.eface" %0) { +_llgo_0: + %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %0, 0 + %2 = load ptr, ptr @"*_llgo_int8", align 8 + %3 = icmp eq ptr %1, %2 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %0, 1 + ret ptr %4 + +_llgo_2: ; preds = %_llgo_0 + %5 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 + %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 0 + store ptr @0, ptr %6, align 8 + %7 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %5, i32 0, i32 1 + store i64 21, ptr %7, align 4 + %8 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %5, align 8 + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.String" %8) + unreachable +} define i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.eface" %0) { _llgo_0: @@ -26,7 +51,7 @@ _llgo_1: ; preds = %_llgo_0 _llgo_2: ; preds = %_llgo_0 %7 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %8 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 0 - store ptr @0, ptr %8, align 8 + store ptr @1, ptr %8, align 8 %9 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %7, i32 0, i32 1 store i64 21, ptr %9, align 4 %10 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %7, align 8 @@ -41,6 +66,7 @@ _llgo_0: _llgo_1: ; preds = %_llgo_0 store i1 true, ptr @"main.init$guard", align 1 + call void @"main.init$abi"() br label %_llgo_2 _llgo_2: ; preds = %_llgo_1, %_llgo_0 @@ -53,22 +79,48 @@ _llgo_0: store ptr %1, ptr @__llgo_argv, align 8 call void @"github.com/goplus/llgo/internal/runtime.init"() call void @main.init() - %2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) + %2 = load ptr, ptr @"*_llgo_int8", align 8 %3 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %4 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, i32 0, i32 0 store ptr %2, ptr %4, align 8 %5 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, i32 0, i32 1 - store ptr inttoptr (i64 100 to ptr), ptr %5, align 8 + store ptr @3, ptr %5, align 8 %6 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %3, align 8 - %7 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.eface" %6) - %8 = call i32 (ptr, ...) @printf(ptr @1, i64 %7) + %7 = call ptr @main.hi(%"github.com/goplus/llgo/internal/runtime.eface" %6) + %8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) + %9 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 + %10 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, i32 0, i32 0 + store ptr %8, ptr %10, align 8 + %11 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, i32 0, i32 1 + store ptr inttoptr (i64 100 to ptr), ptr %11, align 8 + %12 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %9, align 8 + %13 = call i64 @main.incVal(%"github.com/goplus/llgo/internal/runtime.eface" %12) + %14 = call i32 (ptr, ...) @printf(ptr @2, ptr %7, i64 %13) ret i32 0 } -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 ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) + declare void @"github.com/goplus/llgo/internal/runtime.init"() declare i32 @printf(ptr, ...) + +define void @"main.init$abi"() { +_llgo_0: + %0 = load ptr, ptr @"*_llgo_int8", align 8 + %1 = icmp eq ptr %0, null + br i1 %1, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %2 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3) + %3 = call ptr @"github.com/goplus/llgo/internal/runtime.Pointer"(ptr %2) + store ptr %3, ptr @"*_llgo_int8", align 8 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + ret void +} + +declare ptr @"github.com/goplus/llgo/internal/runtime.Pointer"(ptr) diff --git a/internal/runtime/llgo_autogen.lla b/internal/runtime/llgo_autogen.lla index a5c5b75bc81fc925cd674fcc15e25965e95a45cc..08e35c39a24245609732392d3e53dee61d59638b 100644 GIT binary patch literal 5763 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