mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: when CSEing two values, prefer the statement marked one
Fixes #75249 Change-Id: Ifd61bf5341f23ce2c9735e607e00d987489caacf Reviewed-on: https://go-review.googlesource.com/c/go/+/701295 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Alexander Musman <alexander.musman@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
00824f5ff5
commit
b1f3e38e41
2 changed files with 139 additions and 23 deletions
105
src/cmd/compile/internal/dwarfgen/linenum_test.go
Normal file
105
src/cmd/compile/internal/dwarfgen/linenum_test.go
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
// Copyright 2025 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package dwarfgen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"debug/dwarf"
|
||||||
|
"internal/platform"
|
||||||
|
"internal/testenv"
|
||||||
|
"io"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestIssue75249(t *testing.T) {
|
||||||
|
testenv.MustHaveGoRun(t)
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
if !platform.ExecutableHasDWARF(runtime.GOOS, runtime.GOARCH) {
|
||||||
|
t.Skipf("skipping on %s/%s: no DWARF symbol table in executables", runtime.GOOS, runtime.GOARCH)
|
||||||
|
}
|
||||||
|
|
||||||
|
code := `
|
||||||
|
package main
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
Field1 int
|
||||||
|
Field2 *int
|
||||||
|
Field3 int
|
||||||
|
Field4 *int
|
||||||
|
Field5 int
|
||||||
|
Field6 *int
|
||||||
|
Field7 int
|
||||||
|
Field8 *int
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noinline
|
||||||
|
func InitializeData(d *Data) {
|
||||||
|
d.Field1++ // line 16
|
||||||
|
d.Field2 = d.Field4
|
||||||
|
d.Field3++
|
||||||
|
d.Field4 = d.Field6
|
||||||
|
d.Field5++
|
||||||
|
d.Field6 = d.Field8
|
||||||
|
d.Field7++
|
||||||
|
d.Field8 = d.Field2 // line 23
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var data Data
|
||||||
|
InitializeData(&data)
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
_, f := gobuild(t, t.TempDir(), true, []testline{{line: code}})
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
dwarfData, err := f.DWARF()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
dwarfReader := dwarfData.Reader()
|
||||||
|
|
||||||
|
for {
|
||||||
|
entry, err := dwarfReader.Next()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if entry == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if entry.Tag != dwarf.TagCompileUnit {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name := entry.AttrField(dwarf.AttrName)
|
||||||
|
if name == nil || name.Class != dwarf.ClassString || name.Val != "main" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lr, err := dwarfData.LineReader(entry)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
stmts := map[int]bool{}
|
||||||
|
for {
|
||||||
|
var le dwarf.LineEntry
|
||||||
|
err := lr.Next(&le)
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !le.IsStmt {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
stmts[le.Line] = true
|
||||||
|
}
|
||||||
|
for i := 16; i <= 23; i++ {
|
||||||
|
if !stmts[i] {
|
||||||
|
t.Errorf("missing statement at line %d", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -181,34 +181,45 @@ func cse(f *Func) {
|
||||||
for _, e := range partition {
|
for _, e := range partition {
|
||||||
slices.SortFunc(e, func(v, w *Value) int {
|
slices.SortFunc(e, func(v, w *Value) int {
|
||||||
c := cmp.Compare(sdom.domorder(v.Block), sdom.domorder(w.Block))
|
c := cmp.Compare(sdom.domorder(v.Block), sdom.domorder(w.Block))
|
||||||
if v.Op != OpLocalAddr || c != 0 {
|
if c != 0 {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
// compare the memory args for OpLocalAddrs in the same block
|
if v.Op == OpLocalAddr {
|
||||||
vm := v.Args[1]
|
// compare the memory args for OpLocalAddrs in the same block
|
||||||
wm := w.Args[1]
|
vm := v.Args[1]
|
||||||
if vm == wm {
|
wm := w.Args[1]
|
||||||
return 0
|
if vm == wm {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
// if the two OpLocalAddrs are in the same block, and one's memory
|
||||||
|
// arg also in the same block, but the other one's memory arg not,
|
||||||
|
// the latter must be in an ancestor block
|
||||||
|
if vm.Block != v.Block {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if wm.Block != w.Block {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
// use store order if the memory args are in the same block
|
||||||
|
vs := storeOrdering(vm, o)
|
||||||
|
ws := storeOrdering(wm, o)
|
||||||
|
if vs <= 0 {
|
||||||
|
f.Fatalf("unable to determine the order of %s", vm.LongString())
|
||||||
|
}
|
||||||
|
if ws <= 0 {
|
||||||
|
f.Fatalf("unable to determine the order of %s", wm.LongString())
|
||||||
|
}
|
||||||
|
return cmp.Compare(vs, ws)
|
||||||
}
|
}
|
||||||
// if the two OpLocalAddrs are in the same block, and one's memory
|
vStmt := v.Pos.IsStmt() == src.PosIsStmt
|
||||||
// arg also in the same block, but the other one's memory arg not,
|
wStmt := w.Pos.IsStmt() == src.PosIsStmt
|
||||||
// the latter must be in an ancestor block
|
if vStmt != wStmt {
|
||||||
if vm.Block != v.Block {
|
if vStmt {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
if wm.Block != w.Block {
|
|
||||||
return +1
|
return +1
|
||||||
}
|
}
|
||||||
// use store order if the memory args are in the same block
|
return 0
|
||||||
vs := storeOrdering(vm, o)
|
|
||||||
ws := storeOrdering(wm, o)
|
|
||||||
if vs <= 0 {
|
|
||||||
f.Fatalf("unable to determine the order of %s", vm.LongString())
|
|
||||||
}
|
|
||||||
if ws <= 0 {
|
|
||||||
f.Fatalf("unable to determine the order of %s", wm.LongString())
|
|
||||||
}
|
|
||||||
return cmp.Compare(vs, ws)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
for i := 0; i < len(e)-1; i++ {
|
for i := 0; i < len(e)-1; i++ {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue