aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/dwarf
diff options
context:
space:
mode:
authorHeschi Kreinick <heschi@google.com>2017-09-11 14:28:34 -0400
committerHeschi Kreinick <heschi@google.com>2017-09-28 20:30:12 +0000
commit6bbe1bc94072533ec715cae32f7cda1ae0a2a5eb (patch)
tree9bfc02de9301260db1441396bbcc48371254472a /src/cmd/internal/dwarf
parent6f1724ff415a85b3329806c0c9a3e5e46afac317 (diff)
downloadgo-6bbe1bc94072533ec715cae32f7cda1ae0a2a5eb.tar.xz
cmd/compile: cover control flow insns in location lists
The information that's used to generate DWARF location lists is very ssa.Value centric; it uses Values as start and end coordinates to define ranges. That mostly works fine, but control flow instructions don't come from Values, so the ranges couldn't cover them. Control flow instructions are generated when the SSA representation is converted to assembly, so that's the best place to extend the ranges to cover them. (Before that, there's nothing to refer to, and afterward the boundaries between blocks have been lost.) That requires block information in the debugInfo type, which then flows down to make everything else awkward. On the plus side, there's a little less copying slices around than there used to be, so it should be a little faster. Previously, the ranges for empty blocks were not very meaningful. That was fine, because they had no Values to cover, so no debug information was generated for them. But they do have control flow instructions (that's why they exist) and so now it's important that the information be correct. Introduce two sentinel values, BlockStart and BlockEnd, that denote the boundary of a block, even if the block is empty. BlockEnd replaces the previous SurvivedBlock flag. There's one more problem: the last instruction in the function will be a control flow instruction, so any live ranges need to be extended past it. But there's no instruction after it to use as the end of the range. Instead, leave the EndProg field of those ranges as nil and fix it up to point to past the end of the assembled text at the very last moment. Change-Id: I81f884020ff36fd6fe8d7888fc57c99412c4245b Reviewed-on: https://go-review.googlesource.com/63010 Reviewed-by: Alessandro Arzilli <alessandro.arzilli@gmail.com> Reviewed-by: David Chase <drchase@google.com> Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd/internal/dwarf')
-rw-r--r--src/cmd/internal/dwarf/dwarf.go20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/cmd/internal/dwarf/dwarf.go b/src/cmd/internal/dwarf/dwarf.go
index ea8bc3dbe9..b3fa2f674f 100644
--- a/src/cmd/internal/dwarf/dwarf.go
+++ b/src/cmd/internal/dwarf/dwarf.go
@@ -821,6 +821,18 @@ func putscope(ctxt Context, info, loc, ranges, startPC Sym, curscope int32, scop
func putvar(ctxt Context, info, loc Sym, v *Var, startPC Sym, encbuf []byte) {
n := v.Name
+ // If the variable was entirely optimized out, don't emit a location list;
+ // convert to an inline abbreviation and emit an empty location.
+ missing := false
+ switch {
+ case v.Abbrev == DW_ABRV_AUTO_LOCLIST && len(v.LocationList) == 0:
+ missing = true
+ v.Abbrev = DW_ABRV_AUTO
+ case v.Abbrev == DW_ABRV_PARAM_LOCLIST && len(v.LocationList) == 0:
+ missing = true
+ v.Abbrev = DW_ABRV_PARAM
+ }
+
Uleb128put(ctxt, info, int64(v.Abbrev))
putattr(ctxt, info, v.Abbrev, DW_FORM_string, DW_CLS_STRING, int64(len(n)), n)
putattr(ctxt, info, v.Abbrev, DW_FORM_udata, DW_CLS_CONSTANT, int64(v.DeclLine), nil)
@@ -829,13 +841,15 @@ func putvar(ctxt Context, info, loc Sym, v *Var, startPC Sym, encbuf []byte) {
addLocList(ctxt, loc, startPC, v, encbuf)
} else {
loc := encbuf[:0]
- if v.StackOffset == 0 {
+ switch {
+ case missing:
+ break // no location
+ case v.StackOffset == 0:
loc = append(loc, DW_OP_call_frame_cfa)
- } else {
+ default:
loc = append(loc, DW_OP_fbreg)
loc = AppendSleb128(loc, int64(v.StackOffset))
}
-
putattr(ctxt, info, v.Abbrev, DW_FORM_block1, DW_CLS_BLOCK, int64(len(loc)), loc)
}
putattr(ctxt, info, v.Abbrev, DW_FORM_ref_addr, DW_CLS_REFERENCE, 0, v.Type)