From a03480905b0e22f84fb700fefadd73fde2f8507f Mon Sep 17 00:00:00 2001 From: David Chase Date: Wed, 18 Oct 2017 16:32:01 -0400 Subject: [PATCH] cmd/compile: provide more names for stack slots Recurse into structs/arrays of one element when assigning names. Test incorporated into existing end-to-end debugger test, hand-verified that it fails without this CL. Fixes #19868 Revives CL 40010 Old-Change-Id: I0266e58af975fb64cfa17922be383b70f0a7ea96 Change-Id: I122ac2375931477769ec8d763607c1ec42d78a7f Reviewed-on: https://go-review.googlesource.com/71731 Run-TryBot: David Chase Reviewed-by: Heschi Kreinick Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/debug_test.go | 14 +- src/cmd/compile/internal/ssa/decompose.go | 102 ++++++-- .../compile/internal/ssa/gen/generic.rules | 2 - .../compile/internal/ssa/rewritegeneric.go | 19 -- .../internal/ssa/testdata/hist.dbg-dlv.nexts | 206 +++++++-------- .../internal/ssa/testdata/hist.dbg-gdb.nexts | 243 +++++++++--------- src/cmd/compile/internal/ssa/testdata/hist.go | 33 ++- .../internal/ssa/testdata/hist.opt-dlv.nexts | 110 +------- .../internal/ssa/testdata/hist.opt-gdb.nexts | 223 ++++++++-------- 9 files changed, 450 insertions(+), 502 deletions(-) diff --git a/src/cmd/compile/internal/ssa/debug_test.go b/src/cmd/compile/internal/ssa/debug_test.go index bc8512cb10..cc23a21c71 100644 --- a/src/cmd/compile/internal/ssa/debug_test.go +++ b/src/cmd/compile/internal/ssa/debug_test.go @@ -25,7 +25,7 @@ import ( var update = flag.Bool("u", false, "update test reference files") var verbose = flag.Bool("v", false, "print debugger interactions (very verbose)") var dryrun = flag.Bool("n", false, "just print the command line and first debugging bits") -var delve = flag.Bool("d", false, "use Delve (dlv) instead of gdb, use dlv reverence files") +var useDelve = flag.Bool("d", false, "use Delve (dlv) instead of gdb, use dlv reverence files") var force = flag.Bool("f", false, "force run under not linux-amd64; also do not use tempdir") var repeats = flag.Bool("r", false, "detect repeats in debug steps and don't ignore them") @@ -89,7 +89,7 @@ func TestNexting(t *testing.T) { } testenv.MustHaveGoBuild(t) - if !*delve && !*force && !(runtime.GOOS == "linux" && runtime.GOARCH == "amd64") { + if !*useDelve && !*force && !(runtime.GOOS == "linux" && runtime.GOARCH == "amd64") { // Running gdb on OSX/darwin is very flaky. // Sometimes it is called ggdb, depending on how it is installed. // It also probably requires an admin password typed into a dialog box. @@ -99,7 +99,7 @@ func TestNexting(t *testing.T) { skipReasons += "not run unless linux-amd64 or -d or -f; " } - if *delve { + if *useDelve { debugger = "dlv" _, err := exec.LookPath("dlv") if err != nil { @@ -132,11 +132,11 @@ func TestNexting(t *testing.T) { // If this is test is run with a runtime compiled with -N -l, it is very likely to fail. // This occurs in the noopt builders (for example). if gogcflags := os.Getenv("GO_GCFLAGS"); *force || (!strings.Contains(gogcflags, "-N") && !strings.Contains(gogcflags, "-l")) { - if *delve || *inlines { - testNexting(t, "hist", "opt", "") + if *useDelve || *inlines { + testNexting(t, "hist", "opt", "-dwarflocationlists") } else { // For gdb, disable inlining so that a compiler test does not depend on library code. - testNexting(t, "hist", "opt", "-l") + testNexting(t, "hist", "opt", "-l -dwarflocationlists") } } else { t.Skip("skipping for unoptimized runtime") @@ -176,7 +176,7 @@ func testNexting(t *testing.T, base, tag, gcflags string) { nextlog := logbase + "-" + debugger + ".nexts" tmplog := tmpbase + "-" + debugger + ".nexts" - if *delve { + if *useDelve { h1 = dlvTest(tag, exe, 1000) } else { h1 = gdbTest(tag, exe, 1000) diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go index b2a2e25ed9..c024a22f00 100644 --- a/src/cmd/compile/internal/ssa/decompose.go +++ b/src/cmd/compile/internal/ssa/decompose.go @@ -233,40 +233,14 @@ func decomposeUser(f *Func) { // We must do the opt pass before any deadcode elimination or we will // lose the name->value correspondence. i := 0 - var fnames []LocalSlot var newNames []LocalSlot for _, name := range f.Names { t := name.Type switch { case t.IsStruct(): - n := t.NumFields() - fnames = fnames[:0] - for i := 0; i < n; i++ { - fnames = append(fnames, f.fe.SplitStruct(name, i)) - } - for _, v := range f.NamedValues[name] { - for i := 0; i < n; i++ { - x := v.Block.NewValue1I(v.Pos, OpStructSelect, t.FieldType(i), int64(i), v) - f.NamedValues[fnames[i]] = append(f.NamedValues[fnames[i]], x) - } - } - delete(f.NamedValues, name) - newNames = append(newNames, fnames...) + newNames = decomposeUserStructInto(f, name, newNames) case t.IsArray(): - if t.NumElem() == 0 { - // TODO(khr): Not sure what to do here. Probably nothing. - // Names for empty arrays aren't important. - break - } - if t.NumElem() != 1 { - f.Fatalf("array not of size 1") - } - elemName := f.fe.SplitArray(name) - for _, v := range f.NamedValues[name] { - e := v.Block.NewValue1I(v.Pos, OpArraySelect, t.ElemType(), 0, v) - f.NamedValues[elemName] = append(f.NamedValues[elemName], e) - } - + newNames = decomposeUserArrayInto(f, name, newNames) default: f.Names[i] = name i++ @@ -276,6 +250,78 @@ func decomposeUser(f *Func) { f.Names = append(f.Names, newNames...) } +// decomposeUserArrayInto creates names for the element(s) of arrays referenced +// by name where possible, and appends those new names to slots, which is then +// returned. +func decomposeUserArrayInto(f *Func, name LocalSlot, slots []LocalSlot) []LocalSlot { + t := name.Type + if t.NumElem() == 0 { + // TODO(khr): Not sure what to do here. Probably nothing. + // Names for empty arrays aren't important. + return slots + } + if t.NumElem() != 1 { + // shouldn't get here due to CanSSA + f.Fatalf("array not of size 1") + } + elemName := f.fe.SplitArray(name) + for _, v := range f.NamedValues[name] { + e := v.Block.NewValue1I(v.Pos, OpArraySelect, t.ElemType(), 0, v) + f.NamedValues[elemName] = append(f.NamedValues[elemName], e) + } + // delete the name for the array as a whole + delete(f.NamedValues, name) + + if t.ElemType().IsArray() { + return decomposeUserArrayInto(f, elemName, slots) + } else if t.ElemType().IsStruct() { + return decomposeUserStructInto(f, elemName, slots) + } + + return append(slots, elemName) +} + +// decomposeUserStructInto creates names for the fields(s) of structs referenced +// by name where possible, and appends those new names to slots, which is then +// returned. +func decomposeUserStructInto(f *Func, name LocalSlot, slots []LocalSlot) []LocalSlot { + fnames := []LocalSlot{} // slots for struct in name + t := name.Type + n := t.NumFields() + + for i := 0; i < n; i++ { + fs := f.fe.SplitStruct(name, i) + fnames = append(fnames, fs) + // arrays and structs will be decomposed further, so + // there's no need to record a name + if !fs.Type.IsArray() && !fs.Type.IsStruct() { + slots = append(slots, fs) + } + } + + // create named values for each struct field + for _, v := range f.NamedValues[name] { + for i := 0; i < len(fnames); i++ { + x := v.Block.NewValue1I(v.Pos, OpStructSelect, t.FieldType(i), int64(i), v) + f.NamedValues[fnames[i]] = append(f.NamedValues[fnames[i]], x) + } + } + // remove the name of the struct as a whole + delete(f.NamedValues, name) + + // now that this f.NamedValues contains values for the struct + // fields, recurse into nested structs + for i := 0; i < n; i++ { + if name.Type.FieldType(i).IsStruct() { + slots = decomposeUserStructInto(f, fnames[i], slots) + delete(f.NamedValues, fnames[i]) + } else if name.Type.FieldType(i).IsArray() { + slots = decomposeUserArrayInto(f, fnames[i], slots) + delete(f.NamedValues, fnames[i]) + } + } + return slots +} func decomposeUserPhi(v *Value) { switch { case v.Type.IsStruct(): diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index bc0ee4904c..5150eec0ef 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -875,8 +875,6 @@ (Store _ (ArrayMake0) mem) -> mem (Store dst (ArrayMake1 e) mem) -> (Store {e.Type} dst e mem) -(ArraySelect [0] (Load ptr mem)) -> (Load ptr mem) - // Putting [1]{*byte} and similar into direct interfaces. (IMake typ (ArrayMake1 val)) -> (IMake typ val) (ArraySelect [0] x:(IData _)) -> x diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index d937855c90..8def2dbcc8 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -6704,25 +6704,6 @@ func rewriteValuegeneric_OpArraySelect_0(v *Value) bool { v.AddArg(x) return true } - // match: (ArraySelect [0] (Load ptr mem)) - // cond: - // result: (Load ptr mem) - for { - if v.AuxInt != 0 { - break - } - v_0 := v.Args[0] - if v_0.Op != OpLoad { - break - } - _ = v_0.Args[1] - ptr := v_0.Args[0] - mem := v_0.Args[1] - v.reset(OpLoad) - v.AddArg(ptr) - v.AddArg(mem) - return true - } // match: (ArraySelect [0] x:(IData _)) // cond: // result: x diff --git a/src/cmd/compile/internal/ssa/testdata/hist.dbg-dlv.nexts b/src/cmd/compile/internal/ssa/testdata/hist.dbg-dlv.nexts index 07de28977c..d7d980789c 100644 --- a/src/cmd/compile/internal/ssa/testdata/hist.dbg-dlv.nexts +++ b/src/cmd/compile/internal/ssa/testdata/hist.dbg-dlv.nexts @@ -1,109 +1,99 @@ ./testdata/hist.go -35: func main() { -36: hist := make([]int, 10) -37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) -38: if len(os.Args) > 1 { -43: return -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -57: t := 0 -58: n := 0 -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -68: } +55: func main() { +57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}} +58: tinycall() // this forces l etc to stack +59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y) +60: dy := l.end.y - l.begin.y +61: sink = dx + dy +63: hist := make([]int, 7) +64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) +65: if len(os.Args) > 1 { +70: return +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +84: t := 0 +85: n := 0 +86: for i, a := range hist { +87: if a == 0 { +88: continue +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +87: if a == 0 { +88: continue +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +87: if a == 0 { +88: continue +86: for i, a := range hist { +95: } diff --git a/src/cmd/compile/internal/ssa/testdata/hist.dbg-gdb.nexts b/src/cmd/compile/internal/ssa/testdata/hist.dbg-gdb.nexts index 0ba18c11f1..38609a7566 100644 --- a/src/cmd/compile/internal/ssa/testdata/hist.dbg-gdb.nexts +++ b/src/cmd/compile/internal/ssa/testdata/hist.dbg-gdb.nexts @@ -1,133 +1,124 @@ src/cmd/compile/internal/ssa/testdata/hist.go -35: func main() { -36: hist := make([]int, 10) -37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) -$1 = []int = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} -$2 = "1\n1\n1\n1\n2\n2\n2\n4\n4\n8\n" -38: if len(os.Args) > 1 { -43: return -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -$3 = 1 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -$4 = 1 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) +55: func main() { +57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}} +58: tinycall() // this forces l etc to stack +59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y) +$1 = 1 +$2 = 4 +60: dy := l.end.y - l.begin.y +61: sink = dx + dy +63: hist := make([]int, 7) +64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) +$3 = []int = {0, 0, 0, 0, 0, 0, 0} +$4 = "1\n1\n1\n2\n2\n2\n4\n4\n5\n" +65: if len(os.Args) > 1 { +70: return +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) $5 = 1 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) $6 = 1 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -$7 = 2 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +$7 = 1 +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) $8 = 2 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) $9 = 2 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -$10 = 4 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +$10 = 2 +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) $11 = 4 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -$12 = 8 -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -57: t := 0 -58: n := 0 -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -$13 = 4 -$14 = 1 -$15 = 4 -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -$16 = 7 -$17 = 2 -$18 = 10 -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +$12 = 4 +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +$13 = 5 +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +84: t := 0 +85: n := 0 +86: for i, a := range hist { +87: if a == 0 { +88: continue +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +$14 = 3 +$15 = 1 +$16 = 3 +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +$17 = 6 +$18 = 2 $19 = 9 -$20 = 4 -$21 = 18 -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -60: if a == 0 { -63: t += i * a -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -$22 = 10 -$23 = 8 -$24 = 26 -59: for i, a := range hist { -60: if a == 0 { -61: continue -59: for i, a := range hist { -68: } +86: for i, a := range hist { +87: if a == 0 { +88: continue +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +$20 = 8 +$21 = 4 +$22 = 17 +86: for i, a := range hist { +87: if a == 0 { +90: t += i * a +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +$23 = 9 +$24 = 5 +$25 = 22 +86: for i, a := range hist { +87: if a == 0 { +88: continue +86: for i, a := range hist { +95: } diff --git a/src/cmd/compile/internal/ssa/testdata/hist.go b/src/cmd/compile/internal/ssa/testdata/hist.go index 12ad09cdaa..c31e692012 100644 --- a/src/cmd/compile/internal/ssa/testdata/hist.go +++ b/src/cmd/compile/internal/ssa/testdata/hist.go @@ -2,6 +2,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// This is the input program for an end-to-end test of the DWARF produced +// by the compiler. It is compiled with various flags, then the resulting +// binary is "debugged" under the control of a harness. Because the compile+debug +// step is time-consuming, the tests for different bugs are all accumulated here +// so that their cost is only the time to "n" through the additional code. + package main import ( @@ -13,6 +19,21 @@ import ( "strings" ) +type point struct { + x, y int +} + +type line struct { + begin, end point +} + +var zero int +var sink int + +//go:noinline +func tinycall() { +} + func ensure(n int, sl []int) []int { for len(sl) <= n { sl = append(sl, 0) @@ -23,17 +44,23 @@ func ensure(n int, sl []int) []int { var cannedInput string = `1 1 1 -1 2 2 2 4 4 -8 +5 ` func main() { - hist := make([]int, 10) + // For #19868 + l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}} + tinycall() // this forces l etc to stack + dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y) + dy := l.end.y - l.begin.y + sink = dx + dy + // For #21098 + hist := make([]int, 7) var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) if len(os.Args) > 1 { var err error diff --git a/src/cmd/compile/internal/ssa/testdata/hist.opt-dlv.nexts b/src/cmd/compile/internal/ssa/testdata/hist.opt-dlv.nexts index 635cb74e93..c1688e791d 100644 --- a/src/cmd/compile/internal/ssa/testdata/hist.opt-dlv.nexts +++ b/src/cmd/compile/internal/ssa/testdata/hist.opt-dlv.nexts @@ -1,101 +1,11 @@ ./testdata/hist.go -35: func main() { -36: hist := make([]int, 10) -37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) -13: "strings" -38: if len(os.Args) > 1 { -8: "bufio" -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -59: for i, a := range hist { -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -68: } +55: func main() { +57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}} +58: tinycall() // this forces l etc to stack +57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}} +59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y) +60: dy := l.end.y - l.begin.y +61: sink = dx + dy +63: hist := make([]int, 7) +64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) +19: "strings" diff --git a/src/cmd/compile/internal/ssa/testdata/hist.opt-gdb.nexts b/src/cmd/compile/internal/ssa/testdata/hist.opt-gdb.nexts index 037ede00fe..75de3356f7 100644 --- a/src/cmd/compile/internal/ssa/testdata/hist.opt-gdb.nexts +++ b/src/cmd/compile/internal/ssa/testdata/hist.opt-gdb.nexts @@ -1,110 +1,115 @@ src/cmd/compile/internal/ssa/testdata/hist.go -35: func main() { -36: hist := make([]int, 10) -37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) -38: if len(os.Args) > 1 { -46: scanner := bufio.NewScanner(reader) -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -48: s := scanner.Text() -49: i, err := strconv.ParseInt(s, 10, 64) -50: if err != nil { //gdb-dbg=(i) -54: hist = ensure(int(i), hist) -55: hist[int(i)]++ -47: for scanner.Scan() { -59: for i, a := range hist { -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -64: n += a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -63: t += i * a -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -59: for i, a := range hist { -65: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) -60: if a == 0 { -68: } +55: func main() { +57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}} +58: tinycall() // this forces l etc to stack +57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}} +59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y) +60: dy := l.end.y - l.begin.y +61: sink = dx + dy +63: hist := make([]int, 7) +64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) +65: if len(os.Args) > 1 { +73: scanner := bufio.NewScanner(reader) +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +75: s := scanner.Text() +76: i, err := strconv.ParseInt(s, 10, 64) +77: if err != nil { //gdb-dbg=(i) +81: hist = ensure(int(i), hist) +82: hist[int(i)]++ +74: for scanner.Scan() { +86: for i, a := range hist { +87: if a == 0 { +88: continue +87: if a == 0 { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +87: if a == 0 { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +87: if a == 0 { +88: continue +87: if a == 0 { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +87: if a == 0 { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +91: n += a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +90: t += i * a +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +86: for i, a := range hist { +92: fmt.Fprintf(os.Stderr, "%d\t%d\t%d\t%d\t%d\n", i, a, n, i*a, t) //gdb-dbg=(n,i,t) +87: if a == 0 { +88: continue +95: } -- 2.48.1