]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: always use the compile queue
authorMatthew Dempsky <mdempsky@google.com>
Tue, 12 Jan 2021 19:38:32 +0000 (11:38 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 12 Jan 2021 23:22:04 +0000 (23:22 +0000)
The compiler currently has two modes for compilation: one where it
compiles each function as it sees them, and another where it enqueues
them all into a work queue. A subsequent CL is going to reorder
function compilation to ensure that functions are always compiled
before any non-trivial function literals they enclose, and this will
be easier if we always use the compile work queue.

Also, fewer compilation modes makes things simpler to reason about.

Change-Id: Ie090e81f7476c49486296f2b90911fa0a466a5dd
Reviewed-on: https://go-review.googlesource.com/c/go/+/283313
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/base/debug.go
src/cmd/compile/internal/gc/compile.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/obj.go
src/cmd/compile/internal/liveness/plive.go
test/fixedbugs/issue20250.go

index 3acdcea8463c0aa618ae164714ff3a52c850570a..164941bb26c434c75a0a986ad423b1be14693382 100644 (file)
@@ -32,7 +32,6 @@ type DebugFlags struct {
        Append        int    `help:"print information about append compilation"`
        Checkptr      int    `help:"instrument unsafe pointer conversions"`
        Closure       int    `help:"print information about closure compilation"`
-       CompileLater  int    `help:"compile functions as late as possible"`
        DclStack      int    `help:"run internal dclstack check"`
        Defer         int    `help:"print information about defer compilation"`
        DisableNil    int    `help:"disable nil checks"`
index 25b1c7673711145d6e15e1f5215e958bc6af29d9..b9c10056b4e57c805f1eed251d1afebc6adbbf42 100644 (file)
@@ -26,21 +26,17 @@ var (
        compilequeue []*ir.Func // functions waiting to be compiled
 )
 
-func funccompile(fn *ir.Func) {
+func enqueueFunc(fn *ir.Func) {
        if ir.CurFunc != nil {
-               base.Fatalf("funccompile %v inside %v", fn.Sym(), ir.CurFunc.Sym())
+               base.FatalfAt(fn.Pos(), "enqueueFunc %v inside %v", fn, ir.CurFunc)
        }
 
-       if fn.Type() == nil {
-               if base.Errors() == 0 {
-                       base.Fatalf("funccompile missing type")
-               }
+       if ir.FuncName(fn) == "_" {
+               // Skip compiling blank functions.
+               // Frontend already reported any spec-mandated errors (#29870).
                return
        }
 
-       // assign parameter offsets
-       types.CalcSize(fn.Type())
-
        if len(fn.Body) == 0 {
                // Initialize ABI wrappers if necessary.
                ssagen.InitLSym(fn, false)
@@ -48,35 +44,31 @@ func funccompile(fn *ir.Func) {
                return
        }
 
-       typecheck.DeclContext = ir.PAUTO
-       ir.CurFunc = fn
-       compile(fn)
-       ir.CurFunc = nil
-       typecheck.DeclContext = ir.PEXTERN
+       errorsBefore := base.Errors()
+       prepareFunc(fn)
+       if base.Errors() > errorsBefore {
+               return
+       }
+
+       compilequeue = append(compilequeue, fn)
 }
 
-func compile(fn *ir.Func) {
+// prepareFunc handles any remaining frontend compilation tasks that
+// aren't yet safe to perform concurrently.
+func prepareFunc(fn *ir.Func) {
        // Set up the function's LSym early to avoid data races with the assemblers.
        // Do this before walk, as walk needs the LSym to set attributes/relocations
        // (e.g. in markTypeUsedInInterface).
        ssagen.InitLSym(fn, true)
 
-       errorsBefore := base.Errors()
-       walk.Walk(fn)
-       if base.Errors() > errorsBefore {
-               return
-       }
-
-       // From this point, there should be no uses of Curfn. Enforce that.
-       ir.CurFunc = nil
+       // Calculate parameter offsets.
+       types.CalcSize(fn.Type())
 
-       if ir.FuncName(fn) == "_" {
-               // We don't need to generate code for this function, just report errors in its body.
-               // At this point we've generated any errors needed.
-               // (Beyond here we generate only non-spec errors, like "stack frame too large".)
-               // See issue 29870.
-               return
-       }
+       typecheck.DeclContext = ir.PAUTO
+       ir.CurFunc = fn
+       walk.Walk(fn)
+       ir.CurFunc = nil // enforce no further uses of CurFunc
+       typecheck.DeclContext = ir.PEXTERN
 
        // Make sure type syms are declared for all types that might
        // be types of stack objects. We need to do this here
@@ -95,28 +87,6 @@ func compile(fn *ir.Func) {
                        }
                }
        }
-
-       if compilenow(fn) {
-               ssagen.Compile(fn, 0)
-       } else {
-               compilequeue = append(compilequeue, fn)
-       }
-}
-
-// compilenow reports whether to compile immediately.
-// If functions are not compiled immediately,
-// they are enqueued in compilequeue,
-// which is drained by compileFunctions.
-func compilenow(fn *ir.Func) bool {
-       // Issue 38068: if this function is a method AND an inline
-       // candidate AND was not inlined (yet), put it onto the compile
-       // queue instead of compiling it immediately. This is in case we
-       // wind up inlining it into a method wrapper that is generated by
-       // compiling a function later on in the Target.Decls list.
-       if ir.IsMethod(fn) && isInlinableButNotInlined(fn) {
-               return false
-       }
-       return base.Flag.LowerC == 1 && base.Debug.CompileLater == 0
 }
 
 // compileFunctions compiles all functions in compilequeue.
@@ -163,16 +133,3 @@ func compileFunctions() {
                types.CalcSizeDisabled = false
        }
 }
-
-// isInlinableButNotInlined returns true if 'fn' was marked as an
-// inline candidate but then never inlined (presumably because we
-// found no call sites).
-func isInlinableButNotInlined(fn *ir.Func) bool {
-       if fn.Inl == nil {
-               return false
-       }
-       if fn.Sym() == nil {
-               return true
-       }
-       return !fn.Linksym().WasInlined()
-}
index 1541bc4285f21702c3d6748ae618f315917a854d..2903d64ff8993d7c6caae309d3944c2d76043876 100644 (file)
@@ -300,9 +300,8 @@ func Main(archInit func(*ssagen.ArchInfo)) {
        base.Timer.Start("be", "compilefuncs")
        fcount := int64(0)
        for i := 0; i < len(typecheck.Target.Decls); i++ {
-               n := typecheck.Target.Decls[i]
-               if n.Op() == ir.ODCLFUNC {
-                       funccompile(n.(*ir.Func))
+               if fn, ok := typecheck.Target.Decls[i].(*ir.Func); ok {
+                       enqueueFunc(fn)
                        fcount++
                }
        }
index fbb2145e1b10b9787fd061df3cccd1ff2fcf36e2..753db80f764b1d201284a28b6e71219320ff47ac 100644 (file)
@@ -131,9 +131,8 @@ func dumpdata() {
        // It was not until issue 24761 that we found any code that required a loop at all.
        for {
                for i := numDecls; i < len(typecheck.Target.Decls); i++ {
-                       n := typecheck.Target.Decls[i]
-                       if n.Op() == ir.ODCLFUNC {
-                               funccompile(n.(*ir.Func))
+                       if n, ok := typecheck.Target.Decls[i].(*ir.Func); ok {
+                               enqueueFunc(n)
                        }
                }
                numDecls = len(typecheck.Target.Decls)
index 26d90824b289739e838873e0b615779934694fc4..8d1754c81380b5496fb37553fbe9cbf231a9af2c 100644 (file)
@@ -1223,6 +1223,7 @@ func WriteFuncMap(fn *ir.Func) {
        if ir.FuncName(fn) == "_" || fn.Sym().Linkname != "" {
                return
        }
+       types.CalcSize(fn.Type())
        lsym := base.Ctxt.Lookup(fn.LSym.Name + ".args_stackmap")
        nptr := int(fn.Type().ArgWidth() / int64(types.PtrSize))
        bv := bitvec.New(int32(nptr) * 2)
index c190515274af21ca0cc186a0d24f810a63e3b488..1a513bea56df1f916dfe77d99b0f8f72733a6d28 100644 (file)
@@ -1,4 +1,4 @@
-// errorcheck -0 -live -l -d=compilelater
+// errorcheck -0 -live -l
 
 // Copyright 2017 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style