ir: move adding packages from the compiler
Этот коммит содержится в:
родитель
9df04a2170
коммит
a561e9a9ac
2 изменённых файлов: 50 добавлений и 45 удалений
|
@ -177,50 +177,8 @@ func (c *Compiler) Parse(mainPath string) error {
|
||||||
|
|
||||||
c.ir = ir.NewProgram(lprogram, mainPath)
|
c.ir = ir.NewProgram(lprogram, mainPath)
|
||||||
|
|
||||||
// Make a list of packages in import order.
|
// Run some DCE and analysis passes. The results are later used by the
|
||||||
packageList := []*ssa.Package{}
|
// compiler.
|
||||||
packageSet := map[string]struct{}{}
|
|
||||||
worklist := []string{"runtime", mainPath}
|
|
||||||
for len(worklist) != 0 {
|
|
||||||
pkgPath := worklist[0]
|
|
||||||
pkg := c.ir.Program.ImportedPackage(pkgPath)
|
|
||||||
if pkg == nil {
|
|
||||||
// Non-SSA package (e.g. cgo).
|
|
||||||
packageSet[pkgPath] = struct{}{}
|
|
||||||
worklist = worklist[1:]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, ok := packageSet[pkgPath]; ok {
|
|
||||||
// Package already in the final package list.
|
|
||||||
worklist = worklist[1:]
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
unsatisfiedImports := make([]string, 0)
|
|
||||||
imports := pkg.Pkg.Imports()
|
|
||||||
for _, pkg := range imports {
|
|
||||||
if _, ok := packageSet[pkg.Path()]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
unsatisfiedImports = append(unsatisfiedImports, pkg.Path())
|
|
||||||
}
|
|
||||||
if len(unsatisfiedImports) == 0 {
|
|
||||||
// All dependencies of this package are satisfied, so add this
|
|
||||||
// package to the list.
|
|
||||||
packageList = append(packageList, pkg)
|
|
||||||
packageSet[pkgPath] = struct{}{}
|
|
||||||
worklist = worklist[1:]
|
|
||||||
} else {
|
|
||||||
// Prepend all dependencies to the worklist and reconsider this
|
|
||||||
// package (by not removing it from the worklist). At that point, it
|
|
||||||
// must be possible to add it to packageList.
|
|
||||||
worklist = append(unsatisfiedImports, worklist...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pkg := range packageList {
|
|
||||||
c.ir.AddPackage(pkg)
|
|
||||||
}
|
|
||||||
c.ir.SimpleDCE() // remove most dead code
|
c.ir.SimpleDCE() // remove most dead code
|
||||||
c.ir.AnalyseCallgraph() // set up callgraph
|
c.ir.AnalyseCallgraph() // set up callgraph
|
||||||
c.ir.AnalyseInterfaceConversions() // determine which types are converted to an interface
|
c.ir.AnalyseInterfaceConversions() // determine which types are converted to an interface
|
||||||
|
|
49
ir/ir.go
49
ir/ir.go
|
@ -109,7 +109,48 @@ func NewProgram(lprogram *loader.Program, mainPath string) *Program {
|
||||||
program := ssautil.CreateProgram(lprogram, ssa.SanityCheckFunctions|ssa.BareInits|ssa.GlobalDebug)
|
program := ssautil.CreateProgram(lprogram, ssa.SanityCheckFunctions|ssa.BareInits|ssa.GlobalDebug)
|
||||||
program.Build()
|
program.Build()
|
||||||
|
|
||||||
return &Program{
|
// Make a list of packages in import order.
|
||||||
|
packageList := []*ssa.Package{}
|
||||||
|
packageSet := map[string]struct{}{}
|
||||||
|
worklist := []string{"runtime", mainPath}
|
||||||
|
for len(worklist) != 0 {
|
||||||
|
pkgPath := worklist[0]
|
||||||
|
pkg := program.ImportedPackage(pkgPath)
|
||||||
|
if pkg == nil {
|
||||||
|
// Non-SSA package (e.g. cgo).
|
||||||
|
packageSet[pkgPath] = struct{}{}
|
||||||
|
worklist = worklist[1:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := packageSet[pkgPath]; ok {
|
||||||
|
// Package already in the final package list.
|
||||||
|
worklist = worklist[1:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
unsatisfiedImports := make([]string, 0)
|
||||||
|
imports := pkg.Pkg.Imports()
|
||||||
|
for _, pkg := range imports {
|
||||||
|
if _, ok := packageSet[pkg.Path()]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
unsatisfiedImports = append(unsatisfiedImports, pkg.Path())
|
||||||
|
}
|
||||||
|
if len(unsatisfiedImports) == 0 {
|
||||||
|
// All dependencies of this package are satisfied, so add this
|
||||||
|
// package to the list.
|
||||||
|
packageList = append(packageList, pkg)
|
||||||
|
packageSet[pkgPath] = struct{}{}
|
||||||
|
worklist = worklist[1:]
|
||||||
|
} else {
|
||||||
|
// Prepend all dependencies to the worklist and reconsider this
|
||||||
|
// package (by not removing it from the worklist). At that point, it
|
||||||
|
// must be possible to add it to packageList.
|
||||||
|
worklist = append(unsatisfiedImports, worklist...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p := &Program{
|
||||||
Program: program,
|
Program: program,
|
||||||
mainPkg: program.ImportedPackage(mainPath),
|
mainPkg: program.ImportedPackage(mainPath),
|
||||||
functionMap: make(map[*ssa.Function]*Function),
|
functionMap: make(map[*ssa.Function]*Function),
|
||||||
|
@ -118,6 +159,12 @@ func NewProgram(lprogram *loader.Program, mainPath string) *Program {
|
||||||
interfaces: make(map[string]*Interface),
|
interfaces: make(map[string]*Interface),
|
||||||
comments: comments,
|
comments: comments,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, pkg := range packageList {
|
||||||
|
p.AddPackage(pkg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a package to this Program. All packages need to be added first before any
|
// Add a package to this Program. All packages need to be added first before any
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче