Skip to content

Commit

Permalink
loadPackageEx: dedup
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Jun 15, 2024
1 parent 1b48b98 commit 2b1da5b
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
13 changes: 5 additions & 8 deletions cl/compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package cl_test
import (
"os"
"path/filepath"
"runtime"
"testing"

"github.com/goplus/llgo/cl"
Expand Down Expand Up @@ -71,13 +70,11 @@ func TestPython(t *testing.T) {
cltest.Pkg(t, ssa.PkgPython, "../py/llgo_autogen.ll")
}

func TestGoLibMath(t *testing.T) {
if runtime.GOOS == "darwin" { // TODO(xsw): support linux/windows
root, _ := filepath.Abs("..")
os.Setenv("LLGOROOT", root)
conf := build.NewDefaultConf(build.ModeInstall)
build.Do([]string{"math"}, conf)
}
func TestGoPkgMath(t *testing.T) {
root, _ := filepath.Abs("..")
os.Setenv("LLGOROOT", root)
conf := build.NewDefaultConf(build.ModeInstall)
build.Do([]string{"math"}, conf)
}

func TestVar(t *testing.T) {
Expand Down
52 changes: 46 additions & 6 deletions internal/packages/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,33 @@ type loader struct {
requestedMode LoadMode
}

type Deduper struct {
type cachedPackage struct {
Types *types.Package
TypesInfo *types.Info
Syntax []*ast.File
}

func NewDeduper() *Deduper {
type aDeduper struct {
cache sync.Map
}

type Deduper = *aDeduper

func NewDeduper() Deduper {
return &aDeduper{}
}

func (p Deduper) check(pkgPath string) *cachedPackage {
if v, ok := p.cache.Load(pkgPath); ok {
return v.(*cachedPackage)
}
return nil
}

func (p Deduper) set(pkgPath string, cp *cachedPackage) {
p.cache.Store(pkgPath, cp)
}

//go:linkname defaultDriver golang.org/x/tools/go/packages.defaultDriver
func defaultDriver(cfg *Config, patterns ...string) (*packages.DriverResponse, bool, error)

Expand All @@ -130,7 +150,7 @@ type importerFunc func(path string) (*types.Package, error)

func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }

func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
func loadPackageEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
if lpkg.PkgPath == "unsafe" {
// Fill in the blanks to avoid surprises.
lpkg.Types = types.Unsafe
Expand All @@ -141,6 +161,26 @@ func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
return
}

if dedup != nil {
if cp := dedup.check(lpkg.PkgPath); cp != nil {
lpkg.Types = cp.Types
lpkg.Fset = ld.Fset
lpkg.TypesInfo = cp.TypesInfo
lpkg.Syntax = cp.Syntax
lpkg.TypesSizes = ld.sizes
return
}
defer func() {
if !lpkg.IllTyped && lpkg.needtypes && lpkg.needsrc {
dedup.set(lpkg.PkgPath, &cachedPackage{
Types: lpkg.Types,
TypesInfo: lpkg.TypesInfo,
Syntax: lpkg.Syntax,
})
}
}()
}

// Call NewPackage directly with explicit name.
// This avoids skew between golist and go/types when the files'
// package declarations are inconsistent.
Expand Down Expand Up @@ -404,7 +444,7 @@ func loadPackageEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
lpkg.IllTyped = illTyped
}

func loadRecursiveEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
func loadRecursiveEx(dedup Deduper, ld *loader, lpkg *loaderPackage) {
lpkg.loadOnce.Do(func() {
// Load the direct dependencies, in parallel.
var wg sync.WaitGroup
Expand All @@ -421,7 +461,7 @@ func loadRecursiveEx(dedup *Deduper, ld *loader, lpkg *loaderPackage) {
})
}

func refineEx(dedup *Deduper, ld *loader, response *packages.DriverResponse) ([]*Package, error) {
func refineEx(dedup Deduper, ld *loader, response *packages.DriverResponse) ([]*Package, error) {
roots := response.Roots
rootMap := make(map[string]int, len(roots))
for i, root := range roots {
Expand Down Expand Up @@ -641,7 +681,7 @@ func refineEx(dedup *Deduper, ld *loader, response *packages.DriverResponse) ([]
// return an error. Clients may need to handle such errors before
// proceeding with further analysis. The PrintErrors function is
// provided for convenient display of all errors.
func LoadEx(dedup *Deduper, sizes func(types.Sizes) types.Sizes, cfg *Config, patterns ...string) ([]*Package, error) {
func LoadEx(dedup Deduper, sizes func(types.Sizes) types.Sizes, cfg *Config, patterns ...string) ([]*Package, error) {
ld := newLoader(cfg)
response, external, err := defaultDriver(&ld.Config, patterns...)
if err != nil {
Expand Down

0 comments on commit 2b1da5b

Please sign in to comment.