Commit a0348090 authored by David Chase's avatar David Chase

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 <drchase@google.com>
Reviewed-by: 's avatarHeschi Kreinick <heschi@google.com>
Reviewed-by: 's avatarKeith Randall <khr@golang.org>
parent 018642d6
...@@ -25,7 +25,7 @@ import ( ...@@ -25,7 +25,7 @@ import (
var update = flag.Bool("u", false, "update test reference files") var update = flag.Bool("u", false, "update test reference files")
var verbose = flag.Bool("v", false, "print debugger interactions (very verbose)") 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 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 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") 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) { ...@@ -89,7 +89,7 @@ func TestNexting(t *testing.T) {
} }
testenv.MustHaveGoBuild(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. // Running gdb on OSX/darwin is very flaky.
// Sometimes it is called ggdb, depending on how it is installed. // Sometimes it is called ggdb, depending on how it is installed.
// It also probably requires an admin password typed into a dialog box. // It also probably requires an admin password typed into a dialog box.
...@@ -99,7 +99,7 @@ func TestNexting(t *testing.T) { ...@@ -99,7 +99,7 @@ func TestNexting(t *testing.T) {
skipReasons += "not run unless linux-amd64 or -d or -f; " skipReasons += "not run unless linux-amd64 or -d or -f; "
} }
if *delve { if *useDelve {
debugger = "dlv" debugger = "dlv"
_, err := exec.LookPath("dlv") _, err := exec.LookPath("dlv")
if err != nil { if err != nil {
...@@ -132,11 +132,11 @@ func TestNexting(t *testing.T) { ...@@ -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. // 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). // This occurs in the noopt builders (for example).
if gogcflags := os.Getenv("GO_GCFLAGS"); *force || (!strings.Contains(gogcflags, "-N") && !strings.Contains(gogcflags, "-l")) { if gogcflags := os.Getenv("GO_GCFLAGS"); *force || (!strings.Contains(gogcflags, "-N") && !strings.Contains(gogcflags, "-l")) {
if *delve || *inlines { if *useDelve || *inlines {
testNexting(t, "hist", "opt", "") testNexting(t, "hist", "opt", "-dwarflocationlists")
} else { } else {
// For gdb, disable inlining so that a compiler test does not depend on library code. // 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 { } else {
t.Skip("skipping for unoptimized runtime") t.Skip("skipping for unoptimized runtime")
...@@ -176,7 +176,7 @@ func testNexting(t *testing.T, base, tag, gcflags string) { ...@@ -176,7 +176,7 @@ func testNexting(t *testing.T, base, tag, gcflags string) {
nextlog := logbase + "-" + debugger + ".nexts" nextlog := logbase + "-" + debugger + ".nexts"
tmplog := tmpbase + "-" + debugger + ".nexts" tmplog := tmpbase + "-" + debugger + ".nexts"
if *delve { if *useDelve {
h1 = dlvTest(tag, exe, 1000) h1 = dlvTest(tag, exe, 1000)
} else { } else {
h1 = gdbTest(tag, exe, 1000) h1 = gdbTest(tag, exe, 1000)
......
...@@ -233,40 +233,14 @@ func decomposeUser(f *Func) { ...@@ -233,40 +233,14 @@ func decomposeUser(f *Func) {
// We must do the opt pass before any deadcode elimination or we will // We must do the opt pass before any deadcode elimination or we will
// lose the name->value correspondence. // lose the name->value correspondence.
i := 0 i := 0
var fnames []LocalSlot
var newNames []LocalSlot var newNames []LocalSlot
for _, name := range f.Names { for _, name := range f.Names {
t := name.Type t := name.Type
switch { switch {
case t.IsStruct(): case t.IsStruct():
n := t.NumFields() newNames = decomposeUserStructInto(f, name, newNames)
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...)
case t.IsArray(): case t.IsArray():
if t.NumElem() == 0 { newNames = decomposeUserArrayInto(f, name, newNames)
// 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)
}
default: default:
f.Names[i] = name f.Names[i] = name
i++ i++
...@@ -276,6 +250,78 @@ func decomposeUser(f *Func) { ...@@ -276,6 +250,78 @@ func decomposeUser(f *Func) {
f.Names = append(f.Names, newNames...) 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) { func decomposeUserPhi(v *Value) {
switch { switch {
case v.Type.IsStruct(): case v.Type.IsStruct():
......
...@@ -875,8 +875,6 @@ ...@@ -875,8 +875,6 @@
(Store _ (ArrayMake0) mem) -> mem (Store _ (ArrayMake0) mem) -> mem
(Store dst (ArrayMake1 e) mem) -> (Store {e.Type} dst e 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. // Putting [1]{*byte} and similar into direct interfaces.
(IMake typ (ArrayMake1 val)) -> (IMake typ val) (IMake typ (ArrayMake1 val)) -> (IMake typ val)
(ArraySelect [0] x:(IData _)) -> x (ArraySelect [0] x:(IData _)) -> x
......
...@@ -6704,25 +6704,6 @@ func rewriteValuegeneric_OpArraySelect_0(v *Value) bool { ...@@ -6704,25 +6704,6 @@ func rewriteValuegeneric_OpArraySelect_0(v *Value) bool {
v.AddArg(x) v.AddArg(x)
return true 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 _)) // match: (ArraySelect [0] x:(IData _))
// cond: // cond:
// result: x // result: x
......
./testdata/hist.go ./testdata/hist.go
35: func main() { 55: func main() {
36: hist := make([]int, 10) 57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) 58: tinycall() // this forces l etc to stack
38: if len(os.Args) > 1 { 59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)
43: return 60: dy := l.end.y - l.begin.y
47: for scanner.Scan() { 61: sink = dx + dy
48: s := scanner.Text() 63: hist := make([]int, 7)
49: i, err := strconv.ParseInt(s, 10, 64) 64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
50: if err != nil { //gdb-dbg=(i) 65: if len(os.Args) > 1 {
54: hist = ensure(int(i), hist) 70: return
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 75: s := scanner.Text()
48: s := scanner.Text() 76: i, err := strconv.ParseInt(s, 10, 64)
49: i, err := strconv.ParseInt(s, 10, 64) 77: if err != nil { //gdb-dbg=(i)
50: if err != nil { //gdb-dbg=(i) 81: hist = ensure(int(i), hist)
54: hist = ensure(int(i), hist) 82: hist[int(i)]++
55: hist[int(i)]++ 74: for scanner.Scan() {
47: for scanner.Scan() { 84: t := 0
57: t := 0 85: n := 0
58: n := 0 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 88: continue
61: continue 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 90: t += i * a
63: t += i * a 91: n += a
64: 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)
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) 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 90: t += i * a
63: t += i * a 91: n += a
64: 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)
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) 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 88: continue
61: continue 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 90: t += i * a
63: t += i * a 91: n += a
64: 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)
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) 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 90: t += i * a
61: continue 91: n += a
59: 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)
60: if a == 0 { 86: for i, a := range hist {
61: continue 87: if a == 0 {
59: for i, a := range hist { 88: continue
60: if a == 0 { 86: for i, a := range hist {
61: continue 95: }
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: }
src/cmd/compile/internal/ssa/testdata/hist.go src/cmd/compile/internal/ssa/testdata/hist.go
35: func main() { 55: func main() {
36: hist := make([]int, 10) 57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) 58: tinycall() // this forces l etc to stack
$1 = []int = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)
$2 = "1\n1\n1\n1\n2\n2\n2\n4\n4\n8\n" $1 = 1
38: if len(os.Args) > 1 { $2 = 4
43: return 60: dy := l.end.y - l.begin.y
47: for scanner.Scan() { 61: sink = dx + dy
48: s := scanner.Text() 63: hist := make([]int, 7)
49: i, err := strconv.ParseInt(s, 10, 64) 64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
50: if err != nil { //gdb-dbg=(i) $3 = []int = {0, 0, 0, 0, 0, 0, 0}
$3 = 1 $4 = "1\n1\n1\n2\n2\n2\n4\n4\n5\n"
54: hist = ensure(int(i), hist) 65: if len(os.Args) > 1 {
55: hist[int(i)]++ 70: return
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: 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)
$5 = 1 $5 = 1
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
$6 = 1 $6 = 1
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
$7 = 2 $7 = 1
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
$8 = 2 $8 = 2
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
$9 = 2 $9 = 2
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
$10 = 4 $10 = 2
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
$11 = 4 $11 = 4
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
$12 = 8 $12 = 4
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
57: t := 0 75: s := scanner.Text()
58: n := 0 76: i, err := strconv.ParseInt(s, 10, 64)
59: for i, a := range hist { 77: if err != nil { //gdb-dbg=(i)
60: if a == 0 { $13 = 5
61: continue 81: hist = ensure(int(i), hist)
59: for i, a := range hist { 82: hist[int(i)]++
60: if a == 0 { 74: for scanner.Scan() {
63: t += i * a 84: t := 0
64: n += a 85: n := 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) 86: for i, a := range hist {
$13 = 4 87: if a == 0 {
$14 = 1 88: continue
$15 = 4 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 90: t += i * a
63: t += i * a 91: n += a
64: 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)
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) $14 = 3
$16 = 7 $15 = 1
$17 = 2 $16 = 3
$18 = 10 86: for i, a := range hist {
59: for i, a := range hist { 87: if a == 0 {
60: if a == 0 { 90: t += i * a
61: continue 91: n += a
59: 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)
60: if a == 0 { $17 = 6
63: t += i * a $18 = 2
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)
$19 = 9 $19 = 9
$20 = 4 86: for i, a := range hist {
$21 = 18 87: if a == 0 {
59: for i, a := range hist { 88: continue
60: if a == 0 { 86: for i, a := range hist {
61: continue 87: if a == 0 {
59: for i, a := range hist { 90: t += i * a
60: if a == 0 { 91: n += a
61: continue 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)
59: for i, a := range hist { $20 = 8
60: if a == 0 { $21 = 4
61: continue $22 = 17
59: for i, a := range hist { 86: for i, a := range hist {
60: if a == 0 { 87: if a == 0 {
63: t += i * a 90: t += i * a
64: n += a 91: 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) 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)
$22 = 10 $23 = 9
$23 = 8 $24 = 5
$24 = 26 $25 = 22
59: for i, a := range hist { 86: for i, a := range hist {
60: if a == 0 { 87: if a == 0 {
61: continue 88: continue
59: for i, a := range hist { 86: for i, a := range hist {
68: } 95: }
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // 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 package main
import ( import (
...@@ -13,6 +19,21 @@ import ( ...@@ -13,6 +19,21 @@ import (
"strings" "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 { func ensure(n int, sl []int) []int {
for len(sl) <= n { for len(sl) <= n {
sl = append(sl, 0) sl = append(sl, 0)
...@@ -23,17 +44,23 @@ func ensure(n int, sl []int) []int { ...@@ -23,17 +44,23 @@ func ensure(n int, sl []int) []int {
var cannedInput string = `1 var cannedInput string = `1
1 1
1 1
1
2 2
2 2
2 2
4 4
4 4
8 5
` `
func main() { 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) var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
if len(os.Args) > 1 { if len(os.Args) > 1 {
var err error var err error
......
./testdata/hist.go ./testdata/hist.go
35: func main() { 55: func main() {
36: hist := make([]int, 10) 57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) 58: tinycall() // this forces l etc to stack
13: "strings" 57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
38: if len(os.Args) > 1 { 59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)
8: "bufio" 60: dy := l.end.y - l.begin.y
47: for scanner.Scan() { 61: sink = dx + dy
49: i, err := strconv.ParseInt(s, 10, 64) 63: hist := make([]int, 7)
50: if err != nil { //gdb-dbg=(i) 64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
54: hist = ensure(int(i), hist) 19: "strings"
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: }
src/cmd/compile/internal/ssa/testdata/hist.go src/cmd/compile/internal/ssa/testdata/hist.go
35: func main() { 55: func main() {
36: hist := make([]int, 10) 57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
37: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A) 58: tinycall() // this forces l etc to stack
38: if len(os.Args) > 1 { 57: l := line{point{1 + zero, 2 + zero}, point{3 + zero, 4 + zero}}
46: scanner := bufio.NewScanner(reader) 59: dx := l.end.x - l.begin.x //gdb-dbg=(l.begin.x,l.end.y)
47: for scanner.Scan() { 60: dy := l.end.y - l.begin.y
48: s := scanner.Text() 61: sink = dx + dy
49: i, err := strconv.ParseInt(s, 10, 64) 63: hist := make([]int, 7)
50: if err != nil { //gdb-dbg=(i) 64: var reader io.Reader = strings.NewReader(cannedInput) //gdb-dbg=(hist/A,cannedInput/A)
54: hist = ensure(int(i), hist) 65: if len(os.Args) > 1 {
55: hist[int(i)]++ 73: scanner := bufio.NewScanner(reader)
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
48: s := scanner.Text() 75: s := scanner.Text()
49: i, err := strconv.ParseInt(s, 10, 64) 76: i, err := strconv.ParseInt(s, 10, 64)
50: if err != nil { //gdb-dbg=(i) 77: if err != nil { //gdb-dbg=(i)
54: hist = ensure(int(i), hist) 81: hist = ensure(int(i), hist)
55: hist[int(i)]++ 82: hist[int(i)]++
47: for scanner.Scan() { 74: for scanner.Scan() {
59: for i, a := range hist { 86: for i, a := range hist {
60: if a == 0 { 87: 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) 88: continue
64: n += a 87: 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) 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)
63: t += i * a 91: 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) 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)
63: t += i * a 90: 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) 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)
59: for i, a := range hist { 90: 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) 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)
60: if a == 0 { 86: 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) 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)
64: n += a 87: 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) 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)
63: t += i * a 91: 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) 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)
63: t += i * a 90: 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) 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)
59: for i, a := range hist { 90: 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) 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)
60: if a == 0 { 86: 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) 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)
64: n += a 87: 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) 88: continue
63: t += i * a 87: 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) 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)
63: t += i * a 91: 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) 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)
59: for i, a := range hist { 90: 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) 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)
60: if a == 0 { 90: 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) 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)
64: n += a 86: 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) 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)
63: t += i * a 87: 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) 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)
63: t += i * a 91: 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) 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)
59: for i, a := range hist { 90: 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) 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)
60: if a == 0 { 90: t += i * a
68: } 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: }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment