mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: fix use of original spill name after sinking
This is a fix for the ssacheck builder http://build.golang.org/log/baa00f70c34e41186051cfe90568de3d91f115d7 after CL 21307 for sinking spills down loop exits https://go-review.googlesource.com/#/c/21037/ The fix is to reuse (move) the original spill, thus preserving the definition of the variable and its use count. Original and copy both use the same stack slot, but ssacheck needs to see a definition for the variable itself. Fixes #15279. Change-Id: I286285490193dc211b312d64dbc5a54867730bd6 Reviewed-on: https://go-review.googlesource.com/21995 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
170c1b479b
commit
6b0b3f86d6
2 changed files with 29 additions and 13 deletions
|
|
@ -96,7 +96,12 @@
|
|||
// there is one spill site (one StoreReg) targeting stack slot X, after
|
||||
// sinking there may be multiple spill sites targeting stack slot X,
|
||||
// with no phi functions at any join points reachable by the multiple
|
||||
// spill sites.
|
||||
// spill sites. In addition, uses of the spill from copies of the original
|
||||
// will not name the copy in their reference; instead they will name
|
||||
// the original, though both will have the same spill location. The
|
||||
// first sunk spill will be the original, but moved, to an exit block,
|
||||
// thus ensuring that there is a definition somewhere corresponding to
|
||||
// the original spill's uses.
|
||||
|
||||
package ssa
|
||||
|
||||
|
|
@ -1354,6 +1359,7 @@ sinking:
|
|||
}
|
||||
b.Values = b.Values[:i]
|
||||
|
||||
first := true
|
||||
for i := uint(0); i < 32 && dests != 0; i++ {
|
||||
|
||||
if dests&(1<<i) == 0 {
|
||||
|
|
@ -1363,18 +1369,28 @@ sinking:
|
|||
dests ^= 1 << i
|
||||
|
||||
d := loop.exits[i]
|
||||
vspnew := d.NewValue1(e.Line, OpStoreReg, e.Type, e)
|
||||
|
||||
if s.f.pass.debug > moveSpills {
|
||||
s.f.Config.Warnl(e.Line, "moved spill %v in %v for %v to %v in %v",
|
||||
vsp, b, e, vspnew, d)
|
||||
vspnew := vsp // reuse original for first sunk spill, saves tracking down and renaming uses
|
||||
if !first { // any sunk spills after first must make a copy
|
||||
vspnew = d.NewValue1(e.Line, OpStoreReg, e.Type, e)
|
||||
f.setHome(vspnew, f.getHome(vsp.ID)) // copy stack home
|
||||
if s.f.pass.debug > moveSpills {
|
||||
s.f.Config.Warnl(e.Line, "copied spill %v in %v for %v to %v in %v",
|
||||
vsp, b, e, vspnew, d)
|
||||
}
|
||||
} else {
|
||||
first = false
|
||||
vspnew.Block = d
|
||||
d.Values = append(d.Values, vspnew)
|
||||
if s.f.pass.debug > moveSpills {
|
||||
s.f.Config.Warnl(e.Line, "moved spill %v in %v for %v to %v in %v",
|
||||
vsp, b, e, vspnew, d)
|
||||
}
|
||||
}
|
||||
|
||||
f.setHome(vspnew, f.getHome(vsp.ID)) // copy stack home
|
||||
|
||||
// shuffle vspnew to the beginning of its block
|
||||
copy(d.Values[1:], d.Values[0:len(d.Values)-1])
|
||||
d.Values[0] = vspnew
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue