conflict fix
This commit is contained in:
71
ssa/expr.go
71
ssa/expr.go
@@ -24,6 +24,7 @@ import (
|
||||
"go/types"
|
||||
"log"
|
||||
|
||||
"github.com/goplus/llgo/internal/abi"
|
||||
"github.com/goplus/llvm"
|
||||
)
|
||||
|
||||
@@ -257,6 +258,11 @@ var floatPredOpToLLVM = []llvm.FloatPredicate{
|
||||
token.GEQ - predOpBase: llvm.FloatOGE,
|
||||
}
|
||||
|
||||
var boolPredOpToLLVM = []llvm.IntPredicate{
|
||||
token.EQL - predOpBase: llvm.IntEQ,
|
||||
token.NEQ - predOpBase: llvm.IntNE,
|
||||
}
|
||||
|
||||
// EQL NEQ LSS LEQ GTR GEQ == != < <= < >=
|
||||
func isPredOp(op token.Token) bool {
|
||||
return op >= predOpBase && op <= predOpLast
|
||||
@@ -289,7 +295,7 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
|
||||
}
|
||||
case isLogicOp(op): // op: & | ^ << >> &^
|
||||
if op == token.AND_NOT {
|
||||
panic("todo")
|
||||
return Expr{b.impl.CreateAnd(x.impl, b.impl.CreateNot(y.impl, ""), ""), x.Type}
|
||||
}
|
||||
kind := x.kind
|
||||
llop := logicOpToLLVM[op-logicOpBase]
|
||||
@@ -310,7 +316,10 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr {
|
||||
case vkFloat:
|
||||
pred := floatPredOpToLLVM[op-predOpBase]
|
||||
return Expr{llvm.CreateFCmp(b.impl, pred, x.impl, y.impl), tret}
|
||||
case vkString, vkComplex, vkBool:
|
||||
case vkBool:
|
||||
pred := boolPredOpToLLVM[op-predOpBase]
|
||||
return Expr{llvm.CreateICmp(b.impl, pred, x.impl, y.impl), tret}
|
||||
case vkString, vkComplex:
|
||||
panic("todo")
|
||||
}
|
||||
}
|
||||
@@ -1070,7 +1079,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) {
|
||||
case *types.Basic:
|
||||
kind := tx.Kind()
|
||||
switch {
|
||||
case kind >= types.Int && kind <= types.Uintptr:
|
||||
case kind >= types.Bool && kind <= types.Uintptr:
|
||||
t := b.InlineCall(pkg.rtFunc("Basic"), prog.Val(int(kind)))
|
||||
tptr := prog.Uintptr()
|
||||
vptr := Expr{llvm.CreateIntCast(b.impl, x.impl, tptr.ll), tptr}
|
||||
@@ -1137,7 +1146,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
|
||||
log.Printf("TypeAssert %v, %v, %v\n", x.impl, assertedTyp.raw.Type, commaOk)
|
||||
}
|
||||
switch assertedTyp.kind {
|
||||
case vkSigned, vkUnsigned:
|
||||
case vkSigned, vkUnsigned, vkFloat, vkBool:
|
||||
pkg := b.Func.Pkg
|
||||
fnName := "I2Int"
|
||||
if commaOk {
|
||||
@@ -1152,25 +1161,44 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
|
||||
panic("todo")
|
||||
}
|
||||
typ := b.InlineCall(pkg.rtFunc("Basic"), b.Prog.Val(int(kind)))
|
||||
return b.InlineCall(fn, x, typ)
|
||||
case vkFloat:
|
||||
var fnName string
|
||||
kind := assertedTyp.raw.Underlying().(*types.Basic).Kind()
|
||||
switch kind {
|
||||
case types.Float32:
|
||||
fnName = "I2Float32"
|
||||
if commaOk {
|
||||
fnName = "CheckI2Float32"
|
||||
ret = b.InlineCall(fn, x, typ)
|
||||
if kind != types.Uintptr {
|
||||
conv := func(v llvm.Value) llvm.Value {
|
||||
switch kind {
|
||||
case types.Float32:
|
||||
v = castInt(b.impl, v, b.Prog.tyInt32())
|
||||
v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
|
||||
case types.Float64:
|
||||
v = b.impl.CreateBitCast(v, assertedTyp.ll, "")
|
||||
default:
|
||||
v = castInt(b.impl, v, assertedTyp.ll)
|
||||
}
|
||||
return v
|
||||
}
|
||||
case types.Float64:
|
||||
fnName = "I2Float64"
|
||||
if commaOk {
|
||||
fnName = "CheckI2Float64"
|
||||
if !commaOk {
|
||||
ret.Type = assertedTyp
|
||||
ret.impl = conv(ret.impl)
|
||||
} else {
|
||||
ret.Type = b.Prog.toTuple(
|
||||
types.NewTuple(
|
||||
types.NewVar(token.NoPos, nil, "", assertedTyp.RawType()),
|
||||
ret.Type.RawType().(*types.Tuple).At(1),
|
||||
),
|
||||
)
|
||||
val0 := conv(b.impl.CreateExtractValue(ret.impl, 0, ""))
|
||||
val1 := b.impl.CreateExtractValue(ret.impl, 1, "")
|
||||
ret.impl = llvm.ConstStruct([]llvm.Value{val0, val1}, false)
|
||||
}
|
||||
}
|
||||
return
|
||||
case vkString:
|
||||
pkg := b.Func.Pkg
|
||||
fnName := "I2String"
|
||||
if commaOk {
|
||||
fnName = "CheckI2String"
|
||||
}
|
||||
fn := pkg.rtFunc(fnName)
|
||||
typ := b.InlineCall(pkg.rtFunc("Basic"), b.Prog.Val(int(kind)))
|
||||
typ := b.InlineCall(pkg.rtFunc("Basic"), b.Prog.Val(int(abi.String)))
|
||||
return b.InlineCall(fn, x, typ)
|
||||
}
|
||||
panic("todo")
|
||||
@@ -1285,11 +1313,4 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
|
||||
panic("todo")
|
||||
}
|
||||
|
||||
// BitCast bit cast expr to type
|
||||
func (b Builder) BitCast(val Expr, typ Type) (ret Expr) {
|
||||
ret.Type = typ
|
||||
ret.impl = b.impl.CreateBitCast(val.impl, typ.ll, "")
|
||||
return
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -109,6 +109,7 @@ type aProgram struct {
|
||||
target *Target
|
||||
td llvm.TargetData
|
||||
// tm llvm.TargetMachine
|
||||
named map[string]llvm.Type
|
||||
|
||||
intType llvm.Type
|
||||
int1Type llvm.Type
|
||||
@@ -164,7 +165,7 @@ func NewProgram(target *Target) Program {
|
||||
// TODO(xsw): Finalize may cause panic, so comment it.
|
||||
ctx.Finalize()
|
||||
*/
|
||||
return &aProgram{ctx: ctx, gocvt: newGoTypes(), target: target, td: td}
|
||||
return &aProgram{ctx: ctx, gocvt: newGoTypes(), target: target, td: td, named: make(map[string]llvm.Type)}
|
||||
}
|
||||
|
||||
// SetPython sets the Python package.
|
||||
|
||||
@@ -189,6 +189,10 @@ func (p Program) tyInt64() llvm.Type {
|
||||
return p.int64Type
|
||||
}
|
||||
|
||||
func (p Program) toTuple(typ *types.Tuple) Type {
|
||||
return &aType{p.toLLVMTuple(typ), rawType{typ}, vkTuple}
|
||||
}
|
||||
|
||||
func (p Program) toType(raw types.Type) Type {
|
||||
typ := rawType{raw}
|
||||
switch t := raw.(type) {
|
||||
@@ -252,7 +256,11 @@ func (p Program) toType(raw types.Type) Type {
|
||||
}
|
||||
|
||||
func (p Program) toLLVMNamedStruct(name string, raw *types.Struct) llvm.Type {
|
||||
if typ, ok := p.named[name]; ok {
|
||||
return typ
|
||||
}
|
||||
t := p.ctx.StructCreateNamed(name)
|
||||
p.named[name] = t
|
||||
fields := p.toLLVMFields(raw)
|
||||
t.StructSetBody(fields, false)
|
||||
return t
|
||||
|
||||
@@ -26,12 +26,14 @@ import (
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
type goTypes struct {
|
||||
typs map[unsafe.Pointer]unsafe.Pointer
|
||||
typs map[unsafe.Pointer]unsafe.Pointer
|
||||
named map[string]*types.Named
|
||||
}
|
||||
|
||||
func newGoTypes() goTypes {
|
||||
typs := make(map[unsafe.Pointer]unsafe.Pointer)
|
||||
return goTypes{typs}
|
||||
named := make(map[string]*types.Named)
|
||||
return goTypes{typs, named}
|
||||
}
|
||||
|
||||
type Background int
|
||||
@@ -116,10 +118,16 @@ func (p goTypes) cvtNamed(t *types.Named) (raw *types.Named, cvt bool) {
|
||||
defer func() {
|
||||
p.typs[unsafe.Pointer(t)] = unsafe.Pointer(raw)
|
||||
}()
|
||||
id := t.String()
|
||||
if named, ok := p.named[id]; ok {
|
||||
return named, false
|
||||
}
|
||||
named := types.NewNamed(t.Obj(), types.Typ[types.Int], nil)
|
||||
p.named[id] = named
|
||||
defer delete(p.named, id)
|
||||
if tund, cvt := p.cvtType(t.Underlying()); cvt {
|
||||
old := t.Obj()
|
||||
obj := types.NewTypeName(old.Pos(), old.Pkg(), old.Name(), nil)
|
||||
return types.NewNamed(obj, tund, nil), true
|
||||
named.SetUnderlying(tund)
|
||||
return named, true
|
||||
}
|
||||
return t, false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user