1
0
mirror of https://github.com/golang/go synced 2024-11-24 04:00:13 -07:00

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 <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2019-03-11 19:22:49 -07:00
parent 591454c44c
commit 0047353c53
3 changed files with 35 additions and 3 deletions

View File

@ -5,6 +5,7 @@
package ssa package ssa
import ( import (
"bytes"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/src" "cmd/internal/src"
"fmt" "fmt"
@ -14,6 +15,7 @@ import (
"os" "os"
"regexp" "regexp"
"runtime" "runtime"
"sort"
"strings" "strings"
"time" "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 // Squash error printing defer
phaseName = "" phaseName = ""
} }

View File

@ -38,9 +38,10 @@ type Func struct {
// Given an environment variable used for debug hash match, // Given an environment variable used for debug hash match,
// what file (if any) receives the yes/no logging? // what file (if any) receives the yes/no logging?
logfiles map[string]writeSyncer logfiles map[string]writeSyncer
HTMLWriter *HTMLWriter // html writer, for debugging 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 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. 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 scheduled bool // Values in Blocks are in final order
laidout bool // Blocks are ordered laidout bool // Blocks are ordered

View File

@ -687,6 +687,20 @@ func noteRule(s string) bool {
return true 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 // warnRule generates compiler debug output with string s when
// v is not in autogenerated code, cond is true and the rule has fired. // v is not in autogenerated code, cond is true and the rule has fired.
func warnRule(cond bool, v *Value, s string) bool { func warnRule(cond bool, v *Value, s string) bool {