Skip to content

Commit cf68384

Browse files
mdempskygopherbot
authored andcommitted
cmd/compile/internal/gc: steps towards work-queue
[This is a reattempt of go.dev/cl/520611.] 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: I7502798a8662b3cec92d3001169f3af4f804df2a Reviewed-on: https://go-review.googlesource.com/c/go/+/522339 Reviewed-by: Than McIntosh <[email protected]> Reviewed-by: Cuong Manh Le <[email protected]> Run-TryBot: Matthew Dempsky <[email protected]> Auto-Submit: Matthew Dempsky <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 96b6e78 commit cf68384

File tree

5 files changed

+84
-72
lines changed

5 files changed

+84
-72
lines changed

src/cmd/compile/internal/gc/compile.go

-4
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,6 @@ func prepareFunc(fn *ir.Func) {
113113
// It fans out nBackendWorkers to do the work
114114
// and waits for them to complete.
115115
func compileFunctions() {
116-
if len(compilequeue) == 0 {
117-
return
118-
}
119-
120116
if race.Enabled {
121117
// Randomize compilation order to try to shake out races.
122118
tmp := make([]*ir.Func, len(compilequeue))

src/cmd/compile/internal/gc/main.go

+54-18
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"cmd/compile/internal/noder"
2020
"cmd/compile/internal/pgo"
2121
"cmd/compile/internal/pkginit"
22+
"cmd/compile/internal/reflectdata"
2223
"cmd/compile/internal/ssa"
2324
"cmd/compile/internal/ssagen"
2425
"cmd/compile/internal/staticinit"
@@ -295,18 +296,62 @@ func Main(archInit func(*ssagen.ArchInfo)) {
295296

296297
ir.CurFunc = nil
297298

298-
// Compile top level functions.
299-
// Don't use range--walk can add functions to Target.Decls.
299+
reflectdata.WriteBasicTypes()
300+
301+
// Compile top-level declarations.
302+
//
303+
// There are cyclic dependencies between all of these phases, so we
304+
// need to iterate all of them until we reach a fixed point.
300305
base.Timer.Start("be", "compilefuncs")
301-
fcount := int64(0)
302-
for i := 0; i < len(typecheck.Target.Funcs); i++ {
303-
fn := typecheck.Target.Funcs[i]
304-
enqueueFunc(fn)
305-
fcount++
306+
for nextFunc, nextExtern := 0, 0; ; {
307+
reflectdata.WriteRuntimeTypes()
308+
309+
if nextExtern < len(typecheck.Target.Externs) {
310+
switch n := typecheck.Target.Externs[nextExtern]; n.Op() {
311+
case ir.ONAME:
312+
dumpGlobal(n)
313+
case ir.OLITERAL:
314+
dumpGlobalConst(n)
315+
case ir.OTYPE:
316+
reflectdata.NeedRuntimeType(n.Type())
317+
}
318+
nextExtern++
319+
continue
320+
}
321+
322+
if nextFunc < len(typecheck.Target.Funcs) {
323+
enqueueFunc(typecheck.Target.Funcs[nextFunc])
324+
nextFunc++
325+
continue
326+
}
327+
328+
// The SSA backend supports using multiple goroutines, so keep it
329+
// as late as possible to maximize how much work we can batch and
330+
// process concurrently.
331+
if len(compilequeue) != 0 {
332+
compileFunctions()
333+
continue
334+
}
335+
336+
// Finalize DWARF inline routine DIEs, then explicitly turn off
337+
// further DWARF inlining generation to avoid problems with
338+
// generated method wrappers.
339+
//
340+
// Note: The DWARF fixup code for inlined calls currently doesn't
341+
// allow multiple invocations, so we intentionally run it just
342+
// once after everything else. Worst case, some generated
343+
// functions have slightly larger DWARF DIEs.
344+
if base.Ctxt.DwFixups != nil {
345+
base.Ctxt.DwFixups.Finalize(base.Ctxt.Pkgpath, base.Debug.DwarfInl != 0)
346+
base.Ctxt.DwFixups = nil
347+
base.Flag.GenDwarfInl = 0
348+
continue // may have called reflectdata.TypeLinksym (#62156)
349+
}
350+
351+
break
306352
}
307-
base.Timer.AddEvent(fcount, "funcs")
308353

309-
compileFunctions()
354+
base.Timer.AddEvent(int64(len(typecheck.Target.Funcs)), "funcs")
310355

311356
if base.Flag.CompilingRuntime {
312357
// Write barriers are now known. Check the call graph.
@@ -318,15 +363,6 @@ func Main(archInit func(*ssagen.ArchInfo)) {
318363
staticinit.AddKeepRelocations()
319364
}
320365

321-
// Finalize DWARF inline routine DIEs, then explicitly turn off
322-
// DWARF inlining gen so as to avoid problems with generated
323-
// method wrappers.
324-
if base.Ctxt.DwFixups != nil {
325-
base.Ctxt.DwFixups.Finalize(base.Ctxt.Pkgpath, base.Debug.DwarfInl != 0)
326-
base.Ctxt.DwFixups = nil
327-
base.Flag.GenDwarfInl = 0
328-
}
329-
330366
// Write object data to disk.
331367
base.Timer.Start("be", "dumpobj")
332368
dumpdata()

src/cmd/compile/internal/gc/obj.go

+1-50
Original file line numberDiff line numberDiff line change
@@ -110,39 +110,11 @@ func dumpCompilerObj(bout *bio.Writer) {
110110
}
111111

112112
func dumpdata() {
113-
numExterns := len(typecheck.Target.Externs)
114-
numDecls := len(typecheck.Target.Funcs)
115-
dumpglobls(typecheck.Target.Externs)
116-
addsignats(typecheck.Target.Externs)
117-
reflectdata.WriteRuntimeTypes()
113+
reflectdata.WriteGCSymbols()
118114
reflectdata.WritePluginTable()
119115
reflectdata.WriteImportStrings()
120-
reflectdata.WriteBasicTypes()
121116
dumpembeds()
122117

123-
// Calls to WriteRuntimeTypes can generate functions,
124-
// like method wrappers and hash and equality routines.
125-
// Compile any generated functions, process any new resulting types, repeat.
126-
// This can't loop forever, because there is no way to generate an infinite
127-
// number of types in a finite amount of code.
128-
// In the typical case, we loop 0 or 1 times.
129-
// It was not until issue 24761 that we found any code that required a loop at all.
130-
for {
131-
for i := numDecls; i < len(typecheck.Target.Funcs); i++ {
132-
fn := typecheck.Target.Funcs[i]
133-
enqueueFunc(fn)
134-
}
135-
numDecls = len(typecheck.Target.Funcs)
136-
compileFunctions()
137-
reflectdata.WriteRuntimeTypes()
138-
if numDecls == len(typecheck.Target.Funcs) {
139-
break
140-
}
141-
}
142-
143-
// Dump extra globals.
144-
dumpglobls(typecheck.Target.Externs[numExterns:])
145-
146118
if reflectdata.ZeroSize > 0 {
147119
zero := base.PkgLinksym("go:map", "zero", obj.ABI0)
148120
objw.Global(zero, int32(reflectdata.ZeroSize), obj.DUPOK|obj.RODATA)
@@ -217,18 +189,6 @@ func dumpGlobalConst(n *ir.Name) {
217189
base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym().Name, types.TypeSymName(t), ir.IntVal(t, v))
218190
}
219191

220-
func dumpglobls(externs []*ir.Name) {
221-
// add globals
222-
for _, n := range externs {
223-
switch n.Op() {
224-
case ir.ONAME:
225-
dumpGlobal(n)
226-
case ir.OLITERAL:
227-
dumpGlobalConst(n)
228-
}
229-
}
230-
}
231-
232192
// addGCLocals adds gcargs, gclocals, gcregs, and stack object symbols to Ctxt.Data.
233193
//
234194
// This is done during the sequential phase after compilation, since
@@ -323,12 +283,3 @@ func dumpembeds() {
323283
staticdata.WriteEmbed(v)
324284
}
325285
}
326-
327-
func addsignats(dcls []*ir.Name) {
328-
// copy types from dcl list to signatset
329-
for _, n := range dcls {
330-
if n.Op() == ir.OTYPE {
331-
reflectdata.NeedRuntimeType(n.Type())
332-
}
333-
}
334-
}

src/cmd/compile/internal/reflectdata/reflect.go

+2
Original file line numberDiff line numberDiff line change
@@ -1266,7 +1266,9 @@ func WriteRuntimeTypes() {
12661266
}
12671267
signatslice = signatslice[len(signats):]
12681268
}
1269+
}
12691270

1271+
func WriteGCSymbols() {
12701272
// Emit GC data symbols.
12711273
gcsyms := make([]typeAndStr, 0, len(gcsymset))
12721274
for t := range gcsymset {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Regression test for https://go.dev/issue/62156:
2+
# DWARF generation for inlined functions may require more runtime type
3+
# descriptors to be written.
4+
5+
go build
6+
7+
-- go.mod --
8+
module m
9+
10+
go 1.20
11+
-- main.go --
12+
package main
13+
14+
import "m/sub"
15+
16+
func main() { sub.F() }
17+
-- sub/sub.go --
18+
package sub
19+
20+
type iface interface{ m() }
21+
22+
func F() {
23+
f := func(rt []iface) []iface {
24+
return append([]iface{}, rt...)
25+
}
26+
f(nil)
27+
}

0 commit comments

Comments
 (0)