cmd/compile: reduce allocations in prove by reusing posets

In prove, reuse posets between different functions by storing them
in the per-worker cache.

Allocation count regression caused by prove improvements is down
from 5% to 3% after this CL.

Updates #25179

Change-Id: I6d14003109833d9b3ef5165fdea00aa9c9e952e8
Reviewed-on: https://go-review.googlesource.com/110455
Run-TryBot: Giovanni Bajo <rasky@develer.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Giovanni Bajo 2018-05-01 00:57:57 +02:00
parent 67656ba71b
commit 3c8545c5f6
5 changed files with 48 additions and 11 deletions

View file

@ -181,10 +181,12 @@ type factsTable struct {
var checkpointFact = fact{}
var checkpointBound = limitFact{}
func newFactsTable() *factsTable {
func newFactsTable(f *Func) *factsTable {
ft := &factsTable{}
ft.order[0] = newPoset(false) // signed
ft.order[1] = newPoset(true) // unsigned
ft.order[0] = f.newPoset() // signed
ft.order[1] = f.newPoset() // unsigned
ft.order[0].SetUnsigned(false)
ft.order[1].SetUnsigned(true)
ft.facts = make(map[pair]relation)
ft.stack = make([]fact, 4)
ft.limits = make(map[ID]limit)
@ -666,7 +668,8 @@ var (
// its negation. If either leads to a contradiction, it can trim that
// successor.
func prove(f *Func) {
ft := newFactsTable()
ft := newFactsTable(f)
ft.checkpoint()
// Find length and capacity ops.
var zero *Value
@ -794,6 +797,20 @@ func prove(f *Func) {
ft.restore()
}
}
ft.restore()
// Return the posets to the free list
for _, po := range ft.order {
// Make sure it's empty as it should be. A non-empty poset
// might cause errors and miscompilations if reused.
if checkEnabled {
if err := po.CheckEmpty(); err != nil {
f.Fatalf("prove poset not empty after function %s: %v", f.Name, err)
}
}
f.retPoset(po)
}
}
// getBranch returns the range restrictions added by p