update llvm

This commit is contained in:
xushiwei
2024-05-19 16:42:22 +08:00
parent 39268c681f
commit 55365b1d17
7 changed files with 44 additions and 38 deletions

View File

@@ -46,7 +46,7 @@ See [github.com/goplus/llgo/c](https://pkg.go.dev/github.com/goplus/llgo/c) for
You can import a Python library in LLGo! You can import a Python library in LLGo!
And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The currently imported libraries include: And you can import any Python library into `llgo` through a program called `llpyg` (see [Development tools](#development-tools)). The following libraries have been included in `llgo`:
* [builtins](https://pkg.go.dev/github.com/goplus/llgo/py/std) * [builtins](https://pkg.go.dev/github.com/goplus/llgo/py/std)
* [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys) * [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys)

View File

@@ -28,11 +28,9 @@ func testCompile(t *testing.T, src, expected string) {
cltest.TestCompileEx(t, src, "foo.go", expected) cltest.TestCompileEx(t, src, "foo.go", expected)
} }
/*
func TestFromTestgo(t *testing.T) { func TestFromTestgo(t *testing.T) {
cltest.FromDir(t, "strucintf", "./_testgo", false) cltest.FromDir(t, "strucintf", "./_testgo", false)
} }
*/
func TestFromTestpy(t *testing.T) { func TestFromTestpy(t *testing.T) {
cltest.FromDir(t, "", "./_testpy", false) cltest.FromDir(t, "", "./_testpy", false)

2
go.mod
View File

@@ -5,7 +5,7 @@ go 1.18
require ( require (
github.com/aykevl/go-wasm v0.0.1 github.com/aykevl/go-wasm v0.0.1
github.com/goplus/gogen v1.16.0 github.com/goplus/gogen v1.16.0
github.com/goplus/llvm v0.7.5 github.com/goplus/llvm v0.7.6-0.20240519084034-a108b65b00c7
github.com/goplus/mod v0.13.10 github.com/goplus/mod v0.13.10
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/qiniu/x v1.13.10 github.com/qiniu/x v1.13.10

4
go.sum
View File

@@ -6,8 +6,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/goplus/gogen v1.16.0 h1:hAK2ZX8vCjH+Y2QoJl9viSZ8Gw9pzE0vCz5voYBYnv4= github.com/goplus/gogen v1.16.0 h1:hAK2ZX8vCjH+Y2QoJl9viSZ8Gw9pzE0vCz5voYBYnv4=
github.com/goplus/gogen v1.16.0/go.mod h1:92qEzVgv7y8JEFICWG9GvYI5IzfEkxYdsA1DbmnTkqk= github.com/goplus/gogen v1.16.0/go.mod h1:92qEzVgv7y8JEFICWG9GvYI5IzfEkxYdsA1DbmnTkqk=
github.com/goplus/llvm v0.7.5 h1:ges8WcUdu4FBi0mkZUs27p/4qDQlj28N1UpMg3VQUoE= github.com/goplus/llvm v0.7.6-0.20240519084034-a108b65b00c7 h1:N1aC5m6OPjFpG374SketLHl9yIDCcBa6dkkdgQc6EZY=
github.com/goplus/llvm v0.7.5/go.mod h1:PeVK8GgzxwAYCiMiUAJb5wJR6xbhj989tu9oulKLLT4= github.com/goplus/llvm v0.7.6-0.20240519084034-a108b65b00c7/go.mod h1:PeVK8GgzxwAYCiMiUAJb5wJR6xbhj989tu9oulKLLT4=
github.com/goplus/mod v0.13.10 h1:5Om6KOvo31daN7N30kWU1vC5zhsJPM+uPbcEN/FnlzE= github.com/goplus/mod v0.13.10 h1:5Om6KOvo31daN7N30kWU1vC5zhsJPM+uPbcEN/FnlzE=
github.com/goplus/mod v0.13.10/go.mod h1:HDuPZgpWiaTp3PUolFgsiX+Q77cbUWB/mikVHfYND3c= github.com/goplus/mod v0.13.10/go.mod h1:HDuPZgpWiaTp3PUolFgsiX+Q77cbUWB/mikVHfYND3c=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=

View File

@@ -151,7 +151,7 @@ func (b Builder) checkIndex(idx Expr) Expr {
prog := b.Prog prog := b.Prog
if needsNegativeCheck(idx) { if needsNegativeCheck(idx) {
zero := llvm.ConstInt(idx.ll, 0, false) zero := llvm.ConstInt(idx.ll, 0, false)
check := Expr{b.impl.CreateICmp(llvm.IntSLT, idx.impl, zero, ""), prog.Bool()} check := Expr{llvm.CreateICmp(b.impl, llvm.IntSLT, idx.impl, zero), prog.Bool()}
b.InlineCall(b.Pkg.rtFunc("AssertIndexRange"), check) b.InlineCall(b.Pkg.rtFunc("AssertIndexRange"), check)
} }
typ := prog.Uint() typ := prog.Uint()

View File

@@ -320,29 +320,29 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
case isLogicOp(op): // op: & | ^ << >> &^ case isLogicOp(op): // op: & | ^ << >> &^
switch op { switch op {
case token.AND_NOT: case token.AND_NOT:
return Expr{b.impl.CreateAnd(x.impl, b.impl.CreateNot(y.impl, ""), ""), x.Type} return Expr{llvm.CreateAnd(b.impl, x.impl, llvm.CreateNot(b.impl, y.impl)), x.Type}
case token.SHL, token.SHR: case token.SHL, token.SHR:
if needsNegativeCheck(y) { if needsNegativeCheck(y) {
zero := llvm.ConstInt(y.ll, 0, false) zero := llvm.ConstInt(y.ll, 0, false)
check := Expr{b.impl.CreateICmp(llvm.IntSLT, y.impl, zero, ""), b.Prog.Bool()} check := Expr{llvm.CreateICmp(b.impl, llvm.IntSLT, y.impl, zero), b.Prog.Bool()}
b.InlineCall(b.Pkg.rtFunc("AssertNegativeShift"), check) b.InlineCall(b.Pkg.rtFunc("AssertNegativeShift"), check)
} }
xsize, ysize := b.Prog.SizeOf(x.Type), b.Prog.SizeOf(y.Type) xsize, ysize := b.Prog.SizeOf(x.Type), b.Prog.SizeOf(y.Type)
if xsize != ysize { if xsize != ysize {
y = b.Convert(x.Type, y) y = b.Convert(x.Type, y)
} }
overflows := b.impl.CreateICmp(llvm.IntUGE, y.impl, llvm.ConstInt(y.ll, xsize*8, false), "") overflows := llvm.CreateICmp(b.impl, llvm.IntUGE, y.impl, llvm.ConstInt(y.ll, xsize*8, false))
xzero := llvm.ConstInt(x.ll, 0, false) xzero := llvm.ConstInt(x.ll, 0, false)
if op == token.SHL { if op == token.SHL {
rhs := b.impl.CreateShl(x.impl, y.impl, "") rhs := llvm.CreateShl(b.impl, x.impl, y.impl)
return Expr{b.impl.CreateSelect(overflows, xzero, rhs, ""), x.Type} return Expr{llvm.CreateSelect(b.impl, overflows, xzero, rhs), x.Type}
} else { } else {
if x.kind == vkSigned { if x.kind == vkSigned {
rhs := b.impl.CreateSelect(overflows, llvm.ConstInt(y.ll, 8*xsize-1, false), y.impl, "") rhs := llvm.CreateSelect(b.impl, overflows, llvm.ConstInt(y.ll, 8*xsize-1, false), y.impl)
return Expr{b.impl.CreateAShr(x.impl, rhs, ""), x.Type} return Expr{llvm.CreateAShr(b.impl, x.impl, rhs), x.Type}
} else { } else {
rsh := b.impl.CreateLShr(x.impl, y.impl, "") rsh := llvm.CreateLShr(b.impl, x.impl, y.impl)
return Expr{b.impl.CreateSelect(overflows, xzero, rsh, ""), x.Type} return Expr{llvm.CreateSelect(b.impl, overflows, xzero, rsh), x.Type}
} }
} }
default: default:
@@ -390,9 +390,9 @@ func (b Builder) UnOp(op token.Token, x Expr) (ret Expr) {
case *types.Basic: case *types.Basic:
ret.Type = x.Type ret.Type = x.Type
if t.Info()&types.IsInteger != 0 { if t.Info()&types.IsInteger != 0 {
ret.impl = b.impl.CreateNeg(x.impl, "") ret.impl = llvm.CreateNeg(b.impl, x.impl)
} else if t.Info()&types.IsFloat != 0 { } else if t.Info()&types.IsFloat != 0 {
ret.impl = b.impl.CreateFNeg(x.impl, "") ret.impl = llvm.CreateFNeg(b.impl, x.impl)
} else { } else {
panic("todo") panic("todo")
} }
@@ -401,10 +401,10 @@ func (b Builder) UnOp(op token.Token, x Expr) (ret Expr) {
} }
case token.NOT: case token.NOT:
ret.Type = x.Type ret.Type = x.Type
ret.impl = b.impl.CreateNot(x.impl, "") ret.impl = llvm.CreateNot(b.impl, x.impl)
case token.XOR: case token.XOR:
ret.Type = x.Type ret.Type = x.Type
ret.impl = b.impl.CreateXor(x.impl, llvm.ConstInt(x.Type.ll, ^uint64(0), false), "") ret.impl = llvm.CreateXor(b.impl, x.impl, llvm.ConstInt(x.Type.ll, ^uint64(0), false))
case token.ARROW: case token.ARROW:
panic("todo") panic("todo")
} }
@@ -733,7 +733,7 @@ func (b Builder) ChangeType(t Type, x Expr) (ret Expr) {
switch typ.(type) { switch typ.(type) {
default: default:
// TODO(xsw): remove instr name // TODO(xsw): remove instr name
ret.impl = b.impl.CreateBitCast(x.impl, t.ll, "bitCast") ret.impl = llvm.CreateBitCast(b.impl, x.impl, t.ll)
ret.Type = b.Prog.rawType(typ) ret.Type = b.Prog.rawType(typ)
return return
} }
@@ -790,9 +790,9 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
return return
} else if xtyp.Info()&types.IsFloat != 0 { } else if xtyp.Info()&types.IsFloat != 0 {
if typ.Info()&types.IsUnsigned != 0 { if typ.Info()&types.IsUnsigned != 0 {
ret.impl = b.impl.CreateFPToUI(x.impl, t.ll, "") ret.impl = llvm.CreateFPToUI(b.impl, x.impl, t.ll)
} else { } else {
ret.impl = b.impl.CreateFPToSI(x.impl, t.ll, "") ret.impl = llvm.CreateFPToSI(b.impl, x.impl, t.ll)
} }
return return
} }
@@ -800,9 +800,9 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) {
// float <- int/float // float <- int/float
if xtyp.Info()&types.IsInteger != 0 { if xtyp.Info()&types.IsInteger != 0 {
if xtyp.Info()&types.IsUnsigned != 0 { if xtyp.Info()&types.IsUnsigned != 0 {
ret.impl = b.impl.CreateUIToFP(x.impl, t.ll, "") ret.impl = llvm.CreateUIToFP(b.impl, x.impl, t.ll)
} else { } else {
ret.impl = b.impl.CreateSIToFP(x.impl, t.ll, "") ret.impl = llvm.CreateSIToFP(b.impl, x.impl, t.ll)
} }
return return
} else if xtyp.Info()&types.IsFloat != 0 { } else if xtyp.Info()&types.IsFloat != 0 {
@@ -829,11 +829,11 @@ func castInt(b Builder, x llvm.Value, typ Type) llvm.Value {
xsize := b.Prog.td.TypeAllocSize(x.Type()) xsize := b.Prog.td.TypeAllocSize(x.Type())
size := b.Prog.td.TypeAllocSize(typ.ll) size := b.Prog.td.TypeAllocSize(typ.ll)
if xsize > size { if xsize > size {
return b.impl.CreateTrunc(x, typ.ll, "") return llvm.CreateTrunc(b.impl, x, typ.ll)
} else if typ.kind == vkUnsigned { } else if typ.kind == vkUnsigned {
return b.impl.CreateZExt(x, typ.ll, "") return llvm.CreateZExt(b.impl, x, typ.ll)
} else { } else {
return b.impl.CreateSExt(x, typ.ll, "") return llvm.CreateSExt(b.impl, x, typ.ll)
} }
} }
@@ -841,9 +841,9 @@ func castFloat(b Builder, x llvm.Value, typ Type) llvm.Value {
xsize := b.Prog.td.TypeAllocSize(x.Type()) xsize := b.Prog.td.TypeAllocSize(x.Type())
size := b.Prog.td.TypeAllocSize(typ.ll) size := b.Prog.td.TypeAllocSize(typ.ll)
if xsize > size { if xsize > size {
return b.impl.CreateFPTrunc(x, typ.ll, "") return llvm.CreateFPTrunc(b.impl, x, typ.ll)
} else { } else {
return b.impl.CreateFPExt(x, typ.ll, "") return llvm.CreateFPExt(b.impl, x, typ.ll)
} }
} }
@@ -927,7 +927,7 @@ func (b Builder) Call(fn Expr, args ...Expr) (ret Expr) {
// t1 = extract t0 #1 // t1 = extract t0 #1
func (b Builder) Extract(x Expr, index int) (ret Expr) { func (b Builder) Extract(x Expr, index int) (ret Expr) {
ret.Type = b.Prog.toType(x.Type.raw.Type.(*types.Tuple).At(index).Type()) ret.Type = b.Prog.toType(x.Type.raw.Type.(*types.Tuple).At(index).Type())
ret.impl = b.impl.CreateExtractValue(x.impl, index, "") ret.impl = llvm.CreateExtractValue(b.impl, x.impl, index)
return return
} }

View File

@@ -32,6 +32,14 @@ func (b Builder) AbiBasic(kind types.BasicKind) Expr {
return b.InlineCall(b.Pkg.rtFunc("Basic"), b.Prog.Val(int(kind))) return b.InlineCall(b.Pkg.rtFunc("Basic"), b.Prog.Val(int(kind)))
} }
/*
// AbiStruct returns the abi type of the specified struct type.
func (b Builder) AbiStruct(t *types.Struct) Expr {
panic("todo")
// return b.InlineCall(b.Pkg.rtFunc("Struct"), b.Prog.Val(t.NumFields()))
}
*/
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// MakeInterface constructs an instance of an interface type from a // MakeInterface constructs an instance of an interface type from a
@@ -67,19 +75,19 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) {
case kind == types.Float32: case kind == types.Float32:
t := b.AbiBasic(kind) t := b.AbiBasic(kind)
tptr := prog.Uintptr() tptr := prog.Uintptr()
i32 := b.impl.CreateBitCast(x.impl, prog.tyInt32(), "") i32 := llvm.CreateBitCast(b.impl, x.impl, prog.tyInt32()) // TODO(xsw): more effective
vptr := Expr{llvm.CreateIntCast(b.impl, i32, tptr.ll), tptr} vptr := Expr{llvm.CreateIntCast(b.impl, i32, tptr.ll), tptr}
return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter} return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter}
case kind == types.Float64: case kind == types.Float64:
t := b.AbiBasic(kind) t := b.AbiBasic(kind)
tptr := prog.Uintptr() tptr := prog.Uintptr()
vptr := Expr{b.impl.CreateBitCast(x.impl, tptr.ll, ""), tptr} vptr := Expr{llvm.CreateBitCast(b.impl, x.impl, tptr.ll), tptr}
return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter} return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter}
case kind == types.String: case kind == types.String:
return Expr{b.InlineCall(pkg.rtFunc("MakeAnyString"), x).impl, tinter} return Expr{b.InlineCall(pkg.rtFunc("MakeAnyString"), x).impl, tinter}
} }
// case *types.Struct: // case *types.Struct:
// panic("todo: struct") // t := b.AbiStruct(tx)
} }
panic("todo") panic("todo")
} }
@@ -149,9 +157,9 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
switch kind { switch kind {
case types.Float32: case types.Float32:
v = castInt(b, v, b.Prog.Int32()) v = castInt(b, v, b.Prog.Int32())
v = b.impl.CreateBitCast(v, assertedTyp.ll, "") v = llvm.CreateBitCast(b.impl, v, assertedTyp.ll)
case types.Float64: case types.Float64:
v = b.impl.CreateBitCast(v, assertedTyp.ll, "") v = llvm.CreateBitCast(b.impl, v, assertedTyp.ll)
default: default:
v = castInt(b, v, assertedTyp) v = castInt(b, v, assertedTyp)
} }
@@ -167,8 +175,8 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
ret.Type.RawType().(*types.Tuple).At(1), ret.Type.RawType().(*types.Tuple).At(1),
), ),
) )
val0 := conv(b.impl.CreateExtractValue(ret.impl, 0, "")) val0 := conv(llvm.CreateExtractValue(b.impl, ret.impl, 0))
val1 := b.impl.CreateExtractValue(ret.impl, 1, "") val1 := llvm.CreateExtractValue(b.impl, ret.impl, 1)
ret.impl = llvm.ConstStruct([]llvm.Value{val0, val1}, false) ret.impl = llvm.ConstStruct([]llvm.Value{val0, val1}, false)
} }
} }