ssa: index check take address

This commit is contained in:
visualfc
2024-07-03 13:21:18 +08:00
parent 28d8c56534
commit 490a16a8df
8 changed files with 1154 additions and 548 deletions

View File

@@ -317,93 +317,94 @@ _llgo_0:
store ptr null, ptr %70, align 8 store ptr null, ptr %70, align 8
%71 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, align 8 %71 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %68, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %71) call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %71)
%72 = load ptr, ptr @"[10]_llgo_int", align 8 %72 = load ptr, ptr @_llgo_int, align 8
%73 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 80) %73 = load ptr, ptr @"[10]_llgo_int", align 8
store [10 x i64] zeroinitializer, ptr %73, align 4 %74 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 80)
%74 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 store [10 x i64] zeroinitializer, ptr %74, align 4
%75 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, i32 0, i32 0 %75 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
store ptr %72, ptr %75, align 8 %76 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %75, i32 0, i32 0
%76 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, i32 0, i32 1
store ptr %73, ptr %76, align 8 store ptr %73, ptr %76, align 8
%77 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %74, align 8 %77 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %75, i32 0, i32 1
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %77) store ptr %74, ptr %77, align 8
%78 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8 %78 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %75, align 8
%79 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %78)
%80 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %79, i32 0, i32 0 %79 = load ptr, ptr @"_llgo_func$2_iS07vIlF2_rZqWB5eU0IvP_9HviM4MYZNkXZDvbac", align 8
store ptr %78, ptr %80, align 8 %80 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %79, i32 0, i32 1 %81 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %80, i32 0, i32 0
store ptr @"main.main$1", ptr %81, align 8 store ptr %79, ptr %81, align 8
%82 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %79, align 8 %82 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %80, i32 0, i32 1
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %82) store ptr @"main.main$1", ptr %82, align 8
%83 = load ptr, ptr @"*_llgo_int", align 8 %83 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %80, align 8
%84 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %83)
%85 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %84, i32 0, i32 0 %84 = load ptr, ptr @"*_llgo_int", align 8
store ptr %83, ptr %85, align 8 %85 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%86 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %84, i32 0, i32 1 %86 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %85, i32 0, i32 0
store ptr null, ptr %86, align 8 store ptr %84, ptr %86, align 8
%87 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %84, align 8 %87 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %85, i32 0, i32 1
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %87) store ptr null, ptr %87, align 8
%88 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 0) %88 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %85, align 8
%89 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8 call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %88)
%90 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, i32 0, i32 0 %89 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 0)
store ptr %88, ptr %90, align 8 %90 = alloca %"github.com/goplus/llgo/internal/runtime.Slice", align 8
%91 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, i32 0, i32 1 %91 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %90, i32 0, i32 0
store i64 0, ptr %91, align 4 store ptr %89, ptr %91, align 8
%92 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, i32 0, i32 2 %92 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %90, i32 0, i32 1
store i64 0, ptr %92, align 4 store i64 0, ptr %92, align 4
%93 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %89, align 8 %93 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.Slice", ptr %90, i32 0, i32 2
%94 = load ptr, ptr @"[]_llgo_int", align 8 store i64 0, ptr %93, align 4
%95 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24) %94 = load %"github.com/goplus/llgo/internal/runtime.Slice", ptr %90, align 8
store %"github.com/goplus/llgo/internal/runtime.Slice" %93, ptr %95, align 8 %95 = load ptr, ptr @"[]_llgo_int", align 8
%96 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %96 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
%97 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %96, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.Slice" %94, ptr %96, align 8
store ptr %94, ptr %97, align 8 %97 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%98 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %96, i32 0, i32 1 %98 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %97, i32 0, i32 0
store ptr %95, ptr %98, align 8 store ptr %95, ptr %98, align 8
%99 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %96, align 8 %99 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %97, i32 0, i32 1
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %99) store ptr %96, ptr %99, align 8
%100 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %100 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %97, align 8
%101 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %100, i32 0, i32 0 call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %100)
store ptr @3, ptr %101, align 8 %101 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%102 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %100, i32 0, i32 1 %102 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %101, i32 0, i32 0
store i64 5, ptr %102, align 4 store ptr @3, ptr %102, align 8
%103 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %100, align 8 %103 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %101, i32 0, i32 1
%104 = load ptr, ptr @_llgo_string, align 8 store i64 5, ptr %103, align 4
%105 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) %104 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %101, align 8
store %"github.com/goplus/llgo/internal/runtime.String" %103, ptr %105, align 8 %105 = load ptr, ptr @_llgo_string, align 8
%106 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %106 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
%107 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %106, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.String" %104, ptr %106, align 8
store ptr %104, ptr %107, align 8 %107 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%108 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %106, i32 0, i32 1 %108 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, i32 0, i32 0
store ptr %105, ptr %108, align 8 store ptr %105, ptr %108, align 8
%109 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %106, align 8 %109 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, i32 0, i32 1
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %109) store ptr %106, ptr %109, align 8
%110 = load ptr, ptr @"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM", align 8 %110 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %107, align 8
%111 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24) call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %110)
store { i8, i64, i64 } zeroinitializer, ptr %111, align 4 %111 = load ptr, ptr @"main.struct$RKbUG45GE4henGMAdmt0Rju0JptyR8NsX7IZLsOI0OM", align 8
%112 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %112 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 24)
%113 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %112, i32 0, i32 0 store { i8, i64, i64 } zeroinitializer, ptr %112, align 4
store ptr %110, ptr %113, align 8 %113 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%114 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %112, i32 0, i32 1 %114 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %113, i32 0, i32 0
store ptr %111, ptr %114, align 8 store ptr %111, ptr %114, align 8
%115 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %112, align 8 %115 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %113, i32 0, i32 1
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %115) store ptr %112, ptr %115, align 8
%116 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8 %116 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %113, align 8
%117 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %116, i32 0, i32 0 call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %116)
store ptr null, ptr %117, align 8 %117 = alloca %"github.com/goplus/llgo/internal/runtime.String", align 8
%118 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %116, i32 0, i32 1 %118 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %117, i32 0, i32 0
store i64 0, ptr %118, align 4 store ptr null, ptr %118, align 8
%119 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %116, align 8 %119 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.String", ptr %117, i32 0, i32 1
%120 = load ptr, ptr @_llgo_main.T, align 8 store i64 0, ptr %119, align 4
%121 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16) %120 = load %"github.com/goplus/llgo/internal/runtime.String", ptr %117, align 8
store %"github.com/goplus/llgo/internal/runtime.String" %119, ptr %121, align 8 %121 = load ptr, ptr @_llgo_main.T, align 8
%122 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8 %122 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
%123 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %122, i32 0, i32 0 store %"github.com/goplus/llgo/internal/runtime.String" %120, ptr %122, align 8
store ptr %120, ptr %123, align 8 %123 = alloca %"github.com/goplus/llgo/internal/runtime.eface", align 8
%124 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %122, i32 0, i32 1 %124 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %123, i32 0, i32 0
store ptr %121, ptr %124, align 8 store ptr %121, ptr %124, align 8
%125 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %122, align 8 %125 = getelementptr inbounds %"github.com/goplus/llgo/internal/runtime.eface", ptr %123, i32 0, i32 1
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %125) store ptr %122, ptr %125, align 8
%126 = load %"github.com/goplus/llgo/internal/runtime.eface", ptr %123, align 8
call void @main.dump(%"github.com/goplus/llgo/internal/runtime.eface" %126)
ret i32 0 ret i32 0
} }

