cl: _testcgo/strlen

This commit is contained in:
xushiwei
2024-04-26 02:40:36 +08:00
parent 43ae7a23b2
commit a3d6a94600
5 changed files with 88 additions and 15 deletions

View File

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

View File

@@ -25,6 +25,7 @@ import (
"log"
"os"
"sort"
"strings"
llssa "github.com/goplus/llgo/ssa"
"golang.org/x/tools/go/ssa"
@@ -57,7 +58,7 @@ func SetDebug(dbgFlags dbgFlags) {
const (
fnNormal = iota
fnHasVArg
fnUnsafeInit
fnIgnore
)
func funcKind(vfn ssa.Value) int {
@@ -65,8 +66,8 @@ func funcKind(vfn ssa.Value) int {
params := fn.Signature.Params()
n := params.Len()
if n == 0 {
if fn.Name() == "init" && fn.Pkg.Pkg.Path() == "unsafe" {
return fnUnsafeInit
if fn.Name() == "init" && ignorePkgInit(fn.Pkg.Pkg.Path()) {
return fnIgnore
}
} else {
last := params.At(n - 1)
@@ -78,6 +79,32 @@ func funcKind(vfn ssa.Value) int {
return fnNormal
}
func ignorePkgInit(pkgPath string) bool {
switch pkgPath {
case "unsafe", "syscall", "runtime/cgo":
return true
}
return false
}
func ignoreFunc(name string, fn *ssa.Function) bool {
/* TODO(xsw): confirm this is not needed more
if name == "unsafe.init" {
return true
}
*/
fnName := fn.Name()
if strings.HasPrefix(fnName, "_Cgo_") {
return true
}
const runtime = "runtime"
if strings.HasPrefix(name, runtime) {
left := name[len(runtime):]
return strings.HasPrefix(left, ".cgo") || strings.HasPrefix(left, "/cgo")
}
return false
}
// -----------------------------------------------------------------------------
type none = struct{}
@@ -137,14 +164,12 @@ func (p *context) compileGlobal(pkg llssa.Package, gbl *ssa.Global) {
func (p *context) compileFunc(pkg llssa.Package, pkgTypes *types.Package, f *ssa.Function) {
sig := f.Signature
name := p.funcName(pkgTypes, f)
/* TODO(xsw): confirm this is not needed more
if name == "unsafe.init" {
return
}
*/
if debugInstr {
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig)
}
if ignoreFunc(name, f) {
return
}
fn := pkg.NewFunc(name, sig)
p.inits = append(p.inits, func() {
p.fn = fn
@@ -229,7 +254,7 @@ func (p *context) compileInstrAndValue(b llssa.Builder, iv instrAndValue) (ret l
call := v.Call
cv := call.Value
kind := funcKind(cv)
if kind == fnUnsafeInit {
if kind == fnIgnore {
return
}
if debugGoSSA {

View File

@@ -27,8 +27,12 @@ func testCompile(t *testing.T, src, expected string) {
cltest.TestCompileEx(t, src, "foo.go", expected)
}
func TestFromTestcgo(t *testing.T) {
cltest.FromDir(t, "strlen", "./_testcgo", true)
}
func TestFromTestdata(t *testing.T) {
cltest.FromDir(t, "apkg", "./_testdata", false)
cltest.FromDir(t, "", "./_testdata", false)
}
func TestVar(t *testing.T) {

View File

@@ -120,10 +120,11 @@ func fullName(pkg *types.Package, name string) string {
// method: (pkg.T).name
func funcName(pkg *types.Package, fn *ssa.Function) string {
sig := fn.Signature
name := fn.Name()
if recv := sig.Recv(); recv != nil {
return "(" + recv.Type().String() + ")." + fn.Name()
return "(" + recv.Type().String() + ")." + name
}
ret := fullName(pkg, fn.Name())
ret := fullName(pkg, name)
if ret == "main.main" {
ret = "main"
}

View File

@@ -22,6 +22,7 @@ import (
"github.com/goplus/llgo/cl"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"
llssa "github.com/goplus/llgo/ssa"
)
@@ -40,10 +41,11 @@ func GenFromFile(inFile string) string {
initial, err := packages.Load(cfg, inFile)
check(err)
_, pkgs := ssautil.AllPackages(initial, ssa.SanityCheckFunctions)
pkg := initial[0]
fset := pkg.Fset
ssaProg := ssa.NewProgram(fset, ssa.SanityCheckFunctions)
ssaPkg := ssaProg.CreatePackage(pkg.Types, pkg.Syntax, pkg.TypesInfo, true)
ssaPkg := pkgs[0]
ssaPkg.Build()
prog := llssa.NewProgram(nil)
ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax)