]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/gc: steps towards work-queue
authorMatthew Dempsky <mdempsky@google.com>
Fri, 18 Aug 2023 07:32:11 +0000 (00:32 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 18 Aug 2023 22:42:12 +0000 (22:42 +0000)
This CL reorganizes the top-level functions for handling package-level
declarations, runtime type descriptors, and SSA compilation to work in
a loop. This generalizes the loop that previously existed in dumpdata.

Change-Id: I0e51e60f6ef9e7f96a4a3ccd5801f7baf83eba9a
Reviewed-on: https://go-review.googlesource.com/c/go/+/520611
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
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/reflectdata/reflect.go

index a2ffed7b00882cba94f6e8191ed1293c33262418..b3e8e0e94156352e0d6e974501da555a861a23d8 100644 (file)
@@ -113,10 +113,6 @@ func prepareFunc(fn *ir.Func) {
 // It fans out nBackendWorkers to do the work
 // and waits for them to complete.
 func compileFunctions() {
-       if len(compilequeue) == 0 {
-               return
-       }
-
        if race.Enabled {
                // Randomize compilation order to try to shake out races.
                tmp := make([]*ir.Func, len(compilequeue))
index ae695b58f9e1a6fba58574d3156ee0badc49c9a5..5e8ffb34ab63853c00c1620d59a1f10363084037 100644 (file)
@@ -298,18 +298,47 @@ func Main(archInit func(*ssagen.ArchInfo)) {
 
        ir.CurFunc = nil
 
-       // Compile top level functions.
-       // Don't use range--walk can add functions to Target.Decls.
+       reflectdata.WriteBasicTypes()
+
+       // Compile top-level declarations.
+       //
+       // There are cyclic dependencies between all of these phases, so we
+       // need to iterate all of them until we reach a fixed point.
        base.Timer.Start("be", "compilefuncs")
-       fcount := int64(0)
-       for i := 0; i < len(typecheck.Target.Funcs); i++ {
-               fn := typecheck.Target.Funcs[i]
-               enqueueFunc(fn)
-               fcount++
+       for nextFunc, nextExtern := 0, 0; ; {
+               reflectdata.WriteRuntimeTypes()
+
+               if nextExtern < len(typecheck.Target.Externs) {
+                       switch n := typecheck.Target.Externs[nextExtern]; n.Op() {
+                       case ir.ONAME:
+                               dumpGlobal(n)
+                       case ir.OLITERAL:
+                               dumpGlobalConst(n)
+                       case ir.OTYPE:
+                               reflectdata.NeedRuntimeType(n.Type())
+                       }
+                       nextExtern++
+                       continue
+               }
+
+               if nextFunc < len(typecheck.Target.Funcs) {
+                       enqueueFunc(typecheck.Target.Funcs[nextFunc])
+                       nextFunc++
+                       continue
+               }
+
+               // The SSA backend supports using multiple goroutines, so keep it
+               // as the last step to maximize how much work we can batch and
+               // process concurrently.
+               if len(compilequeue) != 0 {
+                       compileFunctions()
+                       continue
+               }
+
+               break
        }
-       base.Timer.AddEvent(fcount, "funcs")
 
-       compileFunctions()
+       base.Timer.AddEvent(int64(len(typecheck.Target.Funcs)), "funcs")
 
        if base.Flag.CompilingRuntime {
                // Write barriers are now known. Check the call graph.
index 4ff249ca2e0d967fd62ffa65d479ee6dee5a2416..249eeb221dd6ccb386879b0fc6023ec296aa2440 100644 (file)
@@ -110,39 +110,11 @@ func dumpCompilerObj(bout *bio.Writer) {
 }
 
 func dumpdata() {
-       numExterns := len(typecheck.Target.Externs)
-       numDecls := len(typecheck.Target.Funcs)
-       dumpglobls(typecheck.Target.Externs)
-       addsignats(typecheck.Target.Externs)
-       reflectdata.WriteRuntimeTypes()
+       reflectdata.WriteGCSymbols()
        reflectdata.WritePluginTable()
        reflectdata.WriteImportStrings()
-       reflectdata.WriteBasicTypes()
        dumpembeds()
 
-       // Calls to WriteRuntimeTypes can generate functions,
-       // like method wrappers and hash and equality routines.
-       // Compile any generated functions, process any new resulting types, repeat.
-       // This can't loop forever, because there is no way to generate an infinite
-       // number of types in a finite amount of code.
-       // In the typical case, we loop 0 or 1 times.
-       // 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.Funcs); i++ {
-                       fn := typecheck.Target.Funcs[i]
-                       enqueueFunc(fn)
-               }
-               numDecls = len(typecheck.Target.Funcs)
-               compileFunctions()
-               reflectdata.WriteRuntimeTypes()
-               if numDecls == len(typecheck.Target.Funcs) {
-                       break
-               }
-       }
-
-       // Dump extra globals.
-       dumpglobls(typecheck.Target.Externs[numExterns:])
-
        if reflectdata.ZeroSize > 0 {
                zero := base.PkgLinksym("go:map", "zero", obj.ABI0)
                objw.Global(zero, int32(reflectdata.ZeroSize), obj.DUPOK|obj.RODATA)
@@ -217,18 +189,6 @@ func dumpGlobalConst(n *ir.Name) {
        base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym().Name, types.TypeSymName(t), ir.IntVal(t, v))
 }
 
-func dumpglobls(externs []*ir.Name) {
-       // add globals
-       for _, n := range externs {
-               switch n.Op() {
-               case ir.ONAME:
-                       dumpGlobal(n)
-               case ir.OLITERAL:
-                       dumpGlobalConst(n)
-               }
-       }
-}
-
 // addGCLocals adds gcargs, gclocals, gcregs, and stack object symbols to Ctxt.Data.
 //
 // This is done during the sequential phase after compilation, since
@@ -323,12 +283,3 @@ func dumpembeds() {
                staticdata.WriteEmbed(v)
        }
 }
-
-func addsignats(dcls []*ir.Name) {
-       // copy types from dcl list to signatset
-       for _, n := range dcls {
-               if n.Op() == ir.OTYPE {
-                       reflectdata.NeedRuntimeType(n.Type())
-               }
-       }
-}
index 2e5301c82348fe95907bcbadea39baa591f58b91..ac0f1a96d8e2b67ed077b66d740d245ed473d7f4 100644 (file)
@@ -1264,7 +1264,9 @@ func WriteRuntimeTypes() {
                }
                signatslice = signatslice[len(signats):]
        }
+}
 
+func WriteGCSymbols() {
        // Emit GC data symbols.
        gcsyms := make([]typeAndStr, 0, len(gcsymset))
        for t := range gcsymset {