mirror of
https://github.com/golang/go.git
synced 2025-05-21 15:24:21 +00:00
cmd/compile: omit racefuncentry/exit when they are not needed
When compiling with -race, we insert calls to racefuncentry, into every function. Add a rule that removes them in leaf functions, without instrumented loads/stores. Shaves ~30kb from "-race" version of go tool: file difference: go_old 15626192 go_new 15597520 [-28672 bytes] section differences: global text (code) = -24513 bytes (-0.358598%) read-only data = -5849 bytes (-0.167064%) Total difference -30362 bytes (-0.097928%) Fixes #24662 Change-Id: Ia63bf1827f4cf2c25e3e28dcd097c150994ade0a Reviewed-on: https://go-review.googlesource.com/121235 Run-TryBot: Ilya Tocar <ilya.tocar@intel.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
f76eaeb2c8
commit
4201c2077e
@ -10,7 +10,7 @@ import (
|
||||
"cmd/internal/sys"
|
||||
)
|
||||
|
||||
// The racewalk pass is currently handled in two parts.
|
||||
// The racewalk pass is currently handled in three parts.
|
||||
//
|
||||
// First, for flag_race, it inserts calls to racefuncenter and
|
||||
// racefuncexit at the start and end (respectively) of each
|
||||
@ -22,6 +22,10 @@ import (
|
||||
// the Func.InstrumentBody flag as needed. For background on why this
|
||||
// is done during SSA construction rather than a separate SSA pass,
|
||||
// see issue #19054.
|
||||
//
|
||||
// Third we remove calls to racefuncenter and racefuncexit, for leaf
|
||||
// functions without instrumented operations. This is done as part of
|
||||
// ssa opt pass via special rule.
|
||||
|
||||
// TODO(dvyukov): do not instrument initialization as writes:
|
||||
// a := make([]int, 10)
|
||||
|
@ -131,6 +131,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
|
||||
s.f.Cache = &ssaCaches[worker]
|
||||
s.f.Cache.Reset()
|
||||
s.f.DebugTest = s.f.DebugHashMatch("GOSSAHASH", name)
|
||||
s.f.Config.Race = flag_race
|
||||
s.f.Name = name
|
||||
if fn.Func.Pragma&Nosplit != 0 {
|
||||
s.f.NoSplit = true
|
||||
|
@ -38,6 +38,7 @@ type Config struct {
|
||||
nacl bool // GOOS=nacl
|
||||
use387 bool // GO386=387
|
||||
SoftFloat bool //
|
||||
Race bool // race detector enabled
|
||||
NeedsFpScratch bool // No direct move between GP and FP register sets
|
||||
BigEndian bool //
|
||||
}
|
||||
|
@ -1791,3 +1791,5 @@
|
||||
(Store {t4} (OffPtr <tt4> [o4] dst) d3
|
||||
(Store {t5} (OffPtr <tt5> [o5] dst) d4
|
||||
(Zero {t1} [n] dst mem)))))
|
||||
|
||||
(StaticCall {sym} x) && needRaceCleanup(sym,v) -> x
|
||||
|
@ -1026,3 +1026,31 @@ func registerizable(b *Block, t interface{}) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// needRaceCleanup reports whether this call to racefuncenter/exit isn't needed.
|
||||
func needRaceCleanup(sym interface{}, v *Value) bool {
|
||||
f := v.Block.Func
|
||||
if !f.Config.Race {
|
||||
return false
|
||||
}
|
||||
if !isSameSym(sym, "runtime.racefuncenter") && !isSameSym(sym, "runtime.racefuncexit") {
|
||||
return false
|
||||
}
|
||||
for _, b := range f.Blocks {
|
||||
for _, v := range b.Values {
|
||||
if v.Op == OpStaticCall {
|
||||
switch v.Aux.(fmt.Stringer).String() {
|
||||
case "runtime.racefuncenter", "runtime.racefuncexit", "runtime.panicindex",
|
||||
"runtime.panicslice", "runtime.panicdivide", "runtime.panicwrap":
|
||||
// Check for racefuncenter will encounter racefuncexit and vice versa.
|
||||
// Allow calls to panic*
|
||||
default:
|
||||
// If we encounterd any call, we need to keep racefunc*,
|
||||
// for accurate stacktraces.
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -27595,6 +27595,20 @@ func rewriteValuegeneric_OpStaticCall_0(v *Value) bool {
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// match: (StaticCall {sym} x)
|
||||
// cond: needRaceCleanup(sym,v)
|
||||
// result: x
|
||||
for {
|
||||
sym := v.Aux
|
||||
x := v.Args[0]
|
||||
if !(needRaceCleanup(sym, v)) {
|
||||
break
|
||||
}
|
||||
v.reset(OpCopy)
|
||||
v.Type = x.Type
|
||||
v.AddArg(x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func rewriteValuegeneric_OpStore_0(v *Value) bool {
|
||||
|
Loading…
x
Reference in New Issue
Block a user