From e885df2731cb36925c9a9de9cf1a34a167461cd7 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Sun, 6 Dec 2020 12:14:46 -0800 Subject: [PATCH] [dev.regabi] cmd/compile: change iexport to avoid map[ir.Node] In the past, we had a lot of trouble with misusing *types.Sym throughout the frontend, so I tried to push us towards always passing around ONAMEs instead. But for constructing and writing out the symbol indexes for the indexed export data, keying by *types.Sym is exactly what we want. Passes buildall w/ toolstash -cmp. Updates #42982. Change-Id: Idd8f1fb057d75a52a34ebc7788d9332fb49caf8d Reviewed-on: https://go-review.googlesource.com/c/go/+/275755 Trust: Matthew Dempsky Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Cuong Manh Le --- src/cmd/compile/internal/gc/iexport.go | 62 +++++++++++++------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/cmd/compile/internal/gc/iexport.go b/src/cmd/compile/internal/gc/iexport.go index 14614d8ab89..003cf3b446d 100644 --- a/src/cmd/compile/internal/gc/iexport.go +++ b/src/cmd/compile/internal/gc/iexport.go @@ -259,8 +259,8 @@ func iexport(out *bufio.Writer) { p := iexporter{ allPkgs: map[*types.Pkg]bool{}, stringIndex: map[string]uint64{}, - declIndex: map[ir.Node]uint64{}, - inlineIndex: map[ir.Node]uint64{}, + declIndex: map[*types.Sym]uint64{}, + inlineIndex: map[*types.Sym]uint64{}, typIndex: map[*types.Type]uint64{}, } @@ -310,37 +310,34 @@ func iexport(out *bufio.Writer) { out.Write(base.Ctxt.Fingerprint[:]) } -// writeIndex writes out an object index. mainIndex indicates whether +// writeIndex writes out a symbol index. mainIndex indicates whether // we're writing out the main index, which is also read by // non-compiler tools and includes a complete package description // (i.e., name and height). -func (w *exportWriter) writeIndex(index map[ir.Node]uint64, mainIndex bool) { - // Build a map from packages to objects from that package. - pkgObjs := map[*types.Pkg][]ir.Node{} +func (w *exportWriter) writeIndex(index map[*types.Sym]uint64, mainIndex bool) { + // Build a map from packages to symbols from that package. + pkgSyms := map[*types.Pkg][]*types.Sym{} // For the main index, make sure to include every package that // we reference, even if we're not exporting (or reexporting) // any symbols from it. if mainIndex { - pkgObjs[ir.LocalPkg] = nil + pkgSyms[ir.LocalPkg] = nil for pkg := range w.p.allPkgs { - pkgObjs[pkg] = nil + pkgSyms[pkg] = nil } } - for n := range index { - pkgObjs[n.Sym().Pkg] = append(pkgObjs[n.Sym().Pkg], n) + // Group symbols by package. + for sym := range index { + pkgSyms[sym.Pkg] = append(pkgSyms[sym.Pkg], sym) } + // Sort packages by path. var pkgs []*types.Pkg - for pkg, objs := range pkgObjs { + for pkg := range pkgSyms { pkgs = append(pkgs, pkg) - - sort.Slice(objs, func(i, j int) bool { - return objs[i].Sym().Name < objs[j].Sym().Name - }) } - sort.Slice(pkgs, func(i, j int) bool { return pkgs[i].Path < pkgs[j].Path }) @@ -353,11 +350,16 @@ func (w *exportWriter) writeIndex(index map[ir.Node]uint64, mainIndex bool) { w.uint64(uint64(pkg.Height)) } - objs := pkgObjs[pkg] - w.uint64(uint64(len(objs))) - for _, n := range objs { - w.string(n.Sym().Name) - w.uint64(index[n]) + // Sort symbols within a package by name. + syms := pkgSyms[pkg] + sort.Slice(syms, func(i, j int) bool { + return syms[i].Name < syms[j].Name + }) + + w.uint64(uint64(len(syms))) + for _, sym := range syms { + w.string(sym.Name) + w.uint64(index[sym]) } } } @@ -374,8 +376,8 @@ type iexporter struct { stringIndex map[string]uint64 data0 intWriter - declIndex map[ir.Node]uint64 - inlineIndex map[ir.Node]uint64 + declIndex map[*types.Sym]uint64 + inlineIndex map[*types.Sym]uint64 typIndex map[*types.Type]uint64 } @@ -404,11 +406,11 @@ func (p *iexporter) pushDecl(n *ir.Name) { return } - if _, ok := p.declIndex[n]; ok { + if _, ok := p.declIndex[n.Sym()]; ok { return } - p.declIndex[n] = ^uint64(0) // mark n present in work queue + p.declIndex[n.Sym()] = ^uint64(0) // mark n present in work queue p.declTodo.PushRight(n) } @@ -423,13 +425,12 @@ type exportWriter struct { prevColumn int64 } -func (p *iexporter) doDecl(n ir.Node) { +func (p *iexporter) doDecl(n *ir.Name) { w := p.newWriter() w.setPkg(n.Sym().Pkg, false) switch n.Op() { case ir.ONAME: - n := n.(*ir.Name) switch n.Class() { case ir.PEXTERN: // Variable. @@ -455,7 +456,8 @@ func (p *iexporter) doDecl(n ir.Node) { case ir.OLITERAL: // Constant. - n = typecheck(n, ctxExpr) + // TODO(mdempsky): Do we still need this typecheck? If so, why? + n = typecheck(n, ctxExpr).(*ir.Name) w.tag('C') w.pos(n.Pos()) w.value(n.Type(), n.Val()) @@ -509,7 +511,7 @@ func (p *iexporter) doDecl(n ir.Node) { base.Fatalf("unexpected node: %v", n) } - p.declIndex[n] = w.flush() + p.declIndex[n.Sym()] = w.flush() } func (w *exportWriter) tag(tag byte) { @@ -522,7 +524,7 @@ func (p *iexporter) doInline(f *ir.Name) { w.stmtList(ir.AsNodes(f.Func().Inl.Body)) - p.inlineIndex[f] = w.flush() + p.inlineIndex[f.Sym()] = w.flush() } func (w *exportWriter) pos(pos src.XPos) {