compileBlock: support pyModule init
This commit is contained in:
@@ -216,7 +216,7 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) llssa.Func
|
|||||||
if ftype != goFunc {
|
if ftype != goFunc {
|
||||||
if ftype == pyFunc {
|
if ftype == pyFunc {
|
||||||
// TODO(xsw): pyMod == ""
|
// TODO(xsw): pyMod == ""
|
||||||
fn := "__llgo_py." + p.pyMod + "." + name
|
fn := pysymPrefix + p.pyMod + "." + name
|
||||||
pkg.NewVar(fn, types.Typ[types.Int], llssa.InC)
|
pkg.NewVar(fn, types.Typ[types.Int], llssa.InC)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -250,6 +250,7 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) llssa.Func
|
|||||||
}
|
}
|
||||||
if nblk := len(f.Blocks); nblk > 0 {
|
if nblk := len(f.Blocks); nblk > 0 {
|
||||||
fn.MakeBlocks(nblk) // to set fn.HasBody() = true
|
fn.MakeBlocks(nblk) // to set fn.HasBody() = true
|
||||||
|
isPyMod := p.pyMod != ""
|
||||||
p.inits = append(p.inits, func() {
|
p.inits = append(p.inits, func() {
|
||||||
p.fn = fn
|
p.fn = fn
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -269,7 +270,9 @@ func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) llssa.Func
|
|||||||
off[i] = p.compilePhis(b, block)
|
off[i] = p.compilePhis(b, block)
|
||||||
}
|
}
|
||||||
for i, block := range f.Blocks {
|
for i, block := range f.Blocks {
|
||||||
p.compileBlock(b, block, off[i], i == 0 && name == "main")
|
doInit := (i == 0 && name == "main")
|
||||||
|
doPyModInit := (isPyMod && i == 1 && f.Name() == "init" && sig.Recv() == nil)
|
||||||
|
p.compileBlock(b, block, off[i], doInit, doPyModInit)
|
||||||
}
|
}
|
||||||
for _, phi := range p.phis {
|
for _, phi := range p.phis {
|
||||||
phi()
|
phi()
|
||||||
@@ -314,9 +317,16 @@ func (p *context) funcOf(fn *ssa.Function) (ret llssa.Function, ftype int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doInit bool) llssa.BasicBlock {
|
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, doInit, pyModInit bool) llssa.BasicBlock {
|
||||||
ret := p.fn.Block(block.Index)
|
var last int
|
||||||
|
var instrs []ssa.Instruction
|
||||||
|
var ret = p.fn.Block(block.Index)
|
||||||
b.SetBlock(ret)
|
b.SetBlock(ret)
|
||||||
|
if pyModInit {
|
||||||
|
last = len(block.Instrs) - 1
|
||||||
|
instrs = block.Instrs[n:last]
|
||||||
|
} else {
|
||||||
|
instrs = block.Instrs[n:]
|
||||||
if doInit {
|
if doInit {
|
||||||
prog := p.prog
|
prog := p.prog
|
||||||
pkg := p.pkg
|
pkg := p.pkg
|
||||||
@@ -330,9 +340,23 @@ func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock, n int, do
|
|||||||
callRuntimeInit(b, pkg)
|
callRuntimeInit(b, pkg)
|
||||||
b.Call(pkg.FuncOf("main.init").Expr)
|
b.Call(pkg.FuncOf("main.init").Expr)
|
||||||
}
|
}
|
||||||
for _, instr := range block.Instrs[n:] {
|
}
|
||||||
|
for _, instr := range instrs {
|
||||||
p.compileInstr(b, instr)
|
p.compileInstr(b, instr)
|
||||||
}
|
}
|
||||||
|
if pyModInit {
|
||||||
|
jump := block.Instrs[last].(*ssa.Jump)
|
||||||
|
jumpTo := p.jumpTo(jump)
|
||||||
|
modName := pysymPrefix + p.pyMod
|
||||||
|
modPtr := p.pkg.NewPyModVar(modName).Expr
|
||||||
|
mod := b.Load(modPtr)
|
||||||
|
cond := b.BinOp(token.NEQ, mod, b.Prog.Null(mod.Type))
|
||||||
|
newBlk := p.fn.MakeBlock()
|
||||||
|
b.If(cond, jumpTo, newBlk)
|
||||||
|
b.SetBlock(newBlk)
|
||||||
|
// TODO(xsw): pyModInit
|
||||||
|
b.Jump(jumpTo)
|
||||||
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,6 +681,12 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *context) jumpTo(v *ssa.Jump) llssa.BasicBlock {
|
||||||
|
fn := p.fn
|
||||||
|
succs := v.Block().Succs
|
||||||
|
return fn.Block(succs[0].Index)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
||||||
if iv, ok := instr.(instrOrValue); ok {
|
if iv, ok := instr.(instrOrValue); ok {
|
||||||
p.compileInstrOrValue(b, iv, false)
|
p.compileInstrOrValue(b, iv, false)
|
||||||
@@ -680,9 +710,7 @@ func (p *context) compileInstr(b llssa.Builder, instr ssa.Instruction) {
|
|||||||
val := p.compileValue(b, v.Val)
|
val := p.compileValue(b, v.Val)
|
||||||
b.Store(ptr, val)
|
b.Store(ptr, val)
|
||||||
case *ssa.Jump:
|
case *ssa.Jump:
|
||||||
fn := p.fn
|
jmpb := p.jumpTo(v)
|
||||||
succs := v.Block().Succs
|
|
||||||
jmpb := fn.Block(succs[0].Index)
|
|
||||||
b.Jump(jmpb)
|
b.Jump(jmpb)
|
||||||
case *ssa.Return:
|
case *ssa.Return:
|
||||||
var results []llssa.Expr
|
var results []llssa.Expr
|
||||||
|
|||||||
@@ -402,6 +402,10 @@ func pkgKindByPath(pkgPath string) int {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const (
|
||||||
|
pysymPrefix = "__llgo_py."
|
||||||
|
)
|
||||||
|
|
||||||
func (p *context) initPyModule() {
|
func (p *context) initPyModule() {
|
||||||
if kind, mod := pkgKindByScope(p.goTyps.Scope()); kind == PkgPyModule {
|
if kind, mod := pkgKindByScope(p.goTyps.Scope()); kind == PkgPyModule {
|
||||||
p.pyMod = mod
|
p.pyMod = mod
|
||||||
|
|||||||
22
ssa/decl.go
22
ssa/decl.go
@@ -212,19 +212,29 @@ func (p Function) MakeBody(nblk int) Builder {
|
|||||||
|
|
||||||
// MakeBlocks creates nblk basic blocks for the function.
|
// MakeBlocks creates nblk basic blocks for the function.
|
||||||
func (p Function) MakeBlocks(nblk int) []BasicBlock {
|
func (p Function) MakeBlocks(nblk int) []BasicBlock {
|
||||||
if p.blks == nil {
|
n := len(p.blks)
|
||||||
|
if n == 0 {
|
||||||
p.blks = make([]BasicBlock, 0, nblk)
|
p.blks = make([]BasicBlock, 0, nblk)
|
||||||
}
|
}
|
||||||
n := len(p.blks)
|
|
||||||
f := p.impl
|
|
||||||
for i := 0; i < nblk; i++ {
|
for i := 0; i < nblk; i++ {
|
||||||
label := "_llgo_" + strconv.Itoa(i)
|
p.addBlock(n + i)
|
||||||
blk := llvm.AddBasicBlock(f, label)
|
|
||||||
p.blks = append(p.blks, &aBasicBlock{blk, p, n + i})
|
|
||||||
}
|
}
|
||||||
return p.blks[n:]
|
return p.blks[n:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Function) addBlock(idx int) BasicBlock {
|
||||||
|
label := "_llgo_" + strconv.Itoa(idx)
|
||||||
|
blk := llvm.AddBasicBlock(p.impl, label)
|
||||||
|
ret := &aBasicBlock{blk, p, idx}
|
||||||
|
p.blks = append(p.blks, ret)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeBlock creates a new basic block for the function.
|
||||||
|
func (p Function) MakeBlock() BasicBlock {
|
||||||
|
return p.addBlock(len(p.blks))
|
||||||
|
}
|
||||||
|
|
||||||
// Block returns the ith basic block of the function.
|
// Block returns the ith basic block of the function.
|
||||||
func (p Function) Block(idx int) BasicBlock {
|
func (p Function) Block(idx int) BasicBlock {
|
||||||
return p.blks[idx]
|
return p.blks[idx]
|
||||||
|
|||||||
@@ -327,6 +327,13 @@ func (p Package) NewConst(name string, val constant.Value) NamedConst {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// NewPyModVar creates a new global variable for a Python module.
|
||||||
|
func (p Package) NewPyModVar(name string) Global {
|
||||||
|
ret := p.NewVar(name, types.NewPointer(types.Typ[types.Int]), InC)
|
||||||
|
ret.impl.SetLinkage(llvm.LinkOnceAnyLinkage)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
// NewVar creates a new global variable.
|
// NewVar creates a new global variable.
|
||||||
func (p Package) NewVar(name string, typ types.Type, bg Background) Global {
|
func (p Package) NewVar(name string, typ types.Type, bg Background) Global {
|
||||||
t := p.Prog.Type(typ, bg)
|
t := p.Prog.Type(typ, bg)
|
||||||
|
|||||||
Reference in New Issue
Block a user