mirror of
https://github.com/golang/go
synced 2024-11-24 21:20:05 -07:00
[dev.ssa] cmd/compile: add backing store buffers for block.{Preds,Succs,Values}
Speeds up compilation by 6%. Change-Id: Ibaad95710323ddbe13c1b0351843fe43a48d776e Reviewed-on: https://go-review.googlesource.com/19080 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
4c5459da2b
commit
056c09bb88
@ -53,6 +53,11 @@ type Block struct {
|
||||
|
||||
// After flagalloc, records whether flags are live at the end of the block.
|
||||
FlagsLiveAtEnd bool
|
||||
|
||||
// Storage for Succs, Preds, and Values
|
||||
succstorage [2]*Block
|
||||
predstorage [4]*Block
|
||||
valstorage [8]*Value
|
||||
}
|
||||
|
||||
// kind control successors
|
||||
|
@ -219,7 +219,7 @@ func checkFunc(f *Func) {
|
||||
f.Fatalf("control value for %s is missing: %v", b, b.Control)
|
||||
}
|
||||
}
|
||||
for b := f.freeBlocks; b != nil; b = b.Aux.(*Block) {
|
||||
for b := f.freeBlocks; b != nil; b = b.succstorage[0] {
|
||||
if blockMark[b.ID] {
|
||||
f.Fatalf("used block b%d in free list", b.ID)
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ func deadcode(f *Func) {
|
||||
b.Values = b.Values[:i]
|
||||
}
|
||||
|
||||
// Remove unreachable blocks. Return dead block ids to allocator.
|
||||
// Remove unreachable blocks. Return dead blocks to allocator.
|
||||
i = 0
|
||||
for _, b := range f.Blocks {
|
||||
if reachable[b.ID] {
|
||||
@ -193,10 +193,6 @@ func deadcode(f *Func) {
|
||||
if len(b.Values) > 0 {
|
||||
b.Fatalf("live values in unreachable block %v: %v", b, b.Values)
|
||||
}
|
||||
b.Preds = nil
|
||||
b.Succs = nil
|
||||
b.Control = nil
|
||||
b.Kind = BlockDead
|
||||
f.freeBlock(b)
|
||||
}
|
||||
}
|
||||
@ -206,9 +202,6 @@ func deadcode(f *Func) {
|
||||
tail[j] = nil
|
||||
}
|
||||
f.Blocks = f.Blocks[:i]
|
||||
|
||||
// TODO: renumber Blocks and Values densely?
|
||||
// TODO: save dead Values and Blocks for reuse? Or should we just let GC handle it?
|
||||
}
|
||||
|
||||
// removePred removes the predecessor p from b's predecessor list.
|
||||
|
@ -30,7 +30,7 @@ type Func struct {
|
||||
Names []LocalSlot
|
||||
|
||||
freeValues *Value // free Values linked by argstorage[0]. All other fields except ID are 0/nil.
|
||||
freeBlocks *Block // free Blocks linked by Aux.(*Block). All other fields except ID are 0/nil.
|
||||
freeBlocks *Block // free Blocks linked by succstorage[0]. All other fields except ID are 0/nil.
|
||||
}
|
||||
|
||||
// NumBlocks returns an integer larger than the id of any Block in the Func.
|
||||
@ -68,7 +68,7 @@ func (f *Func) newValue(op Op, t Type, b *Block, line int32) *Value {
|
||||
|
||||
// freeValue frees a value. It must no longer be referenced.
|
||||
func (f *Func) freeValue(v *Value) {
|
||||
if v.Type == nil {
|
||||
if v.Block == nil {
|
||||
f.Fatalf("trying to free an already freed value")
|
||||
}
|
||||
// Clear everything but ID (which we reuse).
|
||||
@ -84,8 +84,8 @@ func (f *Func) NewBlock(kind BlockKind) *Block {
|
||||
var b *Block
|
||||
if f.freeBlocks != nil {
|
||||
b = f.freeBlocks
|
||||
f.freeBlocks = b.Aux.(*Block)
|
||||
b.Aux = nil
|
||||
f.freeBlocks = b.succstorage[0]
|
||||
b.succstorage[0] = nil
|
||||
} else {
|
||||
ID := f.bid.get()
|
||||
if int(ID) < len(f.Config.blocks) {
|
||||
@ -96,16 +96,22 @@ func (f *Func) NewBlock(kind BlockKind) *Block {
|
||||
}
|
||||
b.Kind = kind
|
||||
b.Func = f
|
||||
b.Preds = b.predstorage[:0]
|
||||
b.Succs = b.succstorage[:0]
|
||||
b.Values = b.valstorage[:0]
|
||||
f.Blocks = append(f.Blocks, b)
|
||||
return b
|
||||
}
|
||||
|
||||
func (f *Func) freeBlock(b *Block) {
|
||||
if b.Func == nil {
|
||||
f.Fatalf("trying to free an already freed block")
|
||||
}
|
||||
// Clear everything but ID (which we reuse).
|
||||
id := b.ID
|
||||
*b = Block{}
|
||||
b.ID = id
|
||||
b.Aux = f.freeBlocks
|
||||
b.succstorage[0] = f.freeBlocks
|
||||
f.freeBlocks = b
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,12 @@ func fuse(f *Func) {
|
||||
}
|
||||
|
||||
// replace b->c edge with preds(b) -> c
|
||||
c.Preds = b.Preds
|
||||
c.predstorage[0] = nil
|
||||
if len(b.Preds) > len(b.predstorage) {
|
||||
c.Preds = b.Preds
|
||||
} else {
|
||||
c.Preds = append(c.predstorage[:0], b.Preds...)
|
||||
}
|
||||
for _, p := range c.Preds {
|
||||
for i, q := range p.Succs {
|
||||
if q == b {
|
||||
|
Loading…
Reference in New Issue
Block a user