From: Todd Neal Date: Fri, 16 Oct 2015 01:25:32 +0000 (-0500) Subject: [dev.ssa] cmd/compile/internal/ssa: reuse symbols X-Git-Tag: go1.7beta1~1623^2^2~139 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d076ef749b8628c9743f6544eb30e8fde5d7f289;p=gostls13.git [dev.ssa] cmd/compile/internal/ssa: reuse symbols Reuse the ArgSymbol for nodes so that the Aux values will be equal for cse. Change-Id: Iaae80bd19ff2d3f51b6c9049fd860e04baa6f175 Reviewed-on: https://go-review.googlesource.com/15930 Reviewed-by: Keith Randall Run-TryBot: Todd Neal --- diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 312d494f5d..7219ffd653 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -87,17 +87,19 @@ func buildssa(fn *Node) (ssafn *ssa.Func, usessa bool) { s.startBlock(s.f.Entry) s.vars[&memVar] = s.startmem + s.varsyms = map[*Node]interface{}{} + // Generate addresses of local declarations s.decladdrs = map[*Node]*ssa.Value{} for d := fn.Func.Dcl; d != nil; d = d.Next { n := d.N switch n.Class { case PPARAM: - aux := &ssa.ArgSymbol{Typ: n.Type, Node: n} + aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n}) s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp) case PAUTO | PHEAP: // TODO this looks wrong for PAUTO|PHEAP, no vardef, but also no definition - aux := &ssa.AutoSymbol{Typ: n.Type, Node: n} + aux := s.lookupSymbol(n, &ssa.AutoSymbol{Typ: n.Type, Node: n}) s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp) case PPARAM | PHEAP, PPARAMOUT | PHEAP: // This ends up wrong, have to do it at the PARAM node instead. @@ -234,6 +236,9 @@ type state struct { // addresses of PPARAM and PPARAMOUT variables. decladdrs map[*Node]*ssa.Value + // symbols for PEXTERN, PAUTO and PPARAMOUT variables so they can be reused. + varsyms map[*Node]interface{} + // starting values. Memory, frame pointer, and stack pointer startmem *ssa.Value sp *ssa.Value @@ -1247,7 +1252,7 @@ func (s *state) expr(n *Node) *ssa.Value { s.stmtList(n.Ninit) switch n.Op { case OCFUNC: - aux := &ssa.ExternSymbol{n.Type, n.Left.Sym} + aux := s.lookupSymbol(n, &ssa.ExternSymbol{n.Type, n.Left.Sym}) return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb) case OPARAM: addr := s.addr(n, false) @@ -2187,6 +2192,25 @@ func etypesign(e uint8) int8 { return 0 } +// lookupSymbol is used to retrieve the symbol (Extern, Arg or Auto) used for a particular node. +// This improves the effectiveness of cse by using the same Aux values for the +// same symbols. +func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} { + switch sym.(type) { + default: + s.Fatalf("sym %v is of uknown 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 + } +} + // addr converts the address of the expression n to SSA, adds it to s and returns the SSA result. // The value that the returned Value represents is guaranteed to be non-nil. // If bounded is true then this address does not require a nil check for its operand @@ -2226,7 +2250,9 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value { aux := &ssa.AutoSymbol{Typ: n.Type, Node: n} return s.newValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp) case PPARAMOUT: // Same as PAUTO -- cannot generate LEA early. - aux := &ssa.ArgSymbol{Typ: n.Type, Node: n} + // ensure that we reuse symbols for out parameters so + // that cse works on their addresses + aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n}) return s.newValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp) case PAUTO | PHEAP, PPARAM | PHEAP, PPARAMOUT | PHEAP, PPARAMREF: return s.expr(n.Name.Heapaddr)