@@ -203,16 +203,16 @@ func DecodeArg(arg string) string {
203
203
}
204
204
205
205
type debugField struct {
206
- name string
207
- help string
208
- val interface {} // *int or *string
206
+ name string
207
+ help string
208
+ concurrentOk bool // true if this field/flag is compatible with concurrent compilation
209
+ val interface {} // *int or *string
209
210
}
210
211
211
212
type DebugFlag struct {
212
- tab map [string ]debugField
213
- any * bool
214
-
215
- debugSSA DebugSSA
213
+ tab map [string ]debugField
214
+ concurrentOk * bool // this is non-nil only for compiler's DebugFlags, but only compiler has concurrent:ok fields
215
+ debugSSA DebugSSA // this is non-nil only for compiler's DebugFlags.
216
216
}
217
217
218
218
// A DebugSSA function is called to set a -d ssa/... option.
@@ -244,12 +244,12 @@ func NewDebugFlag(debug interface{}, debugSSA DebugSSA) *DebugFlag {
244
244
for i := 0 ; i < t .NumField (); i ++ {
245
245
f := t .Field (i )
246
246
ptr := v .Field (i ).Addr ().Interface ()
247
- if f .Name == "Any " {
247
+ if f .Name == "ConcurrentOk " {
248
248
switch ptr := ptr .(type ) {
249
249
default :
250
- panic ("debug.Any must have type bool" )
250
+ panic ("debug.ConcurrentOk must have type bool" )
251
251
case * bool :
252
- flag .any = ptr
252
+ flag .concurrentOk = ptr
253
253
}
254
254
continue
255
255
}
@@ -258,13 +258,15 @@ func NewDebugFlag(debug interface{}, debugSSA DebugSSA) *DebugFlag {
258
258
if help == "" {
259
259
panic (fmt .Sprintf ("debug.%s is missing help text" , f .Name ))
260
260
}
261
+ concurrent := f .Tag .Get ("concurrent" )
262
+
261
263
switch ptr .(type ) {
262
264
default :
263
265
panic (fmt .Sprintf ("debug.%s has invalid type %v (must be int or string)" , f .Name , f .Type ))
264
266
case * int , * string :
265
267
// ok
266
268
}
267
- flag .tab [name ] = debugField {name , help , ptr }
269
+ flag .tab [name ] = debugField {name , help , concurrent == "ok" , ptr }
268
270
}
269
271
270
272
return flag
@@ -274,9 +276,6 @@ func (f *DebugFlag) Set(debugstr string) error {
274
276
if debugstr == "" {
275
277
return nil
276
278
}
277
- if f .any != nil {
278
- * f .any = true
279
- }
280
279
for _ , name := range strings .Split (debugstr , "," ) {
281
280
if name == "" {
282
281
continue
@@ -332,6 +331,10 @@ func (f *DebugFlag) Set(debugstr string) error {
332
331
default :
333
332
panic ("bad debugtab type" )
334
333
}
334
+ // assembler DebugFlags don't have a ConcurrentOk field to reset, so check against that.
335
+ if ! t .concurrentOk && f .concurrentOk != nil {
336
+ * f .concurrentOk = false
337
+ }
335
338
} else if f .debugSSA != nil && strings .HasPrefix (name , "ssa/" ) {
336
339
// expect form ssa/phase/flag
337
340
// e.g. -d=ssa/generic_cse/time
@@ -346,6 +349,11 @@ func (f *DebugFlag) Set(debugstr string) error {
346
349
if err != "" {
347
350
log .Fatalf (err )
348
351
}
352
+ // Setting this false for -d=ssa/... preserves old behavior
353
+ // of turning off concurrency for any debug flags.
354
+ // It's not known for sure if this is necessary, but it is safe.
355
+ * f .concurrentOk = false
356
+
349
357
} else {
350
358
return fmt .Errorf ("unknown debug key %s\n " , name )
351
359
}
0 commit comments