1
0
mirror of https://github.com/golang/go synced 2024-09-30 17:38:33 -06: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)
// For each type referenced by the functions auto vars, attach a
// dummy relocation to the function symbol to insure that the type
// included in DWARF processing during linking.
// For each type referenced by the functions auto vars but not
// already referenced by a dwarf var, attach a dummy relocation to
// the function symbol to insure that the type included in DWARF
// processing during linking.
typesyms := []*obj.LSym{}
for t, _ := range fnsym.Func.Autot {
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
// 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 decls []*Node
selected := make(map[*Node]bool)
@ -490,13 +491,13 @@ func createSimpleVars(apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
}
decls = append(decls, n)
vars = append(vars, createSimpleVar(n))
vars = append(vars, createSimpleVar(fnsym, n))
selected[n] = true
}
return decls, vars, selected
}
func createSimpleVar(n *Node) *dwarf.Var {
func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
var abbrev int
offs := n.Xoffset
@ -519,6 +520,7 @@ func createSimpleVar(n *Node) *dwarf.Var {
}
typename := dwarf.InfoPrefix + typesymname(n.Type)
delete(fnsym.Func.Autot, ngotype(n).Linksym())
inlIndex := 0
if genDwarfInline > 1 {
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,
// 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
// 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
}
if dvar := createComplexVar(fn, ssa.VarID(varID)); dvar != nil {
if dvar := createComplexVar(fnsym, fn, ssa.VarID(varID)); dvar != nil {
decls = append(decls, n)
vars = append(vars, dvar)
}
@ -578,9 +580,9 @@ func createDwarfVars(fnsym *obj.LSym, fn *Func, apDecls []*Node) ([]*Node, []*dw
var decls []*Node
var selected map[*Node]bool
if Ctxt.Flag_locationlists && Ctxt.Flag_optimize && fn.DebugInfo != nil {
decls, vars, selected = createComplexVars(fn)
decls, vars, selected = createComplexVars(fnsym, fn)
} else {
decls, vars, selected = createSimpleVars(apDecls)
decls, vars, selected = createSimpleVars(fnsym, 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
// are homed on the stack in a single place for the
// entire call.
vars = append(vars, createSimpleVar(n))
vars = append(vars, createSimpleVar(fnsym, n))
decls = append(decls, n)
continue
}
@ -712,7 +714,7 @@ func stackOffset(slot ssa.LocalSlot) int32 {
}
// 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
n := debug.Vars[varID].(*Node)
@ -727,6 +729,7 @@ func createComplexVar(fn *Func, varID ssa.VarID) *dwarf.Var {
}
gotype := ngotype(n).Linksym()
delete(fnsym.Func.Autot, gotype)
typename := dwarf.InfoPrefix + gotype.Name[len("type."):]
inlIndex := 0
if genDwarfInline > 1 {