diff --git a/README.md b/README.md index f575ddc9..cdb38794 100644 --- a/README.md +++ b/README.md @@ -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! -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) * [sys](https://pkg.go.dev/github.com/goplus/llgo/py/sys) diff --git a/go.mod b/go.mod index 03585e58..d49f25d5 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/aykevl/go-wasm v0.0.1 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/json-iterator/go v1.1.12 github.com/qiniu/x v1.13.10 diff --git a/go.sum b/go.sum index 02ccb95b..0a1f347c 100644 --- a/go.sum +++ b/go.sum @@ -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/goplus/gogen v1.16.0 h1:hAK2ZX8vCjH+Y2QoJl9viSZ8Gw9pzE0vCz5voYBYnv4= 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.5/go.mod h1:PeVK8GgzxwAYCiMiUAJb5wJR6xbhj989tu9oulKLLT4= +github.com/goplus/llvm v0.7.6-0.20240519084034-a108b65b00c7 h1:N1aC5m6OPjFpG374SketLHl9yIDCcBa6dkkdgQc6EZY= +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/go.mod h1:HDuPZgpWiaTp3PUolFgsiX+Q77cbUWB/mikVHfYND3c= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= diff --git a/ssa/datastruct.go b/ssa/datastruct.go index 06f26b3a..0ce70e97 100644 --- a/ssa/datastruct.go +++ b/ssa/datastruct.go @@ -151,7 +151,7 @@ func (b Builder) checkIndex(idx Expr) Expr { prog := b.Prog if needsNegativeCheck(idx) { 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) } typ := prog.Uint() diff --git a/ssa/expr.go b/ssa/expr.go index 740bce6b..0ff74112 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -320,29 +320,29 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr { case isLogicOp(op): // op: & | ^ << >> &^ switch op { 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: if needsNegativeCheck(y) { 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) } xsize, ysize := b.Prog.SizeOf(x.Type), b.Prog.SizeOf(y.Type) if xsize != ysize { 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) if op == token.SHL { - rhs := b.impl.CreateShl(x.impl, y.impl, "") - return Expr{b.impl.CreateSelect(overflows, xzero, rhs, ""), x.Type} + rhs := llvm.CreateShl(b.impl, x.impl, y.impl) + return Expr{llvm.CreateSelect(b.impl, overflows, xzero, rhs), x.Type} } else { if x.kind == vkSigned { - rhs := b.impl.CreateSelect(overflows, llvm.ConstInt(y.ll, 8*xsize-1, false), y.impl, "") - return Expr{b.impl.CreateAShr(x.impl, rhs, ""), x.Type} + rhs := llvm.CreateSelect(b.impl, overflows, llvm.ConstInt(y.ll, 8*xsize-1, false), y.impl) + return Expr{llvm.CreateAShr(b.impl, x.impl, rhs), x.Type} } else { - rsh := b.impl.CreateLShr(x.impl, y.impl, "") - return Expr{b.impl.CreateSelect(overflows, xzero, rsh, ""), x.Type} + rsh := llvm.CreateLShr(b.impl, x.impl, y.impl) + return Expr{llvm.CreateSelect(b.impl, overflows, xzero, rsh), x.Type} } } default: @@ -390,9 +390,9 @@ func (b Builder) UnOp(op token.Token, x Expr) (ret Expr) { case *types.Basic: ret.Type = x.Type 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 { - ret.impl = b.impl.CreateFNeg(x.impl, "") + ret.impl = llvm.CreateFNeg(b.impl, x.impl) } else { panic("todo") } @@ -401,10 +401,10 @@ func (b Builder) UnOp(op token.Token, x Expr) (ret Expr) { } case token.NOT: ret.Type = x.Type - ret.impl = b.impl.CreateNot(x.impl, "") + ret.impl = llvm.CreateNot(b.impl, x.impl) case token.XOR: 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: panic("todo") } @@ -733,7 +733,7 @@ func (b Builder) ChangeType(t Type, x Expr) (ret Expr) { switch typ.(type) { default: // 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) return } @@ -790,9 +790,9 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) { return } else if xtyp.Info()&types.IsFloat != 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 { - ret.impl = b.impl.CreateFPToSI(x.impl, t.ll, "") + ret.impl = llvm.CreateFPToSI(b.impl, x.impl, t.ll) } return } @@ -800,9 +800,9 @@ func (b Builder) Convert(t Type, x Expr) (ret Expr) { // float <- int/float if xtyp.Info()&types.IsInteger != 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 { - ret.impl = b.impl.CreateSIToFP(x.impl, t.ll, "") + ret.impl = llvm.CreateSIToFP(b.impl, x.impl, t.ll) } return } 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()) size := b.Prog.td.TypeAllocSize(typ.ll) if xsize > size { - return b.impl.CreateTrunc(x, typ.ll, "") + return llvm.CreateTrunc(b.impl, x, typ.ll) } else if typ.kind == vkUnsigned { - return b.impl.CreateZExt(x, typ.ll, "") + return llvm.CreateZExt(b.impl, x, typ.ll) } 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()) size := b.Prog.td.TypeAllocSize(typ.ll) if xsize > size { - return b.impl.CreateFPTrunc(x, typ.ll, "") + return llvm.CreateFPTrunc(b.impl, x, typ.ll) } 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 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.impl = b.impl.CreateExtractValue(x.impl, index, "") + ret.impl = llvm.CreateExtractValue(b.impl, x.impl, index) return } diff --git a/ssa/interface.go b/ssa/interface.go index 1bbfc8e9..ee9a451e 100644 --- a/ssa/interface.go +++ b/ssa/interface.go @@ -32,6 +32,14 @@ func (b Builder) AbiBasic(kind types.BasicKind) Expr { 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 @@ -67,19 +75,19 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) { case kind == types.Float32: t := b.AbiBasic(kind) 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} return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter} case kind == types.Float64: t := b.AbiBasic(kind) 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} case kind == types.String: return Expr{b.InlineCall(pkg.rtFunc("MakeAnyString"), x).impl, tinter} } // case *types.Struct: - // panic("todo: struct") + // t := b.AbiStruct(tx) } panic("todo") } @@ -149,9 +157,9 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) { switch kind { case types.Float32: 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: - v = b.impl.CreateBitCast(v, assertedTyp.ll, "") + v = llvm.CreateBitCast(b.impl, v, assertedTyp.ll) default: 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), ), ) - val0 := conv(b.impl.CreateExtractValue(ret.impl, 0, "")) - val1 := b.impl.CreateExtractValue(ret.impl, 1, "") + val0 := conv(llvm.CreateExtractValue(b.impl, ret.impl, 0)) + val1 := llvm.CreateExtractValue(b.impl, ret.impl, 1) ret.impl = llvm.ConstStruct([]llvm.Value{val0, val1}, false) } }