ssa: builtin len&cap
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
source_filename = "main"
|
source_filename = "main"
|
||||||
|
|
||||||
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||||
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
|
|
||||||
|
|
||||||
@"main.init$guard" = global ptr null
|
@"main.init$guard" = global ptr null
|
||||||
@0 = private unnamed_addr constant [13 x i8] c"Hello world\0A\00", align 1
|
@0 = private unnamed_addr constant [13 x i8] c"Hello world\0A\00", align 1
|
||||||
@@ -43,7 +42,7 @@ declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/ll
|
|||||||
|
|
||||||
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,33 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/internal/runtime/c"
|
||||||
|
)
|
||||||
|
|
||||||
var a int64 = 1<<63 - 1
|
var a int64 = 1<<63 - 1
|
||||||
var b int64 = -1 << 63
|
var b int64 = -1 << 63
|
||||||
var c uint64 = 1<<64 - 1
|
var n uint64 = 1<<64 - 1
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var a = []int{1, 2, 3, 4}
|
var s = []int{1, 2, 3, 4}
|
||||||
_ = len(a)
|
var a = [...]int{1, 2, 3, 4}
|
||||||
_ = len([]int{1, 2, 3, 4})
|
|
||||||
|
out(len(s))
|
||||||
|
out(len([]int{1, 2, 3, 4}))
|
||||||
|
out(len(a))
|
||||||
|
out(len(&a))
|
||||||
|
out(len([4]int{1, 2, 3, 4}))
|
||||||
|
string_len("hello")
|
||||||
|
|
||||||
|
out(cap(s))
|
||||||
|
out(cap(a))
|
||||||
|
out(cap(&a))
|
||||||
|
}
|
||||||
|
|
||||||
|
func string_len(s string) {
|
||||||
|
out(len(s))
|
||||||
|
}
|
||||||
|
|
||||||
|
func out(n int) {
|
||||||
|
c.Printf(c.Str("%d\n"), n)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,14 @@
|
|||||||
source_filename = "main"
|
source_filename = "main"
|
||||||
|
|
||||||
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
|
%"github.com/goplus/llgo/internal/runtime.Slice" = type { ptr, i64, i64 }
|
||||||
|
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
|
||||||
|
|
||||||
@main.a = global ptr null
|
@main.a = global ptr null
|
||||||
@main.b = global ptr null
|
@main.b = global ptr null
|
||||||
@main.c = global ptr null
|
|
||||||
@"main.init$guard" = global ptr null
|
@"main.init$guard" = global ptr null
|
||||||
|
@main.n = 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"%d\0A\00", align 1
|
||||||
|
|
||||||
define void @main.init() {
|
define void @main.init() {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
@@ -17,7 +20,7 @@ _llgo_1: ; preds = %_llgo_0
|
|||||||
store i1 true, ptr @"main.init$guard", align 1
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
store i64 9223372036854775807, ptr @main.a, align 4
|
store i64 9223372036854775807, ptr @main.a, align 4
|
||||||
store i64 -9223372036854775808, ptr @main.b, align 4
|
store i64 -9223372036854775808, ptr @main.b, align 4
|
||||||
store i64 -1, ptr @main.c, align 4
|
store i64 -1, ptr @main.n, align 4
|
||||||
br label %_llgo_2
|
br label %_llgo_2
|
||||||
|
|
||||||
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
@@ -38,18 +41,51 @@ _llgo_0:
|
|||||||
%4 = getelementptr inbounds i64, ptr %0, i64 3
|
%4 = getelementptr inbounds i64, ptr %0, i64 3
|
||||||
store i64 4, ptr %4, align 4
|
store i64 4, ptr %4, align 4
|
||||||
%5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %0, i64 4, i64 4)
|
%5 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %0, i64 4, i64 4)
|
||||||
%6 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %5)
|
%6 = alloca [4 x i64], align 8
|
||||||
%7 = call ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(i64 32)
|
%7 = getelementptr inbounds i64, ptr %6, i64 0
|
||||||
%8 = getelementptr inbounds i64, ptr %7, i64 0
|
%8 = getelementptr inbounds i64, ptr %6, i64 1
|
||||||
store i64 1, ptr %8, align 4
|
%9 = getelementptr inbounds i64, ptr %6, i64 2
|
||||||
%9 = getelementptr inbounds i64, ptr %7, i64 1
|
%10 = getelementptr inbounds i64, ptr %6, i64 3
|
||||||
store i64 2, ptr %9, align 4
|
store i64 1, ptr %7, align 4
|
||||||
%10 = getelementptr inbounds i64, ptr %7, i64 2
|
store i64 2, ptr %8, align 4
|
||||||
store i64 3, ptr %10, align 4
|
store i64 3, ptr %9, align 4
|
||||||
%11 = getelementptr inbounds i64, ptr %7, i64 3
|
store i64 4, ptr %10, align 4
|
||||||
store i64 4, ptr %11, align 4
|
%11 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %5)
|
||||||
%12 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %7, i64 4, i64 4)
|
call void @main.out(i64 %11)
|
||||||
%13 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %12)
|
%12 = call ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(i64 32)
|
||||||
|
%13 = getelementptr inbounds i64, ptr %12, i64 0
|
||||||
|
store i64 1, ptr %13, align 4
|
||||||
|
%14 = getelementptr inbounds i64, ptr %12, i64 1
|
||||||
|
store i64 2, ptr %14, align 4
|
||||||
|
%15 = getelementptr inbounds i64, ptr %12, i64 2
|
||||||
|
store i64 3, ptr %15, align 4
|
||||||
|
%16 = getelementptr inbounds i64, ptr %12, i64 3
|
||||||
|
store i64 4, ptr %16, align 4
|
||||||
|
%17 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice"(ptr %12, i64 4, i64 4)
|
||||||
|
%18 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %17)
|
||||||
|
call void @main.out(i64 %18)
|
||||||
|
call void @main.out(i64 4)
|
||||||
|
call void @main.out(i64 4)
|
||||||
|
call void @main.out(i64 4)
|
||||||
|
%19 = 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" %19)
|
||||||
|
%20 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %5)
|
||||||
|
call void @main.out(i64 %20)
|
||||||
|
call void @main.out(i64 4)
|
||||||
|
call void @main.out(i64 4)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main.out(i64 %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = call i32 (ptr, ...) @printf(ptr @1, i64 %0)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main.string_len(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = call i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %0)
|
||||||
|
call void @main.out(i64 %1)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,3 +96,11 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(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 i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"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 i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
|
|
||||||
|
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.Alloc"(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.StringLen"(%"github.com/goplus/llgo/internal/runtime.Slice")
|
declare i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
declare ptr @"github.com/goplus/llgo/internal/runtime.CStrCopy"(ptr, %"github.com/goplus/llgo/internal/runtime.String")
|
||||||
|
|
||||||
|
|||||||
@@ -248,6 +248,15 @@ _llgo_0:
|
|||||||
ret %"github.com/goplus/llgo/internal/runtime.Slice" %4
|
ret %"github.com/goplus/llgo/internal/runtime.Slice" %4
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define i64 @"github.com/goplus/llgo/internal/runtime.SliceCap"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
||||||
|
_llgo_0:
|
||||||
|
%1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
||||||
|
store %"github.com/goplus/llgo/internal/runtime.Slice" %0, ptr %1, align 8
|
||||||
|
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %1, i32 0, i32 2
|
||||||
|
%3 = load i64, ptr %2, align 4
|
||||||
|
ret i64 %3
|
||||||
|
}
|
||||||
|
|
||||||
define ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
define ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
%1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
||||||
@@ -309,11 +318,11 @@ _llgo_0:
|
|||||||
ret ptr %3
|
ret ptr %3
|
||||||
}
|
}
|
||||||
|
|
||||||
define i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) {
|
define i64 @"github.com/goplus/llgo/internal/runtime.StringLen"(%"github.com/goplus/llgo/internal/runtime.String" %0) {
|
||||||
_llgo_0:
|
_llgo_0:
|
||||||
%1 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
|
%1 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
|
||||||
store %"github.com/goplus/llgo/internal/runtime.Slice" %0, ptr %1, align 8
|
store %"github.com/goplus/llgo/internal/runtime.String" %0, ptr %1, align 8
|
||||||
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %1, i32 0, i32 1
|
%2 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %1, i32 0, i32 1
|
||||||
%3 = load i64, ptr %2, align 4
|
%3 = load i64, ptr %2, align 4
|
||||||
ret i64 %3
|
ret i64 %3
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ func SliceLen(s Slice) int {
|
|||||||
return s.len
|
return s.len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SliceCap returns the capacity of a slice.
|
||||||
|
func SliceCap(s Slice) int {
|
||||||
|
return s.cap
|
||||||
|
}
|
||||||
|
|
||||||
// SliceData returns the data pointer of a slice.
|
// SliceData returns the data pointer of a slice.
|
||||||
func SliceData(s Slice) unsafe.Pointer {
|
func SliceData(s Slice) unsafe.Pointer {
|
||||||
return s.data
|
return s.data
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ func NewString(data unsafe.Pointer, len int) String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StringLen returns the length of a string.
|
// StringLen returns the length of a string.
|
||||||
func StringLen(s Slice) int {
|
func StringLen(s String) int {
|
||||||
return s.len
|
return s.len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
14
ssa/expr.go
14
ssa/expr.go
@@ -975,9 +975,21 @@ 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 arg.t.Underlying().(type) {
|
switch t := arg.t.Underlying().(type) {
|
||||||
case *types.Slice:
|
case *types.Slice:
|
||||||
return b.InlineCall(b.fn.pkg.rtFunc("SliceLen"), arg)
|
return b.InlineCall(b.fn.pkg.rtFunc("SliceLen"), arg)
|
||||||
|
case *types.Basic:
|
||||||
|
if t.Info()&types.IsString != 0 {
|
||||||
|
return b.InlineCall(b.fn.pkg.rtFunc("StringLen"), arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "cap":
|
||||||
|
if len(args) == 1 {
|
||||||
|
arg := args[0]
|
||||||
|
switch arg.t.Underlying().(type) {
|
||||||
|
case *types.Slice:
|
||||||
|
return b.InlineCall(b.fn.pkg.rtFunc("SliceCap"), arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user