diff options
author | Giovanni Bajo <rasky@develer.com> | 2018-05-12 22:13:44 +0200 |
---|---|---|
committer | David Chase <drchase@google.com> | 2018-05-14 14:31:48 +0000 |
commit | 67656ba71b54779d9f98995a12ed87e7c7618cad (patch) | |
tree | 96d966243ec28054911c136e146b352b9ed77069 /src/cmd/compile/internal/ssa/poset.go | |
parent | 7bac2a95f65418ec18d1fb5f30ae47e91980f30c (diff) | |
download | go-67656ba71b54779d9f98995a12ed87e7c7618cad.tar.gz go-67656ba71b54779d9f98995a12ed87e7c7618cad.zip |
cmd/compile: improve undo of poset
prove uses the poset datastructure in a DFS walk, and always undoes
it back to its pristine status. Before this CL, poset's undo of
a new node creation didn't fully deallocate the node, which means
that at the end of prove there was still some allocated memory pending.
This was not a problem until now because the posets used by prove
were discarded after each function, but it would prevent recycling
them between functions (as a followup CL does).
Change-Id: I1c1c99c03fe19ad765395a43958cb256f686765a
Reviewed-on: https://go-review.googlesource.com/112976
Run-TryBot: Giovanni Bajo <rasky@develer.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/poset.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/poset.go | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/ssa/poset.go b/src/cmd/compile/internal/ssa/poset.go index 22826b92bb..26a689404d 100644 --- a/src/cmd/compile/internal/ssa/poset.go +++ b/src/cmd/compile/internal/ssa/poset.go @@ -679,13 +679,24 @@ func (po *poset) CheckIntegrity() (err error) { // It can be used for debugging purposes, as a poset is supposed to // be empty after it's fully rolled back through Undo. func (po *poset) CheckEmpty() error { - // Check that the poset is completely empty + if len(po.nodes) != 1 { + return fmt.Errorf("non-empty nodes list: %v", po.nodes) + } if len(po.values) != 0 { return fmt.Errorf("non-empty value map: %v", po.values) } if len(po.roots) != 0 { return fmt.Errorf("non-empty root list: %v", po.roots) } + if len(po.constants) != 0 { + return fmt.Errorf("non-empty constants: %v", po.constants) + } + if len(po.undo) != 0 { + return fmt.Errorf("non-empty undo list: %v", po.undo) + } + if po.lastidx != 0 { + return fmt.Errorf("lastidx index is not zero: %v", po.lastidx) + } for _, bs := range po.noneq { for _, x := range bs { if x != 0 { @@ -693,14 +704,6 @@ func (po *poset) CheckEmpty() error { } } } - for idx, n := range po.nodes { - if n.l|n.r != 0 { - return fmt.Errorf("non-empty node %v->[%d,%d]", idx, n.l.Target(), n.r.Target()) - } - } - if len(po.constants) != 0 { - return fmt.Errorf("non-empty constant") - } return nil } @@ -1123,6 +1126,9 @@ func (po *poset) Undo() { po.noneq[pass.ID].Clear(pass.idx) case undoNewNode: + if pass.idx != po.lastidx { + panic("invalid newnode index") + } if pass.ID != 0 { if po.values[pass.ID] != pass.idx { panic("invalid newnode undo pass") @@ -1131,6 +1137,8 @@ func (po *poset) Undo() { } po.setchl(pass.idx, 0) po.setchr(pass.idx, 0) + po.nodes = po.nodes[:pass.idx] + po.lastidx-- // If it was the last inserted constant, remove it nc := len(po.constants) |