Commit 19532d04 authored by Giovanni Bajo's avatar Giovanni Bajo

cmd/compile: add debugging mode for poset

Add an internal mode to simplify debugging of posets
by checking the integrity after every mutation. Turn
it on within SSA checked builds.

Change-Id: Idaa8277f58e5bce3753702e212cea4d698de30ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/196780
Run-TryBot: Giovanni Bajo <rasky@develer.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarKeith Randall <khr@golang.org>
Reviewed-by: default avatarDavid Chase <drchase@google.com>
parent 19e0799b
...@@ -286,10 +286,12 @@ commas. For example: ...@@ -286,10 +286,12 @@ commas. For example:
if phase == "check" && flag == "on" { if phase == "check" && flag == "on" {
checkEnabled = val != 0 checkEnabled = val != 0
debugPoset = checkEnabled // also turn on advanced self-checking in prove's datastructure
return "" return ""
} }
if phase == "check" && flag == "off" { if phase == "check" && flag == "off" {
checkEnabled = val == 0 checkEnabled = val == 0
debugPoset = checkEnabled
return "" return ""
} }
......
...@@ -9,6 +9,9 @@ import ( ...@@ -9,6 +9,9 @@ import (
"os" "os"
) )
// If true, check poset integrity after every mutation
var debugPoset = false
const uintSize = 32 << (^uint(0) >> 32 & 1) // 32 or 64 const uintSize = 32 << (^uint(0) >> 32 & 1) // 32 or 64
// bitset is a bit array for dense indexes. // bitset is a bit array for dense indexes.
...@@ -785,6 +788,9 @@ func (po *poset) DotDump(fn string, title string) error { ...@@ -785,6 +788,9 @@ func (po *poset) DotDump(fn string, title string) error {
// to tell. // to tell.
// Complexity is O(n). // Complexity is O(n).
func (po *poset) Ordered(n1, n2 *Value) bool { func (po *poset) Ordered(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call Ordered with n1==n2") panic("should not call Ordered with n1==n2")
} }
...@@ -803,6 +809,9 @@ func (po *poset) Ordered(n1, n2 *Value) bool { ...@@ -803,6 +809,9 @@ func (po *poset) Ordered(n1, n2 *Value) bool {
// to tell. // to tell.
// Complexity is O(n). // Complexity is O(n).
func (po *poset) OrderedOrEqual(n1, n2 *Value) bool { func (po *poset) OrderedOrEqual(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call Ordered with n1==n2") panic("should not call Ordered with n1==n2")
} }
...@@ -821,6 +830,9 @@ func (po *poset) OrderedOrEqual(n1, n2 *Value) bool { ...@@ -821,6 +830,9 @@ func (po *poset) OrderedOrEqual(n1, n2 *Value) bool {
// to tell. // to tell.
// Complexity is O(1). // Complexity is O(1).
func (po *poset) Equal(n1, n2 *Value) bool { func (po *poset) Equal(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call Equal with n1==n2") panic("should not call Equal with n1==n2")
} }
...@@ -836,6 +848,9 @@ func (po *poset) Equal(n1, n2 *Value) bool { ...@@ -836,6 +848,9 @@ func (po *poset) Equal(n1, n2 *Value) bool {
// Complexity is O(n) (because it internally calls Ordered to see if we // Complexity is O(n) (because it internally calls Ordered to see if we
// can infer n1!=n2 from n1<n2 or n2<n1). // can infer n1!=n2 from n1<n2 or n2<n1).
func (po *poset) NonEqual(n1, n2 *Value) bool { func (po *poset) NonEqual(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call Equal with n1==n2") panic("should not call Equal with n1==n2")
} }
...@@ -982,6 +997,9 @@ func (po *poset) setOrder(n1, n2 *Value, strict bool) bool { ...@@ -982,6 +997,9 @@ func (po *poset) setOrder(n1, n2 *Value, strict bool) bool {
// SetOrder records that n1<n2. Returns false if this is a contradiction // SetOrder records that n1<n2. Returns false if this is a contradiction
// Complexity is O(1) if n2 was never seen before, or O(n) otherwise. // Complexity is O(1) if n2 was never seen before, or O(n) otherwise.
func (po *poset) SetOrder(n1, n2 *Value) bool { func (po *poset) SetOrder(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call SetOrder with n1==n2") panic("should not call SetOrder with n1==n2")
} }
...@@ -991,6 +1009,9 @@ func (po *poset) SetOrder(n1, n2 *Value) bool { ...@@ -991,6 +1009,9 @@ func (po *poset) SetOrder(n1, n2 *Value) bool {
// SetOrderOrEqual records that n1<=n2. Returns false if this is a contradiction // SetOrderOrEqual records that n1<=n2. Returns false if this is a contradiction
// Complexity is O(1) if n2 was never seen before, or O(n) otherwise. // Complexity is O(1) if n2 was never seen before, or O(n) otherwise.
func (po *poset) SetOrderOrEqual(n1, n2 *Value) bool { func (po *poset) SetOrderOrEqual(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call SetOrder with n1==n2") panic("should not call SetOrder with n1==n2")
} }
...@@ -1001,6 +1022,9 @@ func (po *poset) SetOrderOrEqual(n1, n2 *Value) bool { ...@@ -1001,6 +1022,9 @@ func (po *poset) SetOrderOrEqual(n1, n2 *Value) bool {
// (that is, if it is already recorded that n1<n2 or n2<n1). // (that is, if it is already recorded that n1<n2 or n2<n1).
// Complexity is O(1) if n2 was never seen before, or O(n) otherwise. // Complexity is O(1) if n2 was never seen before, or O(n) otherwise.
func (po *poset) SetEqual(n1, n2 *Value) bool { func (po *poset) SetEqual(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call Add with n1==n2") panic("should not call Add with n1==n2")
} }
...@@ -1060,6 +1084,9 @@ func (po *poset) SetEqual(n1, n2 *Value) bool { ...@@ -1060,6 +1084,9 @@ func (po *poset) SetEqual(n1, n2 *Value) bool {
// (that is, if it is already recorded that n1==n2). // (that is, if it is already recorded that n1==n2).
// Complexity is O(n). // Complexity is O(n).
func (po *poset) SetNonEqual(n1, n2 *Value) bool { func (po *poset) SetNonEqual(n1, n2 *Value) bool {
if debugPoset {
defer po.CheckIntegrity()
}
if n1.ID == n2.ID { if n1.ID == n2.ID {
panic("should not call Equal with n1==n2") panic("should not call Equal with n1==n2")
} }
...@@ -1108,6 +1135,9 @@ func (po *poset) Undo() { ...@@ -1108,6 +1135,9 @@ func (po *poset) Undo() {
if len(po.undo) == 0 { if len(po.undo) == 0 {
panic("empty undo stack") panic("empty undo stack")
} }
if debugPoset {
defer po.CheckIntegrity()
}
for len(po.undo) > 0 { for len(po.undo) > 0 {
pass := po.undo[len(po.undo)-1] pass := po.undo[len(po.undo)-1]
...@@ -1187,4 +1217,8 @@ func (po *poset) Undo() { ...@@ -1187,4 +1217,8 @@ func (po *poset) Undo() {
panic(pass.typ) panic(pass.typ)
} }
} }
if debugPoset && po.CheckEmpty() != nil {
panic("poset not empty at the end of undo")
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment