]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: enable CSE of constant strings
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 31 Aug 2016 02:11:19 +0000 (19:11 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 20 Mar 2017 20:22:26 +0000 (20:22 +0000)
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>
src/cmd/compile/internal/gc/ssa.go

index 960e14cc77f481d1d2165607ecaee78fdffb36ec..ee825acb0c8def52e7586d3e89008b1ec8fb37cc 100644 (file)
@@ -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.
@@ -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 {