llgo/ssa: DeferAlways/DeferInCond/DeferInLoop

This commit is contained in:
xushiwei
2024-06-03 02:43:04 +08:00
parent 6ac6fb0192
commit cfca98512a
4 changed files with 63 additions and 22 deletions

View File

@@ -148,8 +148,11 @@ type context struct {
loaded map[*types.Package]*pkgInfo // loaded packages
bvals map[ssa.Value]llssa.Expr // block values
vargs map[*ssa.Alloc][]llssa.Expr // varargs
inits []func()
phis []func()
blkInfos []blockInfo
inits []func()
phis []func()
}
func (p *context) inMain(instr ssa.Instruction) bool {
@@ -277,10 +280,16 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
for i, block := range f.Blocks {
off[i] = p.compilePhis(b, block)
}
for i, block := range f.Blocks {
p.blkInfos = blockInfos(f.Blocks)
i := 0
for {
block := f.Blocks[i]
doMainInit := (i == 0 && name == "main")
doModInit := (i == 1 && f.Name() == "init" && sig.Recv() == nil)
p.compileBlock(b, block, off[i], doMainInit, doModInit)
if i = p.blkInfos[i].next; i < 0 {
break
}
}
for _, phi := range p.phis {
phi()
@@ -291,6 +300,24 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Fun
return fn, nil, goFunc
}
type blockInfo struct {
kind llssa.DoAction
next int
}
func blockInfos(blks []*ssa.BasicBlock) []blockInfo {
n := len(blks)
infos := make([]blockInfo, n)
for i := range blks {
next := i + 1
if next >= n {
next = -1
}
infos[i] = blockInfo{kind: llssa.DeferInCond, next: next}
}
return infos
}
// funcOf returns a function by name and set ftype = goFunc, cFunc, etc.
// or returns nil and set ftype = llgoCstr, llgoAlloca, llgoUnreachable, etc.
func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObjRef, ftype int) {
@@ -516,7 +543,7 @@ func (p *context) compilePhis(b llssa.Builder, block *ssa.BasicBlock) int {
for n < ninstr && isPhi(block.Instrs[n]) {
n++
}
rets := make([]llssa.Expr, n)
rets := make([]llssa.Expr, n) // TODO(xsw): check to remove this
for i := 0; i < n; i++ {
iv := block.Instrs[i].(*ssa.Phi)
rets[i] = p.compilePhi(b, iv)
@@ -798,7 +825,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
val := p.compileValue(b, v.Value)
b.MapUpdate(m, key, val)
case *ssa.Defer:
p.call(b, llssa.Defer, &v.Call)
p.call(b, p.blkInfos[v.Block().Index].kind, &v.Call)
case *ssa.Go:
p.call(b, llssa.Go, &v.Call)
case *ssa.RunDefers: