1
0
mirror of https://github.com/golang/go synced 2024-11-18 11:55:01 -07:00

[dev.link] cmd/compile: emit fewer R_USETYPE relocations

Background: when compiling a function, it's possible that a local
variable will be optimized away, which could potentially degrade the
debugging experience if the compiler fails to emit DWARF information
for the variable's type. To mitigate this situation, the compiler
emits R_USETYPE relocations for the function's auto/param variables as
a signal to the linker to generate DWARF for the types in question,
even if the type is not specifically attached to a DWARF param or var.

This patch change the logic in the compiler to avoid emitting a
R_USETYPE relocation if the type in question is already referenced by
a concrete DWARF param or auto record. This cuts down on the amount of
work the linker has to do, also makes object files a bit smaller on
average (about 1% for the runtime package).

Change-Id: I4d24da458d0658edf90c5dca0bf21d5ddc3961d8
Reviewed-on: https://go-review.googlesource.com/c/go/+/234837
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Than McIntosh 2020-05-21 07:16:29 -04:00
parent 8ca2eae206
commit 6265ed7452

View File

@ -428,9 +428,10 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
decls, dwarfVars := createDwarfVars(fnsym, fn.Func, apdecls) decls, dwarfVars := createDwarfVars(fnsym, fn.Func, apdecls)
// For each type referenced by the functions auto vars, attach a // For each type referenced by the functions auto vars but not
// dummy relocation to the function symbol to insure that the type // already referenced by a dwarf var, attach a dummy relocation to
// included in DWARF processing during linking. // the function symbol to insure that the type included in DWARF
// processing during linking.
typesyms := []*obj.LSym{} typesyms := []*obj.LSym{}
for t, _ := range fnsym.Func.Autot { for t, _ := range fnsym.Func.Autot {
typesyms = append(typesyms, t) typesyms = append(typesyms, t)
@ -480,7 +481,7 @@ func declPos(decl *Node) src.XPos {
// createSimpleVars creates a DWARF entry for every variable declared in the // createSimpleVars creates a DWARF entry for every variable declared in the
// function, claiming that they are permanently on the stack. // function, claiming that they are permanently on the stack.
func createSimpleVars(apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) { func createSimpleVars(fnsym *obj.LSym, apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
var vars []*dwarf.Var var vars []*dwarf.Var
var decls []*Node var decls []*Node
selected := make(map[*Node]bool) selected := make(map[*Node]bool)
@ -490,13 +491,13 @@ func createSimpleVars(apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
} }
decls = append(decls, n) decls = append(decls, n)
vars = append(vars, createSimpleVar(n)) vars = append(vars, createSimpleVar(fnsym, n))
selected[n] = true selected[n] = true
} }
return decls, vars, selected return decls, vars, selected
} }
func createSimpleVar(n *Node) *dwarf.Var { func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
var abbrev int var abbrev int
offs := n.Xoffset offs := n.Xoffset
@ -519,6 +520,7 @@ func createSimpleVar(n *Node) *dwarf.Var {
} }
typename := dwarf.InfoPrefix + typesymname(n.Type) typename := dwarf.InfoPrefix + typesymname(n.Type)
delete(fnsym.Func.Autot, ngotype(n).Linksym())
inlIndex := 0 inlIndex := 0
if genDwarfInline > 1 { if genDwarfInline > 1 {
if n.Name.InlFormal() || n.Name.InlLocal() { if n.Name.InlFormal() || n.Name.InlLocal() {
@ -546,7 +548,7 @@ func createSimpleVar(n *Node) *dwarf.Var {
// createComplexVars creates recomposed DWARF vars with location lists, // createComplexVars creates recomposed DWARF vars with location lists,
// suitable for describing optimized code. // suitable for describing optimized code.
func createComplexVars(fn *Func) ([]*Node, []*dwarf.Var, map[*Node]bool) { func createComplexVars(fnsym *obj.LSym, fn *Func) ([]*Node, []*dwarf.Var, map[*Node]bool) {
debugInfo := fn.DebugInfo debugInfo := fn.DebugInfo
// Produce a DWARF variable entry for each user variable. // Produce a DWARF variable entry for each user variable.
@ -561,7 +563,7 @@ func createComplexVars(fn *Func) ([]*Node, []*dwarf.Var, map[*Node]bool) {
ssaVars[debugInfo.Slots[slot].N.(*Node)] = true ssaVars[debugInfo.Slots[slot].N.(*Node)] = true
} }
if dvar := createComplexVar(fn, ssa.VarID(varID)); dvar != nil { if dvar := createComplexVar(fnsym, fn, ssa.VarID(varID)); dvar != nil {
decls = append(decls, n) decls = append(decls, n)
vars = append(vars, dvar) vars = append(vars, dvar)
} }
@ -578,9 +580,9 @@ func createDwarfVars(fnsym *obj.LSym, fn *Func, apDecls []*Node) ([]*Node, []*dw
var decls []*Node var decls []*Node
var selected map[*Node]bool var selected map[*Node]bool
if Ctxt.Flag_locationlists && Ctxt.Flag_optimize && fn.DebugInfo != nil { if Ctxt.Flag_locationlists && Ctxt.Flag_optimize && fn.DebugInfo != nil {
decls, vars, selected = createComplexVars(fn) decls, vars, selected = createComplexVars(fnsym, fn)
} else { } else {
decls, vars, selected = createSimpleVars(apDecls) decls, vars, selected = createSimpleVars(fnsym, apDecls)
} }
dcl := apDecls dcl := apDecls
@ -616,7 +618,7 @@ func createDwarfVars(fnsym *obj.LSym, fn *Func, apDecls []*Node) ([]*Node, []*dw
// Args not of SSA-able type are treated here; they // Args not of SSA-able type are treated here; they
// are homed on the stack in a single place for the // are homed on the stack in a single place for the
// entire call. // entire call.
vars = append(vars, createSimpleVar(n)) vars = append(vars, createSimpleVar(fnsym, n))
decls = append(decls, n) decls = append(decls, n)
continue continue
} }
@ -712,7 +714,7 @@ func stackOffset(slot ssa.LocalSlot) int32 {
} }
// createComplexVar builds a single DWARF variable entry and location list. // createComplexVar builds a single DWARF variable entry and location list.
func createComplexVar(fn *Func, varID ssa.VarID) *dwarf.Var { func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
debug := fn.DebugInfo debug := fn.DebugInfo
n := debug.Vars[varID].(*Node) n := debug.Vars[varID].(*Node)
@ -727,6 +729,7 @@ func createComplexVar(fn *Func, varID ssa.VarID) *dwarf.Var {
} }
gotype := ngotype(n).Linksym() gotype := ngotype(n).Linksym()
delete(fnsym.Func.Autot, gotype)
typename := dwarf.InfoPrefix + gotype.Name[len("type."):] typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
inlIndex := 0 inlIndex := 0
if genDwarfInline > 1 { if genDwarfInline > 1 {