Skip to content

Commit

Permalink
cmd/compile: enable CSE of constant strings
Browse files Browse the repository at this point in the history
CL 27254 changed a constant string to a byte array
in encoding/hex and got significant performance
improvements.

hex.Encode used the string twice in a single function.
The rewrite rules lower constant strings into components.
The pointer component requires an aux symbol.
The existing implementation created a new aux symbol every time.
As a result, constant string pointers were never CSE'd.
Tighten then moved the pointer calculation next to the uses, i.e.
into the loop.

The re-use of aux syms enabled by this CL
occurs 3691 times during make.bash.

This CL should not go in without CL 38338
or something like it.

Change-Id: Ibbf5b17283c0e31821d04c7e08d995c654de5663
Reviewed-on: https://go-review.googlesource.com/28219
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
  • Loading branch information
josharian committed Mar 20, 2017
1 parent 25b5181 commit e22ba7f
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions src/cmd/compile/internal/gc/ssa.go
Expand Up @@ -3104,17 +3104,16 @@ func etypesign(e EType) int8 {
func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} {
switch sym.(type) {
default:
s.Fatalf("sym %v is of uknown type %T", sym, sym)
s.Fatalf("sym %v is of unknown type %T", sym, sym)
case *ssa.ExternSymbol, *ssa.ArgSymbol, *ssa.AutoSymbol:
// these are the only valid types
}

if lsym, ok := s.varsyms[n]; ok {
return lsym
} else {
s.varsyms[n] = sym
return sym
}
s.varsyms[n] = sym
return sym
}

// addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
Expand Down Expand Up @@ -4692,17 +4691,25 @@ func fieldIdx(n *Node) int {
// It also exports a bunch of compiler services for the ssa backend.
type ssafn struct {
curfn *Node
stksize int64 // stack size for current frame
stkptrsize int64 // prefix of stack containing pointers
strings map[string]interface{} // map from constant string to data symbols
stksize int64 // stack size for current frame
stkptrsize int64 // prefix of stack containing pointers
log bool
}

// StringData returns a symbol (a *Sym wrapped in an interface) which
// is the data component of a global string constant containing s.
func (*ssafn) StringData(s string) interface{} {
// TODO: is idealstring correct? It might not matter...
func (e *ssafn) StringData(s string) interface{} {
if aux, ok := e.strings[s]; ok {
return aux
}
if e.strings == nil {
e.strings = make(map[string]interface{})
}
data := stringsym(s)
return &ssa.ExternSymbol{Typ: idealstring, Sym: data}
aux := &ssa.ExternSymbol{Typ: idealstring, Sym: data}
e.strings[s] = aux
return aux
}

func (e *ssafn) Auto(t ssa.Type) ssa.GCNode {
Expand Down

0 comments on commit e22ba7f

Please sign in to comment.