]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add countRule rewrite rule helper
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 12 Mar 2019 02:22:49 +0000 (19:22 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Wed, 8 May 2019 22:58:10 +0000 (22:58 +0000)
noteRule is useful when you're trying to debug
a particular rule, or get a general sense for
how often a rule fires overall.

It is less useful if you're trying to figure
out which functions might be useful to benchmark
to ascertain the impact of a newly added rule.

Enter countRule. You use it like noteRule,
except that you get per-function summaries.

Sample output:

 # runtime
(*mspan).sweep: idx1=1
evacuate_faststr: idx1=1
evacuate_fast32: idx1=1
evacuate: idx1=2
evacuate_fast64: idx1=1
sweepone: idx1=1
purgecachedstats: idx1=1
mProf_Free: idx1=1

This suggests that the map benchmarks
might be good to run for this added rule.

Change-Id: Id471c3231f1736165f2020f6979ff01c29677808
Reviewed-on: https://go-review.googlesource.com/c/go/+/167088
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/ssa/compile.go
src/cmd/compile/internal/ssa/func.go
src/cmd/compile/internal/ssa/rewrite.go

index ce1e7fb409cf616d8ee9b004d11ba908bf89d64c..937e0223b3d26a7a68c7ea07d2f630557bd4e159 100644 (file)
@@ -5,6 +5,7 @@
 package ssa
 
 import (
+       "bytes"
        "cmd/internal/objabi"
        "cmd/internal/src"
        "fmt"
@@ -14,6 +15,7 @@ import (
        "os"
        "regexp"
        "runtime"
+       "sort"
        "strings"
        "time"
 )
@@ -133,6 +135,21 @@ func Compile(f *Func) {
                }
        }
 
+       if f.ruleMatches != nil {
+               var keys []string
+               for key := range f.ruleMatches {
+                       keys = append(keys, key)
+               }
+               sort.Strings(keys)
+               buf := new(bytes.Buffer)
+               fmt.Fprintf(buf, "%s: ", f.Name)
+               for _, key := range keys {
+                       fmt.Fprintf(buf, "%s=%d ", key, f.ruleMatches[key])
+               }
+               fmt.Fprint(buf, "\n")
+               fmt.Print(buf.String())
+       }
+
        // Squash error printing defer
        phaseName = ""
 }
index 4f6dbff20838fa1ea0c5ad8a7961e5f38d073677..df8df64dd5452e0d86b01b00e00d1a7b274a538a 100644 (file)
@@ -38,9 +38,10 @@ type Func struct {
        // Given an environment variable used for debug hash match,
        // what file (if any) receives the yes/no logging?
        logfiles       map[string]writeSyncer
-       HTMLWriter     *HTMLWriter // html writer, for debugging
-       DebugTest      bool        // default true unless $GOSSAHASH != ""; as a debugging aid, make new code conditional on this and use GOSSAHASH to binary search for failing cases
-       PrintOrHtmlSSA bool        // true if GOSSAFUNC matches, true even if fe.Log() (spew phase results to stdout) is false.
+       HTMLWriter     *HTMLWriter    // html writer, for debugging
+       DebugTest      bool           // default true unless $GOSSAHASH != ""; as a debugging aid, make new code conditional on this and use GOSSAHASH to binary search for failing cases
+       PrintOrHtmlSSA bool           // true if GOSSAFUNC matches, true even if fe.Log() (spew phase results to stdout) is false.
+       ruleMatches    map[string]int // number of times countRule was called during compilation for any given string
 
        scheduled bool // Values in Blocks are in final order
        laidout   bool // Blocks are ordered
index d1b9da276f0b9414d22d1cdc193fa09887c1135d..18d9c9f985c6514cfa211d442adf89e29d3bff63 100644 (file)
@@ -687,6 +687,20 @@ func noteRule(s string) bool {
        return true
 }
 
+// countRule increments Func.ruleMatches[key].
+// If Func.ruleMatches is non-nil at the end
+// of compilation, it will be printed to stdout.
+// This is intended to make it easier to find which functions
+// which contain lots of rules matches when developing new rules.
+func countRule(v *Value, key string) bool {
+       f := v.Block.Func
+       if f.ruleMatches == nil {
+               f.ruleMatches = make(map[string]int)
+       }
+       f.ruleMatches[key]++
+       return true
+}
+
 // warnRule generates compiler debug output with string s when
 // v is not in autogenerated code, cond is true and the rule has fired.
 func warnRule(cond bool, v *Value, s string) bool {