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

12
cl/_testdata/printf/in.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import _ "unsafe"
//go:linkname printf _printf
func printf(format *int8, __llgo_va_list ...any)
var hello = [...]int8{'H', 'e', 'l', 'l', 'o', '\n', 0}
func main() {
printf(&hello[0])
}

View File

@@ -0,0 +1,32 @@
; ModuleID = 'main'
source_filename = "main"
@"init$guard" = global ptr null
@hello = global ptr null
define void @init() {
_llgo_0:
%0 = load i1, ptr @"init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1
_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"init$guard", align 1
store i8 72, ptr @hello, align 1
store i8 101, ptr getelementptr inbounds (i8, ptr @hello, i64 1), align 1
store i8 108, ptr getelementptr inbounds (i8, ptr @hello, i64 2), align 1
store i8 108, ptr getelementptr inbounds (i8, ptr @hello, i64 3), align 1
store i8 111, ptr getelementptr inbounds (i8, ptr @hello, i64 4), align 1
store i8 10, ptr getelementptr inbounds (i8, ptr @hello, i64 5), align 1
store i8 0, ptr getelementptr inbounds (i8, ptr @hello, i64 6), align 1
br label %_llgo_2
_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
declare void @printf(ptr, ...)
define void @main() {
_llgo_0:
ret void
}

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
}

View File

@@ -34,7 +34,12 @@ import (
)
func TestFromTestdata(t *testing.T) {
testFromDir(t, "", "./_testdata")
testFromDir(t, "printf", "./_testdata")
}
func init() {
llssa.Initialize(llssa.InitAll)
llssa.SetDebug(llssa.DbgFlagAll)
}
func testFromDir(t *testing.T, sel, relDir string) {