llgo/ssa.Phi: AddIncoming fix
This commit is contained in:
@@ -274,7 +274,7 @@ func (p Function) NewBuilder() Builder {
|
||||
b := prog.ctx.NewBuilder()
|
||||
// TODO(xsw): Finalize may cause panic, so comment it.
|
||||
// b.Finalize()
|
||||
return &aBuilder{b, p, p.Pkg, prog}
|
||||
return &aBuilder{b, nil, p, p.Pkg, prog}
|
||||
}
|
||||
|
||||
// HasBody reports whether the function has a body.
|
||||
@@ -287,7 +287,7 @@ func (p Function) HasBody() bool {
|
||||
func (p Function) MakeBody(nblk int) Builder {
|
||||
p.MakeBlocks(nblk)
|
||||
b := p.NewBuilder()
|
||||
b.impl.SetInsertPointAtEnd(p.blks[0].impl)
|
||||
b.impl.SetInsertPointAtEnd(p.blks[0].last)
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ func (p Function) MakeBlocks(nblk int) []BasicBlock {
|
||||
func (p Function) addBlock(idx int) BasicBlock {
|
||||
label := "_llgo_" + strconv.Itoa(idx)
|
||||
blk := llvm.AddBasicBlock(p.impl, label)
|
||||
ret := &aBasicBlock{blk, p, idx}
|
||||
ret := &aBasicBlock{blk, blk, p, idx}
|
||||
p.blks = append(p.blks, ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
20
ssa/expr.go
20
ssa/expr.go
@@ -517,10 +517,10 @@ func llvmDelayValues(f func(i int) Expr, n int) []llvm.Value {
|
||||
return ret
|
||||
}
|
||||
|
||||
func llvmBlocks(bblks []BasicBlock) []llvm.BasicBlock {
|
||||
ret := make([]llvm.BasicBlock, len(bblks))
|
||||
for i, v := range bblks {
|
||||
ret[i] = v.impl
|
||||
func llvmPredBlocks(preds []BasicBlock) []llvm.BasicBlock {
|
||||
ret := make([]llvm.BasicBlock, len(preds))
|
||||
for i, v := range preds {
|
||||
ret[i] = v.last
|
||||
}
|
||||
return ret
|
||||
}
|
||||
@@ -531,24 +531,24 @@ type Phi struct {
|
||||
}
|
||||
|
||||
// AddIncoming adds incoming values to a phi node.
|
||||
func (p Phi) AddIncoming(b Builder, bblks []BasicBlock, f func(i int) Expr) {
|
||||
bs := llvmBlocks(bblks)
|
||||
func (p Phi) AddIncoming(b Builder, preds []BasicBlock, f func(i int) Expr) {
|
||||
bs := llvmPredBlocks(preds)
|
||||
if p.kind != vkPhisExpr { // normal phi node
|
||||
vs := llvmDelayValues(f, len(bblks))
|
||||
vs := llvmDelayValues(f, len(preds))
|
||||
p.impl.AddIncoming(vs, bs)
|
||||
return
|
||||
}
|
||||
e := p.raw.Type.(*phisExprTy)
|
||||
phis := e.phis
|
||||
vals := make([][]llvm.Value, len(phis))
|
||||
for iblk, blk := range bblks {
|
||||
last := blk.impl.LastInstruction()
|
||||
for iblk, blk := range preds {
|
||||
last := blk.last.LastInstruction()
|
||||
b.impl.SetInsertPointBefore(last)
|
||||
impl := b.impl
|
||||
val := f(iblk).impl
|
||||
for i := range phis {
|
||||
if iblk == 0 {
|
||||
vals[i] = make([]llvm.Value, len(bblks))
|
||||
vals[i] = make([]llvm.Value, len(preds))
|
||||
}
|
||||
vals[i][iblk] = llvm.CreateExtractValue(impl, val, i)
|
||||
}
|
||||
|
||||
@@ -61,13 +61,14 @@ func (b Builder) abiStruct(t *types.Struct) Expr {
|
||||
eq := b.BinOp(token.EQL, b.Load(expr), b.Prog.Null(expr.Type))
|
||||
blks = b.Func.MakeBlocks(2)
|
||||
b.If(eq, blks[0], blks[1])
|
||||
b.SetBlock(blks[0])
|
||||
b.SetBlockEx(blks[0], AtEnd, false)
|
||||
}
|
||||
tabi := b.structOf(t)
|
||||
b.Store(expr, tabi)
|
||||
if pub {
|
||||
b.Jump(blks[1])
|
||||
b.SetBlock(blks[1])
|
||||
b.SetBlockEx(blks[1], AtEnd, false)
|
||||
b.blk.last = blks[1].last
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -279,9 +280,10 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
|
||||
}
|
||||
blks := b.Func.MakeBlocks(2)
|
||||
b.If(eq, blks[0], blks[1])
|
||||
b.SetBlock(blks[1])
|
||||
b.SetBlockEx(blks[1], AtEnd, false)
|
||||
b.Panic(b.Str("type assertion failed"))
|
||||
b.SetBlock(blks[0])
|
||||
b.SetBlockEx(blks[0], AtEnd, false)
|
||||
b.blk.last = blks[0].last
|
||||
return b.valFromData(assertedTyp, b.faceData(x.impl))
|
||||
}
|
||||
|
||||
|
||||
@@ -559,7 +559,7 @@ func (p Package) AfterInit(b Builder, ret BasicBlock) {
|
||||
doAbiInit := len(p.abiini) > 0
|
||||
doPyLoadModSyms := p.pyHasModSyms()
|
||||
if doAbiInit || doPyLoadModSyms {
|
||||
b.SetBlockEx(ret, afterInit)
|
||||
b.SetBlockEx(ret, afterInit, false)
|
||||
if doAbiInit {
|
||||
sigAbiInit := types.NewSignatureType(nil, nil, nil, nil, nil, false)
|
||||
fn := p.NewFunc(p.abi.Pkg+".init$abi", sigAbiInit, InC)
|
||||
@@ -743,7 +743,7 @@ func (p Program) tyGetAttrString() *types.Signature {
|
||||
func (p Package) PyInit() bool {
|
||||
if fn := p.FuncOf("main"); fn != nil {
|
||||
b := fn.NewBuilder()
|
||||
b.SetBlockEx(fn.Block(0), AtStart).callPyInit()
|
||||
b.SetBlockEx(fn.Block(0), AtStart, false).callPyInit()
|
||||
b.Dispose()
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func TestSetBlockEx(t *testing.T) {
|
||||
}()
|
||||
fn := &aFunction{}
|
||||
b := &aBuilder{Func: fn}
|
||||
b.SetBlockEx(&aBasicBlock{fn: fn}, -1)
|
||||
b.SetBlockEx(&aBasicBlock{fn: fn}, -1, false)
|
||||
}
|
||||
|
||||
func TestSetPython(t *testing.T) {
|
||||
|
||||
@@ -29,9 +29,10 @@ import (
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
type aBasicBlock struct {
|
||||
impl llvm.BasicBlock
|
||||
fn Function
|
||||
idx int
|
||||
first llvm.BasicBlock
|
||||
last llvm.BasicBlock
|
||||
fn Function
|
||||
idx int
|
||||
}
|
||||
|
||||
// BasicBlock represents a basic block in a function.
|
||||
@@ -51,6 +52,7 @@ func (p BasicBlock) Index() int {
|
||||
|
||||
type aBuilder struct {
|
||||
impl llvm.Builder
|
||||
blk BasicBlock
|
||||
Func Function
|
||||
Pkg Package
|
||||
Prog Program
|
||||
@@ -64,12 +66,12 @@ func (b Builder) Dispose() {
|
||||
b.impl.Dispose()
|
||||
}
|
||||
|
||||
// SetBlock means SetBlockEx(blk, AtEnd).
|
||||
// SetBlock means SetBlockEx(blk, AtEnd, true).
|
||||
func (b Builder) SetBlock(blk BasicBlock) Builder {
|
||||
if debugInstr {
|
||||
log.Printf("Block _llgo_%v:\n", blk.idx)
|
||||
}
|
||||
b.SetBlockEx(blk, AtEnd)
|
||||
b.SetBlockEx(blk, AtEnd, true)
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -82,20 +84,23 @@ const (
|
||||
)
|
||||
|
||||
// SetBlockEx sets blk as current basic block and pos as its insert point.
|
||||
func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint) Builder {
|
||||
func (b Builder) SetBlockEx(blk BasicBlock, pos InsertPoint, setBlk bool) Builder {
|
||||
if b.Func != blk.fn {
|
||||
panic("mismatched function")
|
||||
}
|
||||
switch pos {
|
||||
case AtEnd:
|
||||
b.impl.SetInsertPointAtEnd(blk.impl)
|
||||
b.impl.SetInsertPointAtEnd(blk.last)
|
||||
case AtStart:
|
||||
b.impl.SetInsertPointBefore(blk.impl.FirstInstruction())
|
||||
b.impl.SetInsertPointBefore(blk.first.FirstInstruction())
|
||||
case afterInit:
|
||||
b.impl.SetInsertPointBefore(instrAfterInit(blk.impl))
|
||||
b.impl.SetInsertPointBefore(instrAfterInit(blk.first))
|
||||
default:
|
||||
panic("SetBlockEx: invalid pos")
|
||||
}
|
||||
if setBlk {
|
||||
b.blk = blk
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
@@ -184,7 +189,7 @@ func (b Builder) Jump(jmpb BasicBlock) {
|
||||
if debugInstr {
|
||||
log.Printf("Jump _llgo_%v\n", jmpb.idx)
|
||||
}
|
||||
b.impl.CreateBr(jmpb.impl)
|
||||
b.impl.CreateBr(jmpb.first)
|
||||
}
|
||||
|
||||
// If emits an if instruction.
|
||||
@@ -195,7 +200,7 @@ func (b Builder) If(cond Expr, thenb, elseb BasicBlock) {
|
||||
if debugInstr {
|
||||
log.Printf("If %v, _llgo_%v, _llgo_%v\n", cond.impl, thenb.idx, elseb.idx)
|
||||
}
|
||||
b.impl.CreateCondBr(cond.impl, thenb.impl, elseb.impl)
|
||||
b.impl.CreateCondBr(cond.impl, thenb.first, elseb.first)
|
||||
}
|
||||
|
||||
// The MapUpdate instruction updates the association of Map[Key] to
|
||||
|
||||
Reference in New Issue
Block a user