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"
|
||||
"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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user