cmd/compile: regabi support for DWARF location expressions

Revise the code that generates DWARF location expressions for input
parameters to get it to work properly with the new register ABI when
optimization is turned off.

The previously implementation assumed stack locations for all
input+output parameters when -N (disable optimization) was in effect.
In the new implementation, a register-resident input parameter is
given a 2-element location list, the first list element pointing to
the ABI register(s) containing the param, and the second element
pointing to the stack home once it has been spilled.

NB, this change fixes a bunch of the Delve pkg/proc unit tests (maybe
about half of the outstanding failures). Still a good number that need
to be investigated, however.

Updates #40724.
Updates #45720.

Change-Id: I743bbb9af187bcdebeb8e690fdd6db58094ca415
Reviewed-on: https://go-review.googlesource.com/c/go/+/314431
Trust: Than McIntosh <thanm@google.com>
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Than McIntosh 2021-04-27 12:40:43 -04:00
parent 93200b98c7
commit 162d4f9c92
3 changed files with 282 additions and 3 deletions

View file

@ -138,8 +138,11 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir
var vars []*dwarf.Var
var decls []*ir.Name
var selected ir.NameSet
if base.Ctxt.Flag_locationlists && base.Ctxt.Flag_optimize && fn.DebugInfo != nil && complexOK {
decls, vars, selected = createComplexVars(fnsym, fn)
} else if fn.ABI == obj.ABIInternal && base.Flag.N != 0 && complexOK {
decls, vars, selected = createABIVars(fnsym, fn, apDecls)
} else {
decls, vars, selected = createSimpleVars(fnsym, apDecls)
}
@ -314,6 +317,37 @@ func createSimpleVar(fnsym *obj.LSym, n *ir.Name) *dwarf.Var {
}
}
// createABIVars creates DWARF variables for functions in which the
// register ABI is enabled but optimization is turned off. It uses a
// hybrid approach in which register-resident input params are
// captured with location lists, and all other vars use the "simple"
// strategy.
func createABIVars(fnsym *obj.LSym, fn *ir.Func, apDecls []*ir.Name) ([]*ir.Name, []*dwarf.Var, ir.NameSet) {
// Invoke createComplexVars to generate dwarf vars for input parameters
// that are register-allocated according to the ABI rules.
decls, vars, selected := createComplexVars(fnsym, fn)
// Now fill in the remainder of the variables: input parameters
// that are not register-resident, output parameters, and local
// variables.
for _, n := range apDecls {
if ir.IsAutoTmp(n) {
continue
}
if _, ok := selected[n]; ok {
// already handled
continue
}
decls = append(decls, n)
vars = append(vars, createSimpleVar(fnsym, n))
selected.Add(n)
}
return decls, vars, selected
}
// createComplexVars creates recomposed DWARF vars with location lists,
// suitable for describing optimized code.
func createComplexVars(fnsym *obj.LSym, fn *ir.Func) ([]*ir.Name, []*dwarf.Var, ir.NameSet) {