mirror of
https://github.com/golang/go
synced 2024-11-18 08:34:44 -07:00
cmd/compile: enable CSE of constant strings
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>
This commit is contained in:
parent
25b5181001
commit
e22ba7f0fb
@ -3104,17 +3104,16 @@ func etypesign(e EType) int8 {
|
|||||||
func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} {
|
func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} {
|
||||||
switch sym.(type) {
|
switch sym.(type) {
|
||||||
default:
|
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:
|
case *ssa.ExternSymbol, *ssa.ArgSymbol, *ssa.AutoSymbol:
|
||||||
// these are the only valid types
|
// these are the only valid types
|
||||||
}
|
}
|
||||||
|
|
||||||
if lsym, ok := s.varsyms[n]; ok {
|
if lsym, ok := s.varsyms[n]; ok {
|
||||||
return lsym
|
return lsym
|
||||||
} else {
|
}
|
||||||
s.varsyms[n] = sym
|
s.varsyms[n] = sym
|
||||||
return sym
|
return sym
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
|
// addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
|
||||||
@ -4692,6 +4691,7 @@ func fieldIdx(n *Node) int {
|
|||||||
// It also exports a bunch of compiler services for the ssa backend.
|
// It also exports a bunch of compiler services for the ssa backend.
|
||||||
type ssafn struct {
|
type ssafn struct {
|
||||||
curfn *Node
|
curfn *Node
|
||||||
|
strings map[string]interface{} // map from constant string to data symbols
|
||||||
stksize int64 // stack size for current frame
|
stksize int64 // stack size for current frame
|
||||||
stkptrsize int64 // prefix of stack containing pointers
|
stkptrsize int64 // prefix of stack containing pointers
|
||||||
log bool
|
log bool
|
||||||
@ -4699,10 +4699,17 @@ type ssafn struct {
|
|||||||
|
|
||||||
// StringData returns a symbol (a *Sym wrapped in an interface) which
|
// StringData returns a symbol (a *Sym wrapped in an interface) which
|
||||||
// is the data component of a global string constant containing s.
|
// is the data component of a global string constant containing s.
|
||||||
func (*ssafn) StringData(s string) interface{} {
|
func (e *ssafn) StringData(s string) interface{} {
|
||||||
// TODO: is idealstring correct? It might not matter...
|
if aux, ok := e.strings[s]; ok {
|
||||||
|
return aux
|
||||||
|
}
|
||||||
|
if e.strings == nil {
|
||||||
|
e.strings = make(map[string]interface{})
|
||||||
|
}
|
||||||
data := stringsym(s)
|
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 {
|
func (e *ssafn) Auto(t ssa.Type) ssa.GCNode {
|
||||||
|
Loading…
Reference in New Issue
Block a user