cl: _testdata/printf: almost done

This commit is contained in:
xushiwei
2024-04-21 15:12:57 +08:00
parent 8f31e4a6d3
commit 4641cb11eb
12 changed files with 305 additions and 265 deletions

View File

@@ -38,9 +38,8 @@ type context struct {
prog llssa.Program
pkg llssa.Package
fn llssa.Function
fns map[*ssa.Function]llssa.Function
glbs map[*ssa.Global]llssa.Global
bvals map[ssa.Value]llssa.Expr // block values
inits []func()
}
func (p *context) compileType(pkg llssa.Package, member *ssa.Type) {
@@ -48,41 +47,28 @@ func (p *context) compileType(pkg llssa.Package, member *ssa.Type) {
}
// Global variable.
func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) llssa.Global {
if g, ok := p.glbs[gbl]; ok {
return g
}
func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
g := pkg.NewVar(gbl.Name(), gbl.Type())
g.Init(p.prog.Null(g.Type))
p.glbs[gbl] = g
return g
}
func (p *context) compileFunc(pkg llssa.Package, f *ssa.Function) llssa.Function {
if fn, ok := p.fns[f]; ok {
return fn
}
fn := p.doCompileFunc(pkg, f)
p.fns[f] = fn
return fn
}
func (p *context) doCompileFunc(pkg llssa.Package, f *ssa.Function) (fn llssa.Function) {
fn = pkg.NewFunc(f.Name(), f.Signature)
p.fn = fn
defer func() {
p.fn = nil
}()
nblk := len(f.Blocks)
if nblk == 0 { // external function
return
}
fn.MakeBlocks(nblk)
b := fn.NewBuilder()
for _, block := range f.Blocks {
p.compileBlock(b, block)
}
return
func (p *context) compileFunc(pkg llssa.Package, f *ssa.Function) {
fn := pkg.NewFunc(f.Name(), f.Signature)
p.inits = append(p.inits, func() {
p.fn = fn
defer func() {
p.fn = nil
}()
nblk := len(f.Blocks)
if nblk == 0 { // external function
return
}
fn.MakeBlocks(nblk)
b := fn.NewBuilder()
for _, block := range f.Blocks {
p.compileBlock(b, block)
}
})
}
func (p *context) compileBlock(b llssa.Builder, block *ssa.BasicBlock) llssa.BasicBlock {
@@ -101,10 +87,12 @@ func (p *context) compileInstrAndValue(b llssa.Builder, iv instrAndValue) (ret l
}
switch v := iv.(type) {
case *ssa.Call:
call := v.Call
fn := p.compileValue(b, call.Value)
args := p.compileValues(b, call.Args)
ret = b.Call(fn, args...)
if false {
call := v.Call
fn := p.compileValue(b, call.Value)
args := p.compileValues(b, call.Args)
ret = b.Call(fn, args...)
}
case *ssa.BinOp:
x := p.compileValue(b, v.X)
y := p.compileValue(b, v.Y)
@@ -112,6 +100,13 @@ func (p *context) compileInstrAndValue(b llssa.Builder, iv instrAndValue) (ret l
case *ssa.UnOp:
x := p.compileValue(b, v.X)
ret = b.UnOp(v.Op, x)
case *ssa.IndexAddr:
x := p.compileValue(b, v.X)
idx := p.compileValue(b, v.Index)
ret = b.IndexAddr(x, idx)
case *ssa.Alloc:
t := v.Type()
ret = b.Alloc(p.prog.Type(t), v.Heap)
default:
panic(fmt.Sprintf("compileInstrAndValue: unknown instr - %T\n", iv))
}
@@ -168,13 +163,14 @@ func (p *context) compileValue(b llssa.Builder, v ssa.Value) llssa.Expr {
}
}
case *ssa.Function:
fn := p.compileFunc(p.pkg, v)
fn := p.pkg.FuncOf(v.Name())
return fn.Expr
case *ssa.Global:
g := p.compileGlobal(p.pkg, v)
g := p.pkg.VarOf(v.Name())
return g.Expr
case *ssa.Const:
return b.Const(v.Value, v.Type())
t := v.Type()
return b.Const(v.Value, p.prog.Type(t))
}
panic(fmt.Sprintf("compileValue: unknown value - %T\n", v))
}
@@ -215,8 +211,6 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, conf *Config) (ret llssa.P
ctx := &context{
prog: prog,
pkg: ret,
fns: make(map[*ssa.Function]llssa.Function),
glbs: make(map[*ssa.Global]llssa.Global),
}
for _, m := range members {
member := m.val
@@ -233,6 +227,9 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, conf *Config) (ret llssa.P
ctx.compileGlobal(ret, member)
}
}
for _, ini := range ctx.inits {
ini()
}
return
}