View File

@@ -1,8 +1,13 @@
package main package main
type N [1]int
func main() { func main() {
make1()
make2()
make3()
make4()
}
func make1() {
m := make(map[int]string) m := make(map[int]string)
m[1] = "hello" m[1] = "hello"
m[2] = "world" m[2] = "world"
@@ -30,18 +35,55 @@ func main() {
if len(s) != 2 { if len(s) != 2 {
panic("bad len") panic("bad len")
} }
}
type N1 [1]int
func make2() {
m2 := make(map[int]string) m2 := make(map[int]string)
println(m2, len(m2), m2 == nil, m2 != nil) println(m2, len(m2), m2 == nil, m2 != nil)
var m3 map[int]string var m3 map[int]string
println(m3, len(m3), m3 == nil, m3 != nil) println(m3, len(m3), m3 == nil, m3 != nil)
n := make(map[any]int) n := make(map[any]int)
n[N{1}] = 100 n[N1{1}] = 100
n[N{2}] = 200 n[N1{2}] = 200
n[N{3}] = 300 n[N1{3}] = 300
n[N{2}] = -200 n[N1{2}] = -200
for k, v := range n { for k, v := range n {
println(k.(N)[0], v) println(k.(N1)[0], v)
}
}
type N struct {
n1 int8
n2 int8
}
type K [1]N
type K2 [1]*N
func make3() {
var a any = K{N{1, 2}}
var b any = K{N{1, 2}}
println(a == b)
m := make(map[any]int)
m[K{N{1, 2}}] = 100
m[K{N{3, 4}}] = 200
for k, v := range m {
println(k.(K)[0].n1, v)
}
}
func make4() {
var a any = K2{&N{1, 2}}
var b any = K2{&N{1, 2}}
println(a == b)
m := make(map[any]int)
m[K2{&N{1, 2}}] = 100
m[K2{&N{3, 4}}] = 200
for k, v := range m {
println(k.(K2)[0].n1, v)
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -493,10 +493,12 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
case *ssa.Index: case *ssa.Index:
x := p.compileValue(b, v.X) x := p.compileValue(b, v.X)
idx := p.compileValue(b, v.Index) idx := p.compileValue(b, v.Index)
ret = b.Index(x, idx, func() (r llssa.Expr) { ret = b.Index(x, idx, func() (addr llssa.Expr, zero bool) {
switch n := v.X.(type) { switch n := v.X.(type) {
case *ssa.Const:
zero = true
case *ssa.UnOp: case *ssa.UnOp:
return p.compileValue(b, n.X) addr = p.compileValue(b, n.X)
} }
return return
}) })

View File

@@ -148,7 +148,7 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
switch t.Kind() { switch t.Kind() {
case abi.Bool, abi.Int, abi.Int8, abi.Int16, abi.Int32, abi.Int64, case abi.Bool, abi.Int, abi.Int8, abi.Int16, abi.Int32, abi.Int64,
abi.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uint64, abi.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uint64,
abi.Uintptr, abi.UnsafePointer: abi.Uintptr, abi.UnsafePointer, abi.Pointer:
switch t.Size_ { switch t.Size_ {
case 4: case 4:
return memhash32(p, h) return memhash32(p, h)

View File

@@ -135,7 +135,6 @@ func InitNamed(ret *Type, pkgPath, name string, underlying *Type, methods, ptrMe
doInitNamed(ret, pkgPath, name, underlying, methods) doInitNamed(ret, pkgPath, name, underlying, methods)
doInitNamed(ptr, pkgPath, name, newPointer(ret), ptrMethods) doInitNamed(ptr, pkgPath, name, newPointer(ret), ptrMethods)
ret.PtrToThis_ = ptr ret.PtrToThis_ = ptr
ret.Equal = underlying.Equal
ptr.TFlag |= abi.TFlagExtraStar ptr.TFlag |= abi.TFlagExtraStar
} }
@@ -164,6 +163,7 @@ func doInitNamed(ret *Type, pkgPath, fullName string, underlying *Type, methods
ret.TFlag = tflag | abi.TFlagNamed | abi.TFlagUncommon ret.TFlag = tflag | abi.TFlagNamed | abi.TFlagUncommon
ret.Str_ = fullName ret.Str_ = fullName
ret.Equal = underlying.Equal
n := len(methods) n := len(methods)
xcount := uint16(0) xcount := uint16(0)

View File

@@ -406,7 +406,7 @@ func (b Builder) abiType(t types.Type) Expr {
case *types.Pointer: case *types.Pointer:
b.loadType(t.Elem()) b.loadType(t.Elem())
case *types.Array: case *types.Array:
b.loadType(t.Elem()) b.abiType(t.Elem())
} }
g := b.loadType(t) g := b.loadType(t)
return b.Load(g.Expr) return b.Load(g.Expr)

View File

@@ -286,7 +286,7 @@ func (b Builder) checkIndex(idx Expr, max Expr) Expr {
// Example printed form: // Example printed form:
// //
// t2 = t0[t1] // t2 = t0[t1]
func (b Builder) Index(x, idx Expr, takeAddr func() Expr) Expr { func (b Builder) Index(x, idx Expr, takeAddr func() (addr Expr, zero bool)) Expr {
if debugInstr { if debugInstr {
log.Printf("Index %v, %v\n", x.impl, idx.impl) log.Printf("Index %v, %v\n", x.impl, idx.impl)
} }
@@ -294,6 +294,7 @@ func (b Builder) Index(x, idx Expr, takeAddr func() Expr) Expr {
var telem Type var telem Type
var ptr Expr var ptr Expr
var max Expr var max Expr
var zero bool
switch t := x.raw.Type.Underlying().(type) { switch t := x.raw.Type.Underlying().(type) {
case *types.Basic: case *types.Basic:
if t.Kind() != types.String { if t.Kind() != types.String {
@@ -304,12 +305,19 @@ func (b Builder) Index(x, idx Expr, takeAddr func() Expr) Expr {
max = b.StringLen(x) max = b.StringLen(x)
case *types.Array: case *types.Array:
telem = prog.Index(x.Type) telem = prog.Index(x.Type)
ptr = takeAddr() ptr, zero = takeAddr()
max = prog.IntVal(uint64(t.Len()), prog.Int()) max = prog.IntVal(uint64(t.Len()), prog.Int())
} }
idx = b.checkIndex(idx, max) idx = b.checkIndex(idx, max)
if zero {
return prog.Zero(telem)
}
if ptr.IsNil() { if ptr.IsNil() {
return Expr{llvm.ConstExtractElement(x.impl, idx.impl), telem} if x.impl.IsConstant() {
return Expr{llvm.ConstExtractElement(x.impl, idx.impl), telem}
}
ptr = b.Alloc(x.Type, false)
b.impl.CreateStore(x.impl, ptr.impl)
} }
pt := prog.Pointer(telem) pt := prog.Pointer(telem)
indices := []llvm.Value{idx.impl} indices := []llvm.Value{idx.impl}