From e47fad515d50f685677b7418ae3fc24a0849f663 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Sat, 19 Aug 2023 20:09:05 +0000 Subject: [PATCH] Revert "cmd/compile/internal/gc: steps towards work-queue" This reverts commit CL 520611. Reason for revert: #62156. Change-Id: Iebd17bdfc00824de3d5011a74d071a41c4fa06f1 Reviewed-on: https://go-review.googlesource.com/c/go/+/521155 Auto-Submit: Matthew Dempsky Run-TryBot: Matthew Dempsky Reviewed-by: Dmitri Shuralyov TryBot-Result: Gopher Robot Reviewed-by: Dmitri Shuralyov --- src/cmd/compile/internal/gc/compile.go | 4 ++ src/cmd/compile/internal/gc/main.go | 47 ++++------------- src/cmd/compile/internal/gc/obj.go | 51 ++++++++++++++++++- .../compile/internal/reflectdata/reflect.go | 2 - 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/src/cmd/compile/internal/gc/compile.go b/src/cmd/compile/internal/gc/compile.go index b3e8e0e941..a2ffed7b00 100644 --- a/src/cmd/compile/internal/gc/compile.go +++ b/src/cmd/compile/internal/gc/compile.go @@ -113,6 +113,10 @@ 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)) diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index 5e8ffb34ab..ae695b58f9 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -298,47 +298,18 @@ func Main(archInit func(*ssagen.ArchInfo)) { ir.CurFunc = nil - 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. + // Compile top level functions. + // Don't use range--walk can add functions to Target.Decls. base.Timer.Start("be", "compilefuncs") - 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 + fcount := int64(0) + for i := 0; i < len(typecheck.Target.Funcs); i++ { + fn := typecheck.Target.Funcs[i] + enqueueFunc(fn) + fcount++ } + base.Timer.AddEvent(fcount, "funcs") - base.Timer.AddEvent(int64(len(typecheck.Target.Funcs)), "funcs") + compileFunctions() if base.Flag.CompilingRuntime { // Write barriers are now known. Check the call graph. diff --git a/src/cmd/compile/internal/gc/obj.go b/src/cmd/compile/internal/gc/obj.go index 249eeb221d..4ff249ca2e 100644 --- a/src/cmd/compile/internal/gc/obj.go +++ b/src/cmd/compile/internal/gc/obj.go @@ -110,11 +110,39 @@ func dumpCompilerObj(bout *bio.Writer) { } func dumpdata() { - reflectdata.WriteGCSymbols() + numExterns := len(typecheck.Target.Externs) + numDecls := len(typecheck.Target.Funcs) + dumpglobls(typecheck.Target.Externs) + addsignats(typecheck.Target.Externs) + reflectdata.WriteRuntimeTypes() 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) @@ -189,6 +217,18 @@ 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 @@ -283,3 +323,12 @@ 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()) + } + } +} diff --git a/src/cmd/compile/internal/reflectdata/reflect.go b/src/cmd/compile/internal/reflectdata/reflect.go index ac0f1a96d8..2e5301c823 100644 --- a/src/cmd/compile/internal/reflectdata/reflect.go +++ b/src/cmd/compile/internal/reflectdata/reflect.go @@ -1264,9 +1264,7 @@ func WriteRuntimeTypes() { } signatslice = signatslice[len(signats):] } -} -func WriteGCSymbols() { // Emit GC data symbols. gcsyms := make([]typeAndStr, 0, len(gcsymset)) for t := range gcsymset {