mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: fix liveness for open-coded defer args for infinite loops
Once defined, a stack slot holding an open-coded defer arg should always be marked live, since it may be used at any time if there is a panic. These stack slots are typically kept live naturally by the open-defer code inlined at each return/exit point. However, we need to do extra work to make sure that they are kept live if a function has an infinite loop or a panic exit. For this fix, only in the case of a function that is using open-coded defers, we compute the set of blocks (most often empty) that cannot reach a return or a BlockExit (panic) because of an infinite loop. Then, for each block b which cannot reach a return or BlockExit or is a BlockExit block, we mark each defer arg slot as live, as long as the definition of the defer arg slot dominates block b. For this change, had to export (*Func).sdom (-> Sdom) and SparseTree.isAncestorEq (-> IsAncestorEq) Updates #35277 Change-Id: I7b53c9bd38ba384a3794386dd0eb94e4cbde4eb1 Reviewed-on: https://go-review.googlesource.com/c/go/+/204802 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
414c1d454e
commit
1b3a1db19f
12 changed files with 140 additions and 32 deletions
|
|
@ -848,7 +848,7 @@ func prove(f *Func) {
|
|||
})
|
||||
|
||||
idom := f.Idom()
|
||||
sdom := f.sdom()
|
||||
sdom := f.Sdom()
|
||||
|
||||
// DFS on the dominator tree.
|
||||
//
|
||||
|
|
@ -948,10 +948,10 @@ func getBranch(sdom SparseTree, p *Block, b *Block) branch {
|
|||
// has one predecessor then (apart from the degenerate case),
|
||||
// there is no path from entry that can reach b through p.Succs[1].
|
||||
// TODO: how about p->yes->b->yes, i.e. a loop in yes.
|
||||
if sdom.isAncestorEq(p.Succs[0].b, b) && len(p.Succs[0].b.Preds) == 1 {
|
||||
if sdom.IsAncestorEq(p.Succs[0].b, b) && len(p.Succs[0].b.Preds) == 1 {
|
||||
return positive
|
||||
}
|
||||
if sdom.isAncestorEq(p.Succs[1].b, b) && len(p.Succs[1].b.Preds) == 1 {
|
||||
if sdom.IsAncestorEq(p.Succs[1].b, b) && len(p.Succs[1].b.Preds) == 1 {
|
||||
return negative
|
||||
}
|
||||
return unknown
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue