diff options
author | David Chase <drchase@google.com> | 2017-10-27 17:02:11 -0400 |
---|---|---|
committer | David Chase <drchase@google.com> | 2017-11-05 18:32:53 +0000 |
commit | d58d90152ba172dfa52d3135f5fea9b57927e230 (patch) | |
tree | 56326a814b5bfbfe35c0bef8f895d625e8c2154d /src/cmd/compile/internal/ssa/debug_test.go | |
parent | 38c725b14830bc1a95eb48cfb04d5f4c6d916a28 (diff) | |
download | go-d58d90152ba172dfa52d3135f5fea9b57927e230.tar.gz go-d58d90152ba172dfa52d3135f5fea9b57927e230.zip |
cmd/compile: adjust locationlist lifetimes
A statement like
foo = bar + qux
might compile to
AX := AX + BX
resulting in a regkill for AX before this instruction.
The buggy behavior is to kill AX "at" this instruction,
before it has executed. (Code generation of no-instruction
values like RegKills applies their effects at the
next actual instruction emitted).
However, bar is still associated with AX until after the
instruction executes, so the effect of the regkill must
occur at the boundary between this instruction and the
next. Similarly, the new value bound to AX is not visible
until this instruction executes (and in the case of values
that require multiple instructions in code generation, until
all of them have executed).
The ranges are adjusted so that a value's start occurs
at the next following instruction after its evaluation,
and the end occurs after (execution of) the first
instruction following the end of the lifetime as a value.
(Notice the asymmetry; the entire value must be finished
before it is visible, but execution of a single instruction
invalidates. However, the value *is* visible before that
next instruction executes).
The test was adjusted to make it insensitive to the result
numbering for variables printed by gdb, since that is not
relevant to the test and makes the differences introduced
by small changes larger than necessary/useful.
The test was also improved to present variable probes
more intuitively, and also to allow explicit indication
of "this variable was optimized out"
Change-Id: I39453eead8399e6bb05ebd957289b112d1100c0e
Reviewed-on: https://go-review.googlesource.com/74090
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/debug_test.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/debug_test.go | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/ssa/debug_test.go b/src/cmd/compile/internal/ssa/debug_test.go index 6ea8bc23fe..e3603e06ea 100644 --- a/src/cmd/compile/internal/ssa/debug_test.go +++ b/src/cmd/compile/internal/ssa/debug_test.go @@ -34,6 +34,9 @@ var inlines = flag.Bool("i", false, "do inlining for gdb (makes testing flaky ti var hexRe = regexp.MustCompile("0x[a-zA-Z0-9]+") var numRe = regexp.MustCompile("-?[0-9]+") var stringRe = regexp.MustCompile("\"([^\\\"]|(\\.))*\"") +var leadingDollarNumberRe = regexp.MustCompile("^[$][0-9]+") +var optOutGdbRe = regexp.MustCompile("[<]optimized out[>]") +var numberColonRe = regexp.MustCompile("^ *[0-9]+:") var gdb = "gdb" // Might be "ggdb" on Darwin, because gdb no longer part of XCode var debugger = "gdb" // For naming files, etc. @@ -68,8 +71,9 @@ var debugger = "gdb" // For naming files, etc. // The file being tested may contain comments of the form // //DBG-TAG=(v1,v2,v3) // where DBG = {gdb,dlv} and TAG={dbg,opt} -// each variable may optionally be followed by a / and one or more of S,A,N +// each variable may optionally be followed by a / and one or more of S,A,N,O // to indicate normalization of Strings, (hex) addresses, and numbers. +// "O" is an explicit indication that we expect it to be optimized out. // For example: /* if len(os.Args) > 1 { //gdb-dbg=(hist/A,cannedInput/A) //dlv-dbg=(hist/A,cannedInput/A) @@ -302,13 +306,9 @@ func (h *nextHist) write(filename string) { lastfile = p.file } fmt.Fprintf(file, "%d:%s\n", p.line, x) - // Vars must begin with a dollar-sign. // TODO, normalize between gdb and dlv into a common, comparable format. for _, y := range h.vars[i] { y = strings.TrimSpace(y) - if y[0] != '$' { - panic(fmt.Sprintf("Var line '%s' must begin with $, but does not\n", y)) - } fmt.Fprintf(file, "%s\n", y) } } @@ -328,15 +328,15 @@ func (h *nextHist) read(filename string) { if l[0] == ' ' { // file -- first two characters expected to be " " lastfile = strings.TrimSpace(l) - } else if l[0] == '$' { - h.addVar(l) - } else { + } else if numberColonRe.MatchString(l) { // line number -- <number>:<line> colonPos := strings.Index(l, ":") if colonPos == -1 { panic(fmt.Sprintf("Line %d (%s) in file %s expected to contain '<number>:' but does not.\n", i+1, l, filename)) } h.add(lastfile, l[0:colonPos], l[colonPos+1:]) + } else { + h.addVar(l) } } } @@ -634,7 +634,11 @@ func (s *gdbState) stepnext(ss string) bool { if cr == -1 { cr = len(response) } + // Convert the leading $<number> into $<N> to limit scope of diffs + // when a new print-this-variable comment is added. response = strings.TrimSpace(response[dollar:cr]) + response = leadingDollarNumberRe.ReplaceAllString(response, v) + if strings.Contains(substitutions, "A") { response = hexRe.ReplaceAllString(response, "<A>") } @@ -644,6 +648,9 @@ func (s *gdbState) stepnext(ss string) bool { if strings.Contains(substitutions, "S") { response = stringRe.ReplaceAllString(response, "<S>") } + if strings.Contains(substitutions, "O") { + response = optOutGdbRe.ReplaceAllString(response, "<Optimized out, as expected>") + } s.ioState.history.addVar(response) } return true |