cl: _testcgo/strlen
This commit is contained in:
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
llssa "github.com/goplus/llgo/ssa"
|
llssa "github.com/goplus/llgo/ssa"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
@@ -57,7 +58,7 @@ func SetDebug(dbgFlags dbgFlags) {
|
|||||||
const (
|
const (
|
||||||
fnNormal = iota
|
fnNormal = iota
|
||||||
fnHasVArg
|
fnHasVArg
|
||||||
fnUnsafeInit
|
fnIgnore
|
||||||
)
|
)
|
||||||
|
|
||||||
func funcKind(vfn ssa.Value) int {
|
func funcKind(vfn ssa.Value) int {
|
||||||
@@ -65,8 +66,8 @@ func funcKind(vfn ssa.Value) int {
|
|||||||
params := fn.Signature.Params()
|
params := fn.Signature.Params()
|
||||||
n := params.Len()
|
n := params.Len()
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
if fn.Name() == "init" && fn.Pkg.Pkg.Path() == "unsafe" {
|
if fn.Name() == "init" && ignorePkgInit(fn.Pkg.Pkg.Path()) {
|
||||||
return fnUnsafeInit
|
return fnIgnore
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
last := params.At(n - 1)
|
last := params.At(n - 1)
|
||||||
@@ -78,6 +79,32 @@ func funcKind(vfn ssa.Value) int {
|
|||||||
return fnNormal
|
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{}
|
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) {
|
func (p *context) compileFunc(pkg llssa.Package, pkgTypes *types.Package, f *ssa.Function) {
|
||||||
sig := f.Signature
|
sig := f.Signature
|
||||||
name := p.funcName(pkgTypes, f)
|
name := p.funcName(pkgTypes, f)
|
||||||
/* TODO(xsw): confirm this is not needed more
|
|
||||||
if name == "unsafe.init" {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig)
|
log.Println("==> NewFunc", name, "type:", sig.Recv(), sig)
|
||||||
}
|
}
|
||||||
|
if ignoreFunc(name, f) {
|
||||||
|
return
|
||||||
|
}
|
||||||
fn := pkg.NewFunc(name, sig)
|
fn := pkg.NewFunc(name, sig)
|
||||||
p.inits = append(p.inits, func() {
|
p.inits = append(p.inits, func() {
|
||||||
p.fn = fn
|
p.fn = fn
|
||||||
@@ -229,7 +254,7 @@ func (p *context) compileInstrAndValue(b llssa.Builder, iv instrAndValue) (ret l
|
|||||||
call := v.Call
|
call := v.Call
|
||||||
cv := call.Value
|
cv := call.Value
|
||||||
kind := funcKind(cv)
|
kind := funcKind(cv)
|
||||||
if kind == fnUnsafeInit {
|
if kind == fnIgnore {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if debugGoSSA {
|
if debugGoSSA {
|
||||||
|
|||||||
@@ -27,8 +27,12 @@ func testCompile(t *testing.T, src, expected string) {
|
|||||||
cltest.TestCompileEx(t, src, "foo.go", expected)
|
cltest.TestCompileEx(t, src, "foo.go", expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFromTestcgo(t *testing.T) {
|
||||||
|
cltest.FromDir(t, "strlen", "./_testcgo", true)
|
||||||
|
}
|
||||||
|
|
||||||
func TestFromTestdata(t *testing.T) {
|
func TestFromTestdata(t *testing.T) {
|
||||||
cltest.FromDir(t, "apkg", "./_testdata", false)
|
cltest.FromDir(t, "", "./_testdata", false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVar(t *testing.T) {
|
func TestVar(t *testing.T) {
|
||||||
|
|||||||
@@ -120,10 +120,11 @@ func fullName(pkg *types.Package, name string) string {
|
|||||||
// method: (pkg.T).name
|
// method: (pkg.T).name
|
||||||
func funcName(pkg *types.Package, fn *ssa.Function) string {
|
func funcName(pkg *types.Package, fn *ssa.Function) string {
|
||||||
sig := fn.Signature
|
sig := fn.Signature
|
||||||
|
name := fn.Name()
|
||||||
if recv := sig.Recv(); recv != nil {
|
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" {
|
if ret == "main.main" {
|
||||||
ret = "main"
|
ret = "main"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"github.com/goplus/llgo/cl"
|
"github.com/goplus/llgo/cl"
|
||||||
"golang.org/x/tools/go/packages"
|
"golang.org/x/tools/go/packages"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
|
"golang.org/x/tools/go/ssa/ssautil"
|
||||||
|
|
||||||
llssa "github.com/goplus/llgo/ssa"
|
llssa "github.com/goplus/llgo/ssa"
|
||||||
)
|
)
|
||||||
@@ -40,10 +41,11 @@ func GenFromFile(inFile string) string {
|
|||||||
initial, err := packages.Load(cfg, inFile)
|
initial, err := packages.Load(cfg, inFile)
|
||||||
check(err)
|
check(err)
|
||||||
|
|
||||||
|
_, pkgs := ssautil.AllPackages(initial, ssa.SanityCheckFunctions)
|
||||||
|
|
||||||
pkg := initial[0]
|
pkg := initial[0]
|
||||||
fset := pkg.Fset
|
ssaPkg := pkgs[0]
|
||||||
ssaProg := ssa.NewProgram(fset, ssa.SanityCheckFunctions)
|
ssaPkg.Build()
|
||||||
ssaPkg := ssaProg.CreatePackage(pkg.Types, pkg.Syntax, pkg.TypesInfo, true)
|
|
||||||
|
|
||||||
prog := llssa.NewProgram(nil)
|
prog := llssa.NewProgram(nil)
|
||||||
ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax)
|
ret, err := cl.NewPackage(prog, ssaPkg, pkg.Syntax)
|
||||||
|
|||||||
Reference in New Issue
Block a user