SetBlockEx: BeforeLast
This commit is contained in:
@@ -26,7 +26,7 @@ import (
|
||||
)
|
||||
|
||||
func TestFromTestgo(t *testing.T) {
|
||||
cltest.FromDir(t, "abiname", "../cl/_testgo", false)
|
||||
cltest.FromDir(t, "strucintf", "../cl/_testgo", false)
|
||||
}
|
||||
|
||||
func TestFromTestpy(t *testing.T) {
|
||||
|
||||
13
ssa/expr.go
13
ssa/expr.go
@@ -525,16 +525,15 @@ func (b Builder) newPhi(t Type, phis []llvm.Value) Phi {
|
||||
}
|
||||
|
||||
// AddIncoming adds incoming values to a phi node.
|
||||
func (p Phi) AddIncoming(b Builder, preds []BasicBlock, f func(i int) Expr) {
|
||||
func (p Phi) AddIncoming(b Builder, preds []BasicBlock, f func(i int, blk BasicBlock) Expr) {
|
||||
bs := llvmPredBlocks(preds)
|
||||
phis := p.phis
|
||||
if phis != nil {
|
||||
vals := make([][]llvm.Value, len(phis))
|
||||
for iblk, blk := range preds {
|
||||
last := blk.last.LastInstruction()
|
||||
b.impl.SetInsertPointBefore(last)
|
||||
val := f(iblk, blk).impl
|
||||
impl := b.impl
|
||||
val := f(iblk).impl
|
||||
b.SetBlockEx(blk, BeforeLast, false)
|
||||
for i := range phis {
|
||||
if iblk == 0 {
|
||||
vals[i] = make([]llvm.Value, len(preds))
|
||||
@@ -548,9 +547,7 @@ func (p Phi) AddIncoming(b Builder, preds []BasicBlock, f func(i int) Expr) {
|
||||
} else {
|
||||
vals := make([]llvm.Value, len(preds))
|
||||
for iblk, blk := range preds {
|
||||
last := blk.last.LastInstruction()
|
||||
b.impl.SetInsertPointBefore(last)
|
||||
vals[iblk] = f(iblk).impl
|
||||
vals[iblk] = f(iblk, blk).impl
|
||||
}
|
||||
p.impl.AddIncoming(vals, bs)
|
||||
}
|
||||
@@ -571,7 +568,7 @@ func (b Builder) Phi(t Type) Phi {
|
||||
phis := createStrucPhis(impl, nil, tund, b.Prog)
|
||||
return b.newPhi(t, phis)
|
||||
default:
|
||||
panic("todo")
|
||||
log.Panicf("todo: %T\n", tund)
|
||||
}
|
||||
phi := llvm.CreatePHI(impl, t.ll)
|
||||
return &aPhi{Expr{phi, t}, nil}
|
||||
|
||||
@@ -88,7 +88,8 @@ func (b Builder) abiStructOf(t *types.Struct) Expr {
|
||||
params := strucAbi.raw.Type.(*types.Signature).Params()
|
||||
tSlice := prog.rawType(params.At(params.Len() - 1).Type().(*types.Slice))
|
||||
fldSlice := b.SliceLit(tSlice, flds...)
|
||||
return b.Call(pkgPath, strucAbi, fldSlice)
|
||||
size := prog.IntVal(prog.SizeOf(typ), prog.Uintptr())
|
||||
return b.Call(strucAbi, pkgPath, size, fldSlice)
|
||||
}
|
||||
|
||||
// func StructField(name string, typ *abi.Type, off uintptr, tag string, exported, embedded bool) abi.StructField
|
||||
@@ -296,21 +297,20 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
|
||||
eq := b.BinOp(token.EQL, tx, tabi)
|
||||
if commaOk {
|
||||
prog := b.Prog
|
||||
t := prog.Tuple(assertedTyp, prog.Bool())
|
||||
t := prog.Struct(assertedTyp, prog.Bool())
|
||||
blks := b.Func.MakeBlocks(3)
|
||||
b.If(eq, blks[0], blks[1])
|
||||
|
||||
b.SetBlockEx(blks[2], AtEnd, false)
|
||||
phi := b.Phi(t)
|
||||
phi.AddIncoming(b, blks[:2], func(i int) Expr {
|
||||
phi.AddIncoming(b, blks[:2], func(i int, blk BasicBlock) Expr {
|
||||
b.SetBlockEx(blk, AtEnd, false)
|
||||
if i == 0 {
|
||||
b.SetBlockEx(blks[0], AtEnd, false)
|
||||
val := b.valFromData(assertedTyp, b.faceData(x.impl))
|
||||
valTrue := aggregateValue(b.impl, t.ll, val.impl, prog.BoolVal(true).impl)
|
||||
b.Jump(blks[2])
|
||||
return Expr{valTrue, t}
|
||||
}
|
||||
b.SetBlockEx(blks[1], AtEnd, false)
|
||||
zero := prog.Zero(assertedTyp)
|
||||
valFalse := aggregateValue(b.impl, t.ll, zero.impl, prog.BoolVal(false).impl)
|
||||
b.Jump(blks[2])
|
||||
|
||||
@@ -19,6 +19,7 @@ package ssa
|
||||
import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/goplus/llgo/ssa/abi"
|
||||
@@ -296,13 +297,13 @@ func (p Program) NewPackage(name, pkgPath string) Package {
|
||||
return ret
|
||||
}
|
||||
|
||||
// Tuple returns a tuple type.
|
||||
func (p Program) Tuple(typs ...Type) Type {
|
||||
// Struct returns a struct type.
|
||||
func (p Program) Struct(typs ...Type) Type {
|
||||
els := make([]*types.Var, len(typs))
|
||||
for i, t := range typs {
|
||||
els[i] = types.NewParam(token.NoPos, nil, "", t.raw.Type)
|
||||
els[i] = types.NewParam(token.NoPos, nil, "_llgo_f"+strconv.Itoa(i), t.raw.Type)
|
||||
}
|
||||
return p.rawType(types.NewTuple(els...))
|
||||
return p.rawType(types.NewStruct(els, nil))
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -80,6 +80,7 @@ type InsertPoint int
|
||||
const (
|
||||
AtEnd InsertPoint = iota
|
||||
AtStart
|
||||
BeforeLast
|
||||
afterInit
|
||||
)
|
||||
|
||||
@@ -93,6 +94,8 @@ func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint, setBlk bool) Builde
|
||||
b.impl.SetInsertPointAtEnd(blk.last)
|
||||
case AtStart:
|
||||
b.impl.SetInsertPointBefore(blk.first.FirstInstruction())
|
||||
case BeforeLast:
|
||||
b.impl.SetInsertPointBefore(blk.last.LastInstruction())
|
||||
case afterInit:
|
||||
b.impl.SetInsertPointBefore(instrAfterInit(blk.first))
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user