go.tools/ssa: de-dup the creation of method sets, using typemap.

Yields a ~20% improvement in SSA construction time.

Also: better names for promotion wrapper functions.

R=gri
CC=golang-dev
https://golang.org/cl/11050043
This commit is contained in:
Alan Donovan 2013-07-10 18:01:11 -04:00
parent 26d93d2e47
commit 4df74776da
4 changed files with 11 additions and 14 deletions

View File

@ -6,10 +6,11 @@ package typemap_test
// (e.g. all types generated by type-checking some body of real code).
import (
"code.google.com/p/go.tools/go/types"
"code.google.com/p/go.tools/go/types/typemap"
"go/ast"
"testing"
"code.google.com/p/go.tools/go/types"
"code.google.com/p/go.tools/go/types/typemap"
)
var (

View File

@ -39,7 +39,6 @@ func NewProgram(fset *token.FileSet, mode BuilderMode) *Program {
PackagesByPath: make(map[string]*Package),
packages: make(map[*types.Package]*Package),
builtins: make(map[types.Object]*Builtin),
methodSets: make(map[types.Type]MethodSet),
concreteMethods: make(map[*types.Func]*Function),
indirectionWrappers: make(map[*Function]*Function),
boundMethodWrappers: make(map[*Function]*Function),

View File

@ -81,14 +81,13 @@ type candidate struct {
path *anonFieldPath // desugared selector path
}
// For debugging.
func (c candidate) String() string {
s := ""
// Inefficient!
for p := c.path; p != nil; p = p.tail {
s = "." + p.field.Name() + s
}
return "@" + s + "." + c.method.Name()
return s + "." + c.method.Name()
}
// ptrRecv returns true if this candidate has a pointer receiver.
@ -110,15 +109,12 @@ func (p *Program) MethodSet(typ types.Type) MethodSet {
p.methodsMu.Lock()
defer p.methodsMu.Unlock()
// TODO(adonovan): Using Types as map keys doesn't properly
// de-dup. e.g. *Named are canonical but *Struct and
// others are not. Need to de-dup using typemap.T.
mset := p.methodSets[typ]
mset := p.methodSets.At(typ)
if mset == nil {
mset = buildMethodSet(p, typ)
p.methodSets[typ] = mset
p.methodSets.Set(typ, mset)
}
return mset
return mset.(MethodSet)
}
// buildMethodSet computes the concrete method set for type typ.
@ -282,12 +278,12 @@ func promotionWrapper(prog *Program, typ types.Type, cand *candidate) *Function
// TODO(adonovan): consult memoization cache keyed by (typ, cand).
// Needs typemap. Also needs hash/eq functions for 'candidate'.
if prog.mode&LogSource != 0 {
defer logStack("promotionWrapper %s, %s, type %s", typ, cand, sig)()
defer logStack("promotionWrapper (%s)%s, type %s", typ, cand, sig)()
}
fn := &Function{
name: cand.method.Name(),
Signature: sig,
Synthetic: "promotion wrapper for " + cand.String(),
Synthetic: fmt.Sprintf("promotion wrapper for (%s)%s", typ, cand),
Prog: prog,
pos: cand.method.Pos(),
}

View File

@ -11,6 +11,7 @@ import (
"code.google.com/p/go.tools/go/exact"
"code.google.com/p/go.tools/go/types"
"code.google.com/p/go.tools/go/types/typemap"
"code.google.com/p/go.tools/importer"
)
@ -25,7 +26,7 @@ type Program struct {
mode BuilderMode // set of mode bits for SSA construction
methodsMu sync.Mutex // guards the following maps:
methodSets map[types.Type]MethodSet // concrete method set each type [TODO(adonovan): de-dup]
methodSets typemap.M // maps type to its concrete MethodSet
indirectionWrappers map[*Function]*Function // func(*T) wrappers for T-methods
boundMethodWrappers map[*Function]*Function // wrappers for curried x.Method closures
ifaceMethodWrappers map[*types.Func]*Function // wrappers for curried I.Method functions