From: Josh Bleecher Snyder Date: Tue, 12 Mar 2019 02:22:49 +0000 (-0700) Subject: cmd/compile: add countRule rewrite rule helper X-Git-Tag: go1.13beta1~372 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0047353c53cd5c5524f8978c855e982cb4ca4533;p=gostls13.git cmd/compile: add countRule rewrite rule helper 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go index ce1e7fb409..937e0223b3 100644 --- a/src/cmd/compile/internal/ssa/compile.go +++ b/src/cmd/compile/internal/ssa/compile.go @@ -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 = "" } diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go index 4f6dbff208..df8df64dd5 100644 --- a/src/cmd/compile/internal/ssa/func.go +++ b/src/cmd/compile/internal/ssa/func.go @@ -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 diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index d1b9da276f..18d9c9f985 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -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 {