From 317226e61c7269b97dafe8fd7524559ed64c64a2 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Wed, 22 Jul 2015 21:04:25 -0700 Subject: [PATCH] [dev.ssa] cmd/compile: use v.Args[x].Op in CSE key Experimentally, the Ops of v.Args do a good job of differentiating values that will end up in different partitions. Most values have at most two args, so use them. This reduces the wall time to run test/slice3.go on my laptop from ~20s to ~12s. Credit to Todd Neal for the idea. Change-Id: I55d08f09eb678bbe8366924ca2fabcd32526bf41 Reviewed-on: https://go-review.googlesource.com/12565 Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/cse.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go index ebc25151b2..c98217339b 100644 --- a/src/cmd/compile/internal/ssa/cse.go +++ b/src/cmd/compile/internal/ssa/cse.go @@ -25,7 +25,7 @@ func cse(f *Func) { // It starts with a coarse partition and iteratively refines it // until it reaches a fixed point. - // Make initial partition based on opcode/type-name/aux/auxint/nargs/phi-block + // Make initial partition based on opcode, type-name, aux, auxint, nargs, phi-block, and the ops of v's first args type key struct { op Op typ string @@ -33,6 +33,8 @@ func cse(f *Func) { auxint int64 nargs int block ID // block id for phi vars, -1 otherwise + arg0op Op // v.Args[0].Op if len(v.Args) > 0, OpInvalid otherwise + arg1op Op // v.Args[1].Op if len(v.Args) > 1, OpInvalid otherwise } m := map[key]eqclass{} for _, b := range f.Blocks { @@ -41,7 +43,15 @@ func cse(f *Func) { if v.Op == OpPhi { bid = b.ID } - k := key{v.Op, v.Type.String(), v.Aux, v.AuxInt, len(v.Args), bid} + arg0op := OpInvalid + if len(v.Args) > 0 { + arg0op = v.Args[0].Op + } + arg1op := OpInvalid + if len(v.Args) > 1 { + arg1op = v.Args[1].Op + } + k := key{v.Op, v.Type.String(), v.Aux, v.AuxInt, len(v.Args), bid, arg0op, arg1op} m[k] = append(m[k], v) } } -- 2.48.1