aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/poset.go
diff options
context:
space:
mode:
authorGiovanni Bajo <rasky@develer.com>2019-09-19 22:39:37 +0200
committerGiovanni Bajo <rasky@develer.com>2019-09-26 21:24:24 +0000
commit490646e476aabf0cc146d2b203ab7a09e1d4847d (patch)
treedab181fb8625e709370da29ce102d5dc3eacc733 /src/cmd/compile/internal/ssa/poset.go
parent4faf8a8dc44555c4fdbe4fb108f42144e58ae6b1 (diff)
downloadgo-490646e476aabf0cc146d2b203ab7a09e1d4847d.tar.gz
go-490646e476aabf0cc146d2b203ab7a09e1d4847d.zip
cmd/compile: in poset, move all constants to the first DAG
In poset, all constants are always related to each other, so they are part of the same DAG. Currently, it can be any of the DAGs in the forest. Since we're about to start visiting that DAG for the task of calculating bounds, make sure that it's conventionally always the first, so that we don't need to search for it. Change-Id: Ia7ca312b52336b4731b070d45cf0d768a0d6aeeb Reviewed-on: https://go-review.googlesource.com/c/go/+/196599 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.go30
1 files changed, 21 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/ssa/poset.go b/src/cmd/compile/internal/ssa/poset.go
index b80b8bd6f0..5548c3b1c4 100644
--- a/src/cmd/compile/internal/ssa/poset.go
+++ b/src/cmd/compile/internal/ssa/poset.go
@@ -125,7 +125,9 @@ type posetNode struct {
// immediately linked to other constants already present; so for instance if the
// poset knows that x<=3, and then x is tested against 5, 5 is first added and linked
// 3 (using 3<5), so that the poset knows that x<=3<5; at that point, it is able
-// to answer x<5 correctly.
+// to answer x<5 correctly. This means that all constants are always within the same
+// DAG; as an implementation detail, we enfoce that the DAG containtining the constants
+// is always the first in the forest.
//
// poset is designed to be memory efficient and do little allocations during normal usage.
// Most internal data structures are pre-allocated and flat, so for instance adding a
@@ -279,10 +281,14 @@ func (po *poset) newconst(n *Value) {
// If this is the first constant, put it into a new root, as
// we can't record an existing connection so we don't have
- // a specific DAG to add it to.
+ // a specific DAG to add it to. Notice that we want all
+ // constants to be in root #0, so make sure the new root
+ // goes there.
if len(po.constants) == 0 {
+ idx := len(po.roots)
i := po.newnode(n)
po.roots = append(po.roots, i)
+ po.roots[0], po.roots[idx] = po.roots[idx], po.roots[0]
po.upush(undoNewRoot, i, 0)
po.constants = append(po.constants, n)
return
@@ -367,6 +373,9 @@ func (po *poset) newconst(n *Value) {
//
i2 := po.values[higherptr.ID]
r2 := po.findroot(i2)
+ if r2 != po.roots[0] { // all constants should be in root #0
+ panic("constant not in root #0")
+ }
dummy := po.newnode(nil)
po.changeroot(r2, dummy)
po.upush(undoChangeRoot, dummy, newedge(r2, false))
@@ -546,6 +555,12 @@ func (po *poset) findroot(i uint32) uint32 {
// mergeroot merges two DAGs into one DAG by creating a new dummy root
func (po *poset) mergeroot(r1, r2 uint32) uint32 {
+ // Root #0 is special as it contains all constants. Since mergeroot
+ // discards r2 as root and keeps r1, make sure that r2 is not root #0,
+ // otherwise constants would move to a different root.
+ if r2 == po.roots[0] {
+ r1, r2 = r2, r1
+ }
r := po.newnode(nil)
po.setchl(r, newedge(r1, false))
po.setchr(r, newedge(r2, false))
@@ -623,10 +638,9 @@ func (po *poset) CheckIntegrity() (err error) {
}
// Verify that each node appears in a single DAG, and that
- // all constants are within the same DAG
- var croot uint32
+ // all constants are within the first DAG
seen := newBitset(int(po.lastidx + 1))
- for _, r := range po.roots {
+ for ridx, r := range po.roots {
if r == 0 {
err = errors.New("empty root")
return
@@ -639,10 +653,8 @@ func (po *poset) CheckIntegrity() (err error) {
}
seen.Set(i)
if constants.Test(i) {
- if croot == 0 {
- croot = r
- } else if croot != r {
- err = errors.New("constants are in different DAGs")
+ if ridx != 0 {
+ err = errors.New("constants not in the first DAG")
return true
}
}