]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add Func.SetNilCheckDisabled
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 4 May 2017 14:55:00 +0000 (07:55 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 5 May 2017 19:34:09 +0000 (19:34 +0000)
Generated hash and eq routines don't need nil checks.
Prior to this CL, this was accomplished by
temporarily incrementing the global variable disable_checknil.
However, that increment lasted only the lifetime of the
call to funccompile. After CL 41503, funccompile may
do nothing but enqueue the function for compilation,
resulting in nil checks being generated.

Fix this by adding an explicit flag to a function
indicating whether nil checks should be disabled
for that function.

While we're here, allow concurrent compilation
with the -w and -W flags, since that was needed
to investigate this issue.

Fixes #20242

Change-Id: Ib9140c22c49e9a09e62fa3cf350f5d3eff18e2bd
Reviewed-on: https://go-review.googlesource.com/42591
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/syntax.go

index 8bdb7fc349aee5dfbfaf6fee40c6b6d36969414a..0b4c9c7b3f64b9c850b55d6c81fa7c650e6ff3f5 100644 (file)
@@ -311,9 +311,8 @@ func genhash(sym *types.Sym, t *types.Type) {
        old_safemode := safemode
        safemode = false
 
-       disable_checknil++
+       fn.Func.SetNilCheckDisabled(true)
        funccompile(fn)
-       disable_checknil--
 
        safemode = old_safemode
 }
@@ -500,12 +499,10 @@ func geneq(sym *types.Sym, t *types.Type) {
        // We are comparing a struct or an array,
        // neither of which can be nil, and our comparisons
        // are shallow.
-       disable_checknil++
-
+       fn.Func.SetNilCheckDisabled(true)
        funccompile(fn)
 
        safemode = old_safemode
-       disable_checknil--
 }
 
 // eqfield returns the node
index ce84024174345fe5654d9bfa193e3d42633797eb..058c08ec4f861629a0de09410755fef93d64737f 100644 (file)
@@ -1087,6 +1087,8 @@ var concurrentFlagOK = [256]bool{
        'I': true, // add `directory` to import search path
        'N': true, // disable optimizations
        'l': true, // disable inlining
+       'w': true, // all printing happens before compilation
+       'W': true, // all printing happens before compilation
 }
 
 func concurrentBackendAllowed() bool {
index 926bc9d72465dc15e3f1b17b05e6e24e816da105..d058118f2781287ad62f6eef4d21af32325f8b52 100644 (file)
@@ -3399,7 +3399,7 @@ func (s *state) exprPtr(n *Node, bounded bool, lineno src.XPos) *ssa.Value {
 // Used only for automatically inserted nil checks,
 // not for user code like 'x != nil'.
 func (s *state) nilCheck(ptr *ssa.Value) {
-       if disable_checknil != 0 {
+       if disable_checknil != 0 || s.curfn.Func.NilCheckDisabled() {
                return
        }
        s.newValue2(ssa.OpNilCheck, ssa.TypeVoid, ptr, s.mem())
index 234ebad41c62b8cc613ba0d6d77cc0f4e0283255..9b1eeaf43e83c7bd0d1a237304e506219c585af8 100644 (file)
@@ -386,25 +386,28 @@ const (
        funcNeedctxt                  // function uses context register (has closure variables)
        funcReflectMethod             // function calls reflect.Type.Method or MethodByName
        funcIsHiddenClosure
-       funcNoFramePointer // Must not use a frame pointer for this function
-       funcHasDefer       // contains a defer statement
+       funcNoFramePointer   // Must not use a frame pointer for this function
+       funcHasDefer         // contains a defer statement
+       funcNilCheckDisabled // disable nil checks when compiling this function
 )
 
-func (f *Func) Dupok() bool           { return f.flags&funcDupok != 0 }
-func (f *Func) Wrapper() bool         { return f.flags&funcWrapper != 0 }
-func (f *Func) Needctxt() bool        { return f.flags&funcNeedctxt != 0 }
-func (f *Func) ReflectMethod() bool   { return f.flags&funcReflectMethod != 0 }
-func (f *Func) IsHiddenClosure() bool { return f.flags&funcIsHiddenClosure != 0 }
-func (f *Func) NoFramePointer() bool  { return f.flags&funcNoFramePointer != 0 }
-func (f *Func) HasDefer() bool        { return f.flags&funcHasDefer != 0 }
-
-func (f *Func) SetDupok(b bool)           { f.flags.set(funcDupok, b) }
-func (f *Func) SetWrapper(b bool)         { f.flags.set(funcWrapper, b) }
-func (f *Func) SetNeedctxt(b bool)        { f.flags.set(funcNeedctxt, b) }
-func (f *Func) SetReflectMethod(b bool)   { f.flags.set(funcReflectMethod, b) }
-func (f *Func) SetIsHiddenClosure(b bool) { f.flags.set(funcIsHiddenClosure, b) }
-func (f *Func) SetNoFramePointer(b bool)  { f.flags.set(funcNoFramePointer, b) }
-func (f *Func) SetHasDefer(b bool)        { f.flags.set(funcHasDefer, b) }
+func (f *Func) Dupok() bool            { return f.flags&funcDupok != 0 }
+func (f *Func) Wrapper() bool          { return f.flags&funcWrapper != 0 }
+func (f *Func) Needctxt() bool         { return f.flags&funcNeedctxt != 0 }
+func (f *Func) ReflectMethod() bool    { return f.flags&funcReflectMethod != 0 }
+func (f *Func) IsHiddenClosure() bool  { return f.flags&funcIsHiddenClosure != 0 }
+func (f *Func) NoFramePointer() bool   { return f.flags&funcNoFramePointer != 0 }
+func (f *Func) HasDefer() bool         { return f.flags&funcHasDefer != 0 }
+func (f *Func) NilCheckDisabled() bool { return f.flags&funcNilCheckDisabled != 0 }
+
+func (f *Func) SetDupok(b bool)            { f.flags.set(funcDupok, b) }
+func (f *Func) SetWrapper(b bool)          { f.flags.set(funcWrapper, b) }
+func (f *Func) SetNeedctxt(b bool)         { f.flags.set(funcNeedctxt, b) }
+func (f *Func) SetReflectMethod(b bool)    { f.flags.set(funcReflectMethod, b) }
+func (f *Func) SetIsHiddenClosure(b bool)  { f.flags.set(funcIsHiddenClosure, b) }
+func (f *Func) SetNoFramePointer(b bool)   { f.flags.set(funcNoFramePointer, b) }
+func (f *Func) SetHasDefer(b bool)         { f.flags.set(funcHasDefer, b) }
+func (f *Func) SetNilCheckDisabled(b bool) { f.flags.set(funcNilCheckDisabled, b) }
 
 type Op uint8