ssa: add builtin append

This commit is contained in:
visualfc
2024-05-15 10:29:06 +08:00
parent cebfe5c95b
commit 5d93565e16
12 changed files with 216 additions and 91 deletions

View File

@@ -51,7 +51,7 @@ _llgo_0:
define void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { define void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0: _llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
%2 = icmp eq i64 %1, 0 %2 = icmp eq i64 %1, 0
br i1 %2, label %_llgo_1, label %_llgo_2 br i1 %2, label %_llgo_1, label %_llgo_2
@@ -680,7 +680,7 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0
define void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { define void @main.println(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0: _llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_5, %_llgo_0 _llgo_1: ; preds = %_llgo_5, %_llgo_0
@@ -690,7 +690,7 @@ _llgo_1: ; preds = %_llgo_5, %_llgo_0
br i1 %4, label %_llgo_2, label %_llgo_3 br i1 %4, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3 %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8 %7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8
%8 = icmp ne i64 %3, 0 %8 = icmp ne i64 %3, 0
@@ -783,8 +783,6 @@ _llgo_0:
declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
@@ -802,5 +800,3 @@ declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llg
declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) declare { %"github.com/goplus/llgo/internal/runtime.String", i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2String"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")

View File

@@ -48,7 +48,7 @@ _llgo_0:
define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { define void @main.test(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0: _llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
@@ -58,7 +58,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %4, label %_llgo_2, label %_llgo_3 br i1 %4, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3 %6 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.iface", ptr %5, i64 %3
%7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8 %7 = load %"github.com/goplus/llgo/internal/runtime.iface", ptr %6, align 8
%8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2) %8 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
@@ -80,10 +80,6 @@ declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llg
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr) declare i64 @"github.com/goplus/llgo/internal/runtime.I2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)

View File

@@ -40,6 +40,12 @@ func main() {
string_len("hello"[1:]) string_len("hello"[1:])
string_len("hello"[1:2]) string_len("hello"[1:2])
string_len("hello"[5:]) string_len("hello"[5:])
s = append(s, 5, 6, 7, 8)
out(len(s))
data := []byte{'a', 'b', 'c'}
data = append(data, "def"...)
out(len(data))
} }
func string_len(s string) { func string_len(s string) {

View File

@@ -14,7 +14,8 @@ source_filename = "main"
@1 = 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 [6 x i8] c"hello\00", align 1 @2 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1 @3 = private unnamed_addr constant [6 x i8] c"hello\00", align 1
@4 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 @4 = private unnamed_addr constant [4 x i8] c"def\00", align 1
@5 = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
define void @main.init() { define void @main.init() {
_llgo_0: _llgo_0:
@@ -57,7 +58,7 @@ _llgo_0:
store i64 2, ptr %10, align 4 store i64 2, ptr %10, align 4
store i64 3, ptr %11, align 4 store i64 3, ptr %11, align 4
store i64 4, ptr %12, align 4 store i64 4, ptr %12, align 4
%13 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %13 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 1
call void @main.out(i64 %13) call void @main.out(i64 %13)
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32) %14 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%15 = getelementptr inbounds i64, ptr %14, i64 0 %15 = getelementptr inbounds i64, ptr %14, i64 0
@@ -69,64 +70,64 @@ _llgo_0:
%18 = getelementptr inbounds i64, ptr %14, i64 3 %18 = getelementptr inbounds i64, ptr %14, i64 3
store i64 4, ptr %18, align 4 store i64 4, ptr %18, align 4
%19 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %14, i64 8, i64 4, i64 0, i64 4, i64 4) %19 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %14, i64 8, i64 4, i64 0, i64 4, i64 4)
%20 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %19) %20 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %19, 1
call void @main.out(i64 %20) call void @main.out(i64 %20)
call void @main.out(i64 4) call void @main.out(i64 4)
call void @main.out(i64 4) call void @main.out(i64 4)
call void @main.out(i64 4) call void @main.out(i64 4)
%21 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %21 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
call void @main.out(i64 %21) call void @main.out(i64 %21)
call void @main.out(i64 4) call void @main.out(i64 4)
call void @main.out(i64 4) call void @main.out(i64 4)
%22 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %22 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %23 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%24 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %24 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %24, i64 8, i64 %22, i64 1, i64 %23, i64 %22) %25 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %24, i64 8, i64 %22, i64 1, i64 %23, i64 %22)
%26 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %25) %26 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %25, 1
call void @main.out(i64 %26) call void @main.out(i64 %26)
%27 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %27 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%28 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %28 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %29 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%30 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 %27, i64 1, i64 %28, i64 %27) %30 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %29, i64 8, i64 %27, i64 1, i64 %28, i64 %27)
%31 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %30) %31 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %30, 2
call void @main.out(i64 %31) call void @main.out(i64 %31)
%32 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %32 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%33 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %33 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %33, i64 8, i64 %32, i64 1, i64 2, i64 %32) %34 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %33, i64 8, i64 %32, i64 1, i64 2, i64 %32)
%35 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %34) %35 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %34, 1
call void @main.out(i64 %35) call void @main.out(i64 %35)
%36 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %36 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%37 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %37 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %37, i64 8, i64 %36, i64 1, i64 2, i64 %36) %38 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %37, i64 8, i64 %36, i64 1, i64 2, i64 %36)
%39 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %38) %39 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %38, 2
call void @main.out(i64 %39) call void @main.out(i64 %39)
%40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%41 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %41 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%42 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %41, i64 8, i64 %40, i64 1, i64 2, i64 2) %42 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %41, i64 8, i64 %40, i64 1, i64 2, i64 2)
%43 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %42) %43 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %42, 1
call void @main.out(i64 %43) call void @main.out(i64 %43)
%44 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 2
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %7) %45 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %7, 0
%46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %44, i64 1, i64 2, i64 2) %46 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %45, i64 8, i64 %44, i64 1, i64 2, i64 2)
%47 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %46) %47 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %46, 2
call void @main.out(i64 %47) call void @main.out(i64 %47)
%48 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4) %48 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
%49 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %48) %49 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %48, 1
call void @main.out(i64 %49) call void @main.out(i64 %49)
%50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4) %50 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 4, i64 4)
%51 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %50) %51 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %50, 2
call void @main.out(i64 %51) call void @main.out(i64 %51)
%52 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4) %52 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
%53 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %52) %53 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %52, 1
call void @main.out(i64 %53) call void @main.out(i64 %53)
%54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4) %54 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 4)
%55 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %54) %55 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %54, 2
call void @main.out(i64 %55) call void @main.out(i64 %55)
%56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2) %56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
%57 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %56) %57 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %56, 1
call void @main.out(i64 %57) call void @main.out(i64 %57)
%58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2) %58 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %8, i64 8, i64 4, i64 1, i64 2, i64 2)
%59 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %58) %59 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %58, 2
call void @main.out(i64 %59) call void @main.out(i64 %59)
%60 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5) %60 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %60) call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %60)
@@ -141,12 +142,41 @@ _llgo_0:
%67 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %66, 1 %67 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %66, 1
%68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %66, i64 5, i64 %67) %68 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String" %66, i64 5, i64 %67)
call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %68) call void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %68)
%69 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 32)
%70 = getelementptr inbounds i64, ptr %69, i64 0
store i64 5, ptr %70, align 4
%71 = getelementptr inbounds i64, ptr %69, i64 1
store i64 6, ptr %71, align 4
%72 = getelementptr inbounds i64, ptr %69, i64 2
store i64 7, ptr %72, align 4
%73 = getelementptr inbounds i64, ptr %69, i64 3
store i64 8, ptr %73, align 4
%74 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %69, i64 8, i64 4, i64 0, i64 4, i64 4)
%75 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 0
%76 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %74, 1
%77 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %7, ptr %75, i64 %76, i64 8)
%78 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %77, 1
call void @main.out(i64 %78)
%79 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 3)
%80 = getelementptr inbounds i8, ptr %79, i64 0
store i8 97, ptr %80, align 1
%81 = getelementptr inbounds i8, ptr %79, i64 1
store i8 98, ptr %81, align 1
%82 = getelementptr inbounds i8, ptr %79, i64 2
store i8 99, ptr %82, align 1
%83 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %79, i64 1, i64 3, i64 0, i64 3, i64 3)
%84 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 3)
%85 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %84, 0
%86 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %84, 1
%87 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice" %83, ptr %85, i64 %86, i64 1)
%88 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %87, 1
call void @main.out(i64 %88)
ret void ret void
} }
define void @main.out(i64 %0) { define void @main.out(i64 %0) {
_llgo_0: _llgo_0:
%1 = call i32 (ptr, ...) @printf(ptr @4, i64 %0) %1 = call i32 (ptr, ...) @printf(ptr @5, i64 %0)
ret void ret void
} }
@@ -163,14 +193,10 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewStringSlice"(%"github.com/goplus/llgo/internal/runtime.String", i64, i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.SliceAppend"(%"github.com/goplus/llgo/internal/runtime.Slice", ptr, i64, i64)
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)

View File

@@ -18,7 +18,7 @@ source_filename = "main"
define %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { define %"github.com/goplus/llgo/internal/runtime.String" @main.concat(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0: _llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
%2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 0) %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 0)
%3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 0 %3 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 0
%4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1 %4 = extractvalue %"github.com/goplus/llgo/internal/runtime.String" %2, 1
@@ -39,7 +39,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %13, label %_llgo_2, label %_llgo_3 br i1 %13, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%14 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %14 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %14, i64 %12 %15 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %14, i64 %12
%16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8 %16 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %15, align 8
%17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %16) %17 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String" %11, %"github.com/goplus/llgo/internal/runtime.String" %16)
@@ -100,10 +100,6 @@ _llgo_0:
ret void ret void
} }
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String") declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.StringCat"(%"github.com/goplus/llgo/internal/runtime.String", %"github.com/goplus/llgo/internal/runtime.String")
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)

View File

@@ -16,7 +16,7 @@ _llgo_0:
%2 = mul i64 %0, 4 %2 = mul i64 %0, 4
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %2) %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 %2)
%4 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %3, i64 %0, i64 %0) %4 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %3, i64 %0, i64 %0)
%5 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) %5 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 1
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
@@ -29,7 +29,7 @@ _llgo_2: ; preds = %_llgo_1
%9 = extractvalue { ptr, ptr } %1, 1 %9 = extractvalue { ptr, ptr } %1, 1
%10 = extractvalue { ptr, ptr } %1, 0 %10 = extractvalue { ptr, ptr } %1, 0
%11 = call i32 %10(ptr %9) %11 = call i32 %10(ptr %9)
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %4) %12 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %4, 0
%13 = getelementptr inbounds i32, ptr %12, i64 %7 %13 = getelementptr inbounds i32, ptr %12, i64 %7
store i32 %11, ptr %13, align 4 store i32 %11, ptr %13, align 4
br label %_llgo_1 br label %_llgo_1
@@ -76,7 +76,7 @@ _llgo_0:
store ptr null, ptr %4, align 8 store ptr null, ptr %4, align 8
%5 = load { ptr, ptr }, ptr %2, align 8 %5 = load { ptr, ptr }, ptr %2, align 8
%6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %5) %6 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %5)
%7 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %6) %7 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 1
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
@@ -86,7 +86,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %10, label %_llgo_2, label %_llgo_3 br i1 %10, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%11 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %6) %11 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %6, 0
%12 = getelementptr inbounds i32, ptr %11, i64 %9 %12 = getelementptr inbounds i32, ptr %11, i64 %9
%13 = load i32, ptr %12, align 4 %13 = load i32, ptr %12, align 4
%14 = call i32 (ptr, ...) @printf(ptr @0, i32 %13) %14 = call i32 (ptr, ...) @printf(ptr @0, i32 %13)
@@ -105,7 +105,7 @@ _llgo_3: ; preds = %_llgo_1
store ptr %16, ptr %20, align 8 store ptr %16, ptr %20, align 8
%21 = load { ptr, ptr }, ptr %18, align 8 %21 = load { ptr, ptr }, ptr %18, align 8
%22 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %21) %22 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %21)
%23 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %22) %23 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 1
br label %_llgo_4 br label %_llgo_4
_llgo_4: ; preds = %_llgo_5, %_llgo_3 _llgo_4: ; preds = %_llgo_5, %_llgo_3
@@ -115,7 +115,7 @@ _llgo_4: ; preds = %_llgo_5, %_llgo_3
br i1 %26, label %_llgo_5, label %_llgo_6 br i1 %26, label %_llgo_5, label %_llgo_6
_llgo_5: ; preds = %_llgo_4 _llgo_5: ; preds = %_llgo_4
%27 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %22) %27 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %22, 0
%28 = getelementptr inbounds i32, ptr %27, i64 %25 %28 = getelementptr inbounds i32, ptr %27, i64 %25
%29 = load i32, ptr %28, align 4 %29 = load i32, ptr %28, align 4
%30 = call i32 (ptr, ...) @printf(ptr @1, i32 %29) %30 = call i32 (ptr, ...) @printf(ptr @1, i32 %29)
@@ -135,7 +135,7 @@ _llgo_6: ; preds = %_llgo_4
store ptr %33, ptr %37, align 8 store ptr %33, ptr %37, align 8
%38 = load { ptr, ptr }, ptr %35, align 8 %38 = load { ptr, ptr }, ptr %35, align 8
%39 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %38) %39 = call %"github.com/goplus/llgo/internal/runtime.Slice" @main.genInts(i64 5, { ptr, ptr } %38)
%40 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %39) %40 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 1
br label %_llgo_7 br label %_llgo_7
_llgo_7: ; preds = %_llgo_8, %_llgo_6 _llgo_7: ; preds = %_llgo_8, %_llgo_6
@@ -145,7 +145,7 @@ _llgo_7: ; preds = %_llgo_8, %_llgo_6
br i1 %43, label %_llgo_8, label %_llgo_9 br i1 %43, label %_llgo_8, label %_llgo_9
_llgo_8: ; preds = %_llgo_7 _llgo_8: ; preds = %_llgo_7
%44 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %39) %44 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %39, 0
%45 = getelementptr inbounds i32, ptr %44, i64 %42 %45 = getelementptr inbounds i32, ptr %44, i64 %42
%46 = load i32, ptr %45, align 4 %46 = load i32, ptr %45, align 4
%47 = call i32 (ptr, ...) @printf(ptr @2, i32 %46) %47 = call i32 (ptr, ...) @printf(ptr @2, i32 %46)
@@ -159,10 +159,6 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr, i64, i64)
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare void @"github.com/goplus/llgo/internal/runtime.init"() declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare i32 @rand() declare i32 @rand()

View File

@@ -44,7 +44,7 @@ _llgo_0:
define i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %0) { define i64 @main.sum(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
_llgo_0: _llgo_0:
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %1 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 1
br label %_llgo_1 br label %_llgo_1
_llgo_1: ; preds = %_llgo_2, %_llgo_0 _llgo_1: ; preds = %_llgo_2, %_llgo_0
@@ -55,7 +55,7 @@ _llgo_1: ; preds = %_llgo_2, %_llgo_0
br i1 %5, label %_llgo_2, label %_llgo_3 br i1 %5, label %_llgo_2, label %_llgo_3
_llgo_2: ; preds = %_llgo_1 _llgo_2: ; preds = %_llgo_1
%6 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) %6 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %0, 0
%7 = getelementptr inbounds i64, ptr %6, i64 %4 %7 = getelementptr inbounds i64, ptr %6, i64 %4
%8 = load i64, ptr %7, align 4 %8 = load i64, ptr %7, align 4
%9 = add i64 %2, %8 %9 = add i64 %2, %8
@@ -72,7 +72,3 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
declare i32 @printf(ptr, ...) declare i32 @printf(ptr, ...)
declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice")

Binary file not shown.

40
internal/runtime/slice.go Normal file
View File

@@ -0,0 +1,40 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
// nextslicecap computes the next appropriate slice length.
func nextslicecap(newLen, oldCap int) int {
newcap := oldCap
doublecap := newcap + newcap
if newLen > doublecap {
return newLen
}
const threshold = 256
if oldCap < threshold {
return doublecap
}
for {
// Transition from growing 2x for small slices
// to growing 1.25x for large slices. This formula
// gives a smooth-ish transition between the two.
newcap += (newcap + 3*threshold) >> 2
// We need to check `newcap >= newLen` and whether `newcap` overflowed.
// newLen is guaranteed to be larger than zero, hence
// when newcap overflows then `uint(newcap) > uint(newLen)`.
// This allows to check for both with the same comparison.
if uint(newcap) >= uint(newLen) {
break
}
}
// Set newcap to the requested cap when
// the newcap calculation overflowed.
if newcap <= 0 {
return newLen
}
return newcap
}

View File

@@ -70,4 +70,25 @@ func SliceData(s Slice) unsafe.Pointer {
return s.data return s.data
} }
// SliceAppend append elem data and returns a slice.
func SliceAppend(src Slice, data unsafe.Pointer, num, etSize int) Slice {
if etSize == 0 {
return src
}
oldLen := src.len
newLen := src.len + num
if newLen > src.cap {
newCap := nextslicecap(newLen, src.cap)
p := AllocZ(uintptr(newCap * etSize))
if oldLen != 0 {
c.Memcpy(p, src.data, uintptr(oldLen*etSize))
}
src.data = p
src.cap = newCap
}
src.len = newLen
c.Memcpy(c.Advance(src.data, oldLen*etSize), data, uintptr(num*etSize))
return src
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -632,6 +632,36 @@ func (b Builder) StringLen(x Expr) Expr {
return Expr{ptr, prog.Int()} return Expr{ptr, prog.Int()}
} }
// SliceData returns the data pointer of a slice.
func (b Builder) SliceData(x Expr) Expr {
if debugInstr {
log.Printf("SliceData %v\n", x.impl)
}
prog := b.Prog
ptr := llvm.CreateExtractValue(b.impl, x.impl, 0)
return Expr{ptr, prog.CStr()}
}
// SliceLen returns the length of a slice.
func (b Builder) SliceLen(x Expr) Expr {
if debugInstr {
log.Printf("SliceLen %v\n", x.impl)
}
prog := b.Prog
ptr := llvm.CreateExtractValue(b.impl, x.impl, 1)
return Expr{ptr, prog.Int()}
}
// SliceCap returns the length of a slice cap.
func (b Builder) SliceCap(x Expr) Expr {
if debugInstr {
log.Printf("SliceCap %v\n", x.impl)
}
prog := b.Prog
ptr := llvm.CreateExtractValue(b.impl, x.impl, 2)
return Expr{ptr, prog.Int()}
}
// The IndexAddr instruction yields the address of the element at // The IndexAddr instruction yields the address of the element at
// index `idx` of collection `x`. `idx` is an integer expression. // index `idx` of collection `x`. `idx` is an integer expression.
// //
@@ -653,8 +683,7 @@ func (b Builder) IndexAddr(x, idx Expr) Expr {
pt := prog.Pointer(telem) pt := prog.Pointer(telem)
switch x.raw.Type.Underlying().(type) { switch x.raw.Type.Underlying().(type) {
case *types.Slice: case *types.Slice:
pkg := b.Func.Pkg ptr := b.SliceData(x)
ptr := b.InlineCall(pkg.rtFunc("SliceData"), x)
indices := []llvm.Value{idx.impl} indices := []llvm.Value{idx.impl}
return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, ptr.impl, indices), pt} return Expr{llvm.CreateInBoundsGEP(b.impl, telem.ll, ptr.impl, indices), pt}
} }
@@ -757,12 +786,12 @@ func (b Builder) Slice(x, low, high, max Expr) (ret Expr) {
return return
case *types.Slice: case *types.Slice:
nEltSize = b.SizeOf(prog.Index(x.Type)) nEltSize = b.SizeOf(prog.Index(x.Type))
nCap = b.InlineCall(pkg.rtFunc("SliceCap"), x) nCap = b.SliceCap(x)
if high.IsNil() { if high.IsNil() {
high = b.InlineCall(pkg.rtFunc("SliceLen"), x) high = b.SliceCap(x)
} }
ret.Type = x.Type ret.Type = x.Type
base = b.InlineCall(pkg.rtFunc("SliceData"), x) base = b.SliceData(x)
case *types.Pointer: case *types.Pointer:
telem := t.Elem() telem := t.Elem()
switch te := telem.Underlying().(type) { switch te := telem.Underlying().(type) {
@@ -1297,21 +1326,40 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
case "len": case "len":
if len(args) == 1 { if len(args) == 1 {
arg := args[0] arg := args[0]
switch t := arg.raw.Type.Underlying().(type) { switch arg.kind {
case *types.Slice: case vkSlice:
return b.InlineCall(b.Func.Pkg.rtFunc("SliceLen"), arg) return b.SliceLen(arg)
case *types.Basic: case vkString:
if t.Kind() == types.String { return b.StringLen(arg)
return b.StringLen(arg)
}
} }
} }
case "cap": case "cap":
if len(args) == 1 { if len(args) == 1 {
arg := args[0] arg := args[0]
switch arg.raw.Type.Underlying().(type) { switch arg.kind {
case *types.Slice: case vkSlice:
return b.InlineCall(b.Func.Pkg.rtFunc("SliceCap"), arg) return b.SliceCap(arg)
}
}
case "append":
if len(args) == 2 {
src := args[0]
if src.kind == vkSlice {
elem := args[1]
switch elem.kind {
case vkSlice:
etSize := b.Prog.SizeOf(b.Prog.Elem(elem.Type))
ret.Type = src.Type
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"),
src, b.SliceData(elem), b.SliceLen(elem), b.Prog.Val(int(etSize))).impl
return
case vkString:
etSize := b.Prog.SizeOf(b.Prog.Type(types.Typ[types.Byte], InGo))
ret.Type = src.Type
ret.impl = b.InlineCall(b.Func.Pkg.rtFunc("SliceAppend"),
src, b.StringData(elem), b.StringLen(elem), b.Prog.Val(int(etSize))).impl
return
}
} }
} }
} }

View File

@@ -45,6 +45,7 @@ const (
vkClosure vkClosure
vkPyFuncRef vkPyFuncRef
vkTuple vkTuple
vkSlice
vkPhisExpr = -1 vkPhisExpr = -1
) )
@@ -103,7 +104,10 @@ func (p Program) Pointer(typ Type) Type {
} }
func (p Program) Elem(typ Type) Type { func (p Program) Elem(typ Type) Type {
elem := typ.raw.Type.(*types.Pointer).Elem() elem := typ.raw.Type.(interface {
types.Type
Elem() types.Type
}).Elem()
return p.rawType(elem) return p.rawType(elem)
} }
@@ -237,7 +241,7 @@ func (p Program) toType(raw types.Type) Type {
case *types.Interface: case *types.Interface:
return &aType{p.rtIface(), typ, vkInvalid} return &aType{p.rtIface(), typ, vkInvalid}
case *types.Slice: case *types.Slice:
return &aType{p.rtSlice(), typ, vkInvalid} return &aType{p.rtSlice(), typ, vkSlice}
case *types.Map: case *types.Map:
return &aType{p.rtMap(), typ, vkInvalid} return &aType{p.rtMap(), typ, vkInvalid}
case *types.Struct: case *types.Struct: