cmd/compile: add ability to indicate 'concurrentOk' for debug flags

Also removes no-longer-needed "Any" field from compiler's DebugFlags.
Test/use case for this is the fmahash CL.

Change-Id: I214f02c91f30fc2ce53caf75fa5e2b905dd33429
Reviewed-on: https://go-review.googlesource.com/c/go/+/445495
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: David Chase <drchase@google.com>
This commit is contained in:
David Chase 2022-10-25 23:01:44 -04:00
parent 5619dd0849
commit c81c027982
3 changed files with 25 additions and 16 deletions

View file

@ -50,7 +50,7 @@ type DebugFlags struct {
InlineHotBudget int `help:"inline budget for hot functions"` InlineHotBudget int `help:"inline budget for hot functions"`
PGOInline int `help:"debug profile-guided inlining"` PGOInline int `help:"debug profile-guided inlining"`
Any bool // set when any of the debug flags have been set ConcurrentOk bool // true if only concurrentOk flags seen
} }
// DebugSSA is called to set a -d ssa/... option. // DebugSSA is called to set a -d ssa/... option.

View file

@ -165,6 +165,7 @@ func ParseFlags() {
Flag.Shared = &Ctxt.Flag_shared Flag.Shared = &Ctxt.Flag_shared
Flag.WB = true Flag.WB = true
Debug.ConcurrentOk = true
Debug.InlFuncsWithClosures = 1 Debug.InlFuncsWithClosures = 1
if buildcfg.Experiment.Unified { if buildcfg.Experiment.Unified {
Debug.Unified = 1 Debug.Unified = 1
@ -373,7 +374,7 @@ func concurrentBackendAllowed() bool {
// while writing the object file, and that is non-concurrent. // while writing the object file, and that is non-concurrent.
// Adding Debug_vlog, however, causes Debug.S to also print // Adding Debug_vlog, however, causes Debug.S to also print
// while flushing the plist, which happens concurrently. // while flushing the plist, which happens concurrently.
if Ctxt.Debugvlog || Debug.Any || Flag.Live > 0 { if Ctxt.Debugvlog || !Debug.ConcurrentOk || Flag.Live > 0 {
return false return false
} }
// TODO: Test and delete this condition. // TODO: Test and delete this condition.

View file

@ -203,16 +203,16 @@ func DecodeArg(arg string) string {
} }
type debugField struct { type debugField struct {
name string name string
help string help string
val interface{} // *int or *string concurrentOk bool // true if this field/flag is compatible with concurrent compilation
val interface{} // *int or *string
} }
type DebugFlag struct { type DebugFlag struct {
tab map[string]debugField tab map[string]debugField
any *bool concurrentOk *bool // this is non-nil only for compiler's DebugFlags, but only compiler has concurrent:ok fields
debugSSA DebugSSA // this is non-nil only for compiler's DebugFlags.
debugSSA DebugSSA
} }
// A DebugSSA function is called to set a -d ssa/... option. // A DebugSSA function is called to set a -d ssa/... option.
@ -244,12 +244,12 @@ func NewDebugFlag(debug interface{}, debugSSA DebugSSA) *DebugFlag {
for i := 0; i < t.NumField(); i++ { for i := 0; i < t.NumField(); i++ {
f := t.Field(i) f := t.Field(i)
ptr := v.Field(i).Addr().Interface() ptr := v.Field(i).Addr().Interface()
if f.Name == "Any" { if f.Name == "ConcurrentOk" {
switch ptr := ptr.(type) { switch ptr := ptr.(type) {
default: default:
panic("debug.Any must have type bool") panic("debug.ConcurrentOk must have type bool")
case *bool: case *bool:
flag.any = ptr flag.concurrentOk = ptr
} }
continue continue
} }
@ -258,13 +258,15 @@ func NewDebugFlag(debug interface{}, debugSSA DebugSSA) *DebugFlag {
if help == "" { if help == "" {
panic(fmt.Sprintf("debug.%s is missing help text", f.Name)) panic(fmt.Sprintf("debug.%s is missing help text", f.Name))
} }
concurrent := f.Tag.Get("concurrent")
switch ptr.(type) { switch ptr.(type) {
default: default:
panic(fmt.Sprintf("debug.%s has invalid type %v (must be int or string)", f.Name, f.Type)) panic(fmt.Sprintf("debug.%s has invalid type %v (must be int or string)", f.Name, f.Type))
case *int, *string: case *int, *string:
// ok // ok
} }
flag.tab[name] = debugField{name, help, ptr} flag.tab[name] = debugField{name, help, concurrent == "ok", ptr}
} }
return flag return flag
@ -274,9 +276,6 @@ func (f *DebugFlag) Set(debugstr string) error {
if debugstr == "" { if debugstr == "" {
return nil return nil
} }
if f.any != nil {
*f.any = true
}
for _, name := range strings.Split(debugstr, ",") { for _, name := range strings.Split(debugstr, ",") {
if name == "" { if name == "" {
continue continue
@ -332,6 +331,10 @@ func (f *DebugFlag) Set(debugstr string) error {
default: default:
panic("bad debugtab type") panic("bad debugtab type")
} }
// assembler DebugFlags don't have a ConcurrentOk field to reset, so check against that.
if !t.concurrentOk && f.concurrentOk != nil {
*f.concurrentOk = false
}
} else if f.debugSSA != nil && strings.HasPrefix(name, "ssa/") { } else if f.debugSSA != nil && strings.HasPrefix(name, "ssa/") {
// expect form ssa/phase/flag // expect form ssa/phase/flag
// e.g. -d=ssa/generic_cse/time // e.g. -d=ssa/generic_cse/time
@ -346,6 +349,11 @@ func (f *DebugFlag) Set(debugstr string) error {
if err != "" { if err != "" {
log.Fatalf(err) log.Fatalf(err)
} }
// Setting this false for -d=ssa/... preserves old behavior
// of turning off concurrency for any debug flags.
// It's not known for sure if this is necessary, but it is safe.
*f.concurrentOk = false
} else { } else {
return fmt.Errorf("unknown debug key %s\n", name) return fmt.Errorf("unknown debug key %s\n", name)
} }