Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ coverage:
ignore:
- "chore"
- "cmd"
- "cl/cltest"
- "internal/build"
- "internal/llgen"
- "internal/mockable"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ stories*.bin
.DS_Store
err.log
numpy.txt
result.txt

_go/
_runtime/
Expand Down
13 changes: 13 additions & 0 deletions cl/_testdata/cpkg/in.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package C

func Xadd(a, b int) int {
return add(a, b)
}

func Double(x float64) float64 {
return 2 * x
}

func add(a, b int) int {
return a + b
}
35 changes: 35 additions & 0 deletions cl/_testdata/cpkg/out.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
; ModuleID = 'github.com/goplus/llgo/cl/_testdata/cpkg'
source_filename = "github.com/goplus/llgo/cl/_testdata/cpkg"

@"github.com/goplus/llgo/cl/_testdata/cpkg.init$guard" = global i1 false, align 1

define double @Double(double %0) {
_llgo_0:
%1 = fmul double 2.000000e+00, %0
ret double %1
}

define i64 @add(i64 %0, i64 %1) {
_llgo_0:
%2 = call i64 @"github.com/goplus/llgo/cl/_testdata/cpkg.add"(i64 %0, i64 %1)
ret i64 %2
}

define i64 @"github.com/goplus/llgo/cl/_testdata/cpkg.add"(i64 %0, i64 %1) {
_llgo_0:
%2 = add i64 %0, %1
ret i64 %2
}

define void @"github.com/goplus/llgo/cl/_testdata/cpkg.init"() {
_llgo_0:
%0 = load i1, ptr @"github.com/goplus/llgo/cl/_testdata/cpkg.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1

_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"github.com/goplus/llgo/cl/_testdata/cpkg.init$guard", align 1
br label %_llgo_2

_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}
15 changes: 8 additions & 7 deletions cl/cltest/cltest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package cltest

import (
"archive/zip"
"bytes"
"go/ast"
"go/parser"
"go/token"
Expand All @@ -35,6 +36,7 @@ import (
"github.com/goplus/llgo/cl"
"github.com/goplus/llgo/internal/llgen"
"github.com/goplus/llgo/ssa/ssatest"
"github.com/qiniu/x/test"
"golang.org/x/tools/go/ssa"
"golang.org/x/tools/go/ssa/ssautil"

Expand Down Expand Up @@ -112,14 +114,13 @@ func testFrom(t *testing.T, pkgDir, sel string) {
return
}
log.Println("Parsing", pkgDir)
v := llgen.GenFrom(pkgDir)
out := pkgDir + "/out.ll"
b, err := os.ReadFile(out)
if err != nil {
t.Fatal("ReadFile failed:", err)
}
expected := string(b)
if v := llgen.GenFrom(pkgDir); v != expected && expected != ";" { // expected == ";" means skipping out.ll
t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected)
b, _ := os.ReadFile(out)
if !bytes.Equal(b, []byte{';'}) { // expected == ";" means skipping out.ll
if test.Diff(t, pkgDir+"/result.txt", []byte(v), b) {
t.Fatal("llgen.GenFrom: unexpect result")
}
}
}

Expand Down
11 changes: 2 additions & 9 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,15 +213,8 @@ func isCgoVar(name string) bool {
}

func (p *context) compileFuncDecl(pkg llssa.Package, f *ssa.Function) (llssa.Function, llssa.PyObjRef, int) {
pkgTypes, name, ftype := p.funcName(f, true)
pkgTypes, name, ftype := p.funcName(f)
if ftype != goFunc {
/*
if ftype == pyFunc {
// TODO(xsw): pyMod == ""
fnName := pysymPrefix + p.pyMod + "." + name
return nil, pkg.NewPyFunc(fnName, f.Signature, call), pyFunc
}
*/
return nil, nil, ignoredFunc
}
sig := f.Signature
Expand Down Expand Up @@ -1012,7 +1005,7 @@ func NewPackageEx(prog llssa.Program, patches Patches, pkg *ssa.Package, files [
cgoSymbols: make([]string, 0, 128),
}
ctx.initPyModule()
ctx.initFiles(pkgPath, files)
ctx.initFiles(pkgPath, files, pkgName == "C")
ctx.prog.SetPatch(ctx.patchType)
ret.SetPatch(ctx.patchType)
ret.SetResolveLinkname(ctx.resolveLinkname)
Expand Down
56 changes: 34 additions & 22 deletions cl/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,18 @@ start:
syms.initLinknames(p)
}

func (p *context) initFiles(pkgPath string, files []*ast.File) {
func (p *context) initFiles(pkgPath string, files []*ast.File, cPkg bool) {
for _, file := range files {
for _, decl := range file.Decls {
switch decl := decl.(type) {
case *ast.FuncDecl:
fullName, inPkgName := astFuncName(pkgPath, decl)
p.initLinknameByDoc(decl.Doc, fullName, inPkgName, false)
if !p.initLinknameByDoc(decl.Doc, fullName, inPkgName, false) && cPkg {
// package C (https://github.com/goplus/llgo/issues/1165)
if decl.Recv == nil && token.IsExported(inPkgName) {
p.prog.SetLinkname(fullName, strings.TrimPrefix(inPkgName, "X"))
}
}
case *ast.GenDecl:
switch decl.Tok {
case token.VAR:
Expand Down Expand Up @@ -266,51 +271,58 @@ func (p *context) collectSkip(line string, prefix int) {
}
}

func (p *context) initLinknameByDoc(doc *ast.CommentGroup, fullName, inPkgName string, isVar bool) {
func (p *context) initLinknameByDoc(doc *ast.CommentGroup, fullName, inPkgName string, isVar bool) bool {
if doc != nil {
for n := len(doc.List) - 1; n >= 0; n-- {
line := doc.List[n].Text
found := p.initLinkname(line, func(name string) (_ string, _, ok bool) {
ret := p.initLinkname(line, func(name string) (_ string, _, ok bool) {
return fullName, isVar, name == inPkgName
})
if !found {
break
if ret != unknownDirective {
return ret == hasLinkname
}
}
}
return false
}

func (p *context) initLinkname(line string, f func(inPkgName string) (fullName string, isVar, ok bool)) bool {
const (
noDirective = iota
hasLinkname
unknownDirective = -1
)

func (p *context) initLinkname(line string, f func(inPkgName string) (fullName string, isVar, ok bool)) int {
const (
linkname = "//go:linkname "
llgolink = "//llgo:link "
llgolink2 = "// llgo:link "
exportName = "//export "
directive = "//go:"
linkname = "//go:linkname "
llgolink = "//llgo:link "
llgolink2 = "// llgo:link "
export = "//export "
directive = "//go:"
)
if strings.HasPrefix(line, linkname) {
p.initLink(line, len(linkname), f)
return true
return hasLinkname
} else if strings.HasPrefix(line, llgolink2) {
p.initLink(line, len(llgolink2), f)
return true
return hasLinkname
} else if strings.HasPrefix(line, llgolink) {
p.initLink(line, len(llgolink), f)
return true
} else if strings.HasPrefix(line, exportName) {
p.initCgoExport(line, len(exportName), f)
return true
return hasLinkname
} else if strings.HasPrefix(line, export) {
p.initCgoExport(line, len(export), f)
return hasLinkname
} else if strings.HasPrefix(line, directive) {
// skip unknown annotation but continue to parse the next annotation
return true
return unknownDirective
}
return false
return noDirective
}

func (p *context) initCgoExport(line string, prefix int, f func(inPkgName string) (fullName string, isVar, ok bool)) {
name := strings.TrimSpace(line[prefix:])
if fullName, _, ok := f(name); ok {
p.cgoExports[fullName] = name
p.cgoExports[fullName] = name // TODO(xsw): why not use prog.SetLinkname?
}
}

Expand Down Expand Up @@ -497,7 +509,7 @@ const (
llgoAtomicOpLast = llgoAtomicOpBase + int(llssa.OpUMin)
)

func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) {
func (p *context) funcName(fn *ssa.Function) (*types.Package, string, int) {
var pkg *types.Package
var orgName string
if origin := fn.Origin(); origin != nil {
Expand Down
2 changes: 1 addition & 1 deletion cl/instr.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ var llgoInstrs = map[string]int{
// funcOf returns a function by name and set ftype = goFunc, cFunc, etc.
// or returns nil and set ftype = llgoCstr, llgoAlloca, llgoUnreachable, etc.
func (p *context) funcOf(fn *ssa.Function) (aFn llssa.Function, pyFn llssa.PyObjRef, ftype int) {
pkgTypes, name, ftype := p.funcName(fn, false)
pkgTypes, name, ftype := p.funcName(fn)
switch ftype {
case pyFunc:
if kind, mod := pkgKindByScope(pkgTypes.Scope()); kind == PkgPyModule {
Expand Down
8 changes: 5 additions & 3 deletions internal/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func Do(args []string, conf *Config) ([]Package, error) {
prog := llssa.NewProgram(target)
sizes := func(sizes types.Sizes, compiler, arch string) types.Sizes {
if arch == "wasm" {
sizes = &types.StdSizes{4, 4}
sizes = &types.StdSizes{WordSize: 4, MaxAlign: 4}
}
return prog.TypeSizes(sizes)
}
Expand Down Expand Up @@ -803,15 +803,15 @@ func buildPkg(ctx *context, aPkg *aPackage, verbose bool) error {
fmt.Fprintf(os.Stderr, "==> Export %s: %s\n", aPkg.PkgPath, pkg.ExportFile)
}
if IsCheckEnable() {
if err, msg := llcCheck(ctx.env, pkg.ExportFile); err != nil {
if msg, err := llcCheck(ctx.env, pkg.ExportFile); err != nil {
fmt.Fprintf(os.Stderr, "==> lcc %v: %v\n%v\n", pkg.PkgPath, pkg.ExportFile, msg)
}
}
}
return nil
}

func llcCheck(env *llvm.Env, exportFile string) (err error, msg string) {
func llcCheck(env *llvm.Env, exportFile string) (msg string, err error) {
bin := filepath.Join(env.BinDir(), "llc")
cmd := exec.Command(bin, "-filetype=null", exportFile)
var buf bytes.Buffer
Expand Down Expand Up @@ -904,6 +904,7 @@ func createSSAPkg(prog *ssa.Program, p *packages.Package, verbose bool) *ssa.Pac
return pkgSSA
}

/*
var (
// TODO(xsw): complete build flags
buildFlags = map[string]bool{
Expand All @@ -922,6 +923,7 @@ var (
"-ldflags": true, // --ldflags 'flag list': arguments to pass on each go tool link invocation
}
)
*/

const llgoDebug = "LLGO_DEBUG"
const llgoDbgSyms = "LLGO_DEBUG_SYMBOLS"
Expand Down
2 changes: 2 additions & 0 deletions internal/build/clean.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import (
"github.com/goplus/llgo/internal/packages"
)

/*
var (
// TODO(xsw): complete clean flags
cleanFlags = map[string]bool{
"-v": false, // -v: print the paths of packages as they are clean
}
)
*/

func Clean(patterns []string, conf *Config) {
if conf.Goos == "" {
Expand Down
Loading