diff options
author | Dan Scales <danscales@google.com> | 2019-11-01 14:04:08 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2019-11-05 17:19:16 +0000 |
commit | 1b3a1db19fc68591198149540f7b3c99f56691da (patch) | |
tree | c7829cb7cc4d46c253a346b39cf6910b17815038 /src/cmd/compile/internal/ssa/regalloc.go | |
parent | 414c1d454e6d388443239209220fe0783d4dac71 (diff) | |
download | go-1b3a1db19fc68591198149540f7b3c99f56691da.tar.gz go-1b3a1db19fc68591198149540f7b3c99f56691da.zip |
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>
Diffstat (limited to 'src/cmd/compile/internal/ssa/regalloc.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/regalloc.go | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index d7e931d0b8..e125ae4239 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -683,7 +683,7 @@ func (s *regAllocState) init(f *Func) { s.endRegs = make([][]endReg, f.NumBlocks()) s.startRegs = make([][]startReg, f.NumBlocks()) s.spillLive = make([][]ID, f.NumBlocks()) - s.sdom = f.sdom() + s.sdom = f.Sdom() // wasm: Mark instructions that can be optimized to have their values only on the WebAssembly stack. if f.Config.ctxt.Arch.Arch == sys.ArchWasm { @@ -1916,7 +1916,7 @@ func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive for _, spillID := range stacklive { v := e.s.orig[spillID] spill := e.s.values[v.ID].spill - if !e.s.sdom.isAncestorEq(spill.Block, e.p) { + if !e.s.sdom.IsAncestorEq(spill.Block, e.p) { // Spills were placed that only dominate the uses found // during the first regalloc pass. The edge fixup code // can't use a spill location if the spill doesn't dominate |