mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] Merge remote-tracking branch 'origin/master' into mergebranch
Semi-regular merge of tip to dev.ssa. Complicated a bit by the move of cmd/internal/* to cmd/compile/internal/*. Change-Id: I1c66d3c29bb95cce4a53c5a3476373aa5245303d
This commit is contained in:
commit
067e8dfd82
618 changed files with 14079 additions and 7877 deletions
88
src/cmd/compile/internal/ssa/layout.go
Normal file
88
src/cmd/compile/internal/ssa/layout.go
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ssa
|
||||
|
||||
import "log"
|
||||
|
||||
// layout orders basic blocks in f with the goal of minimizing control flow instructions.
|
||||
// After this phase returns, the order of f.Blocks matters and is the order
|
||||
// in which those blocks will appear in the assembly output.
|
||||
func layout(f *Func) {
|
||||
order := make([]*Block, 0, f.NumBlocks())
|
||||
scheduled := make([]bool, f.NumBlocks())
|
||||
idToBlock := make([]*Block, f.NumBlocks())
|
||||
indegree := make([]int, f.NumBlocks())
|
||||
posdegree := newSparseSet(f.NumBlocks()) // blocks with positive remaining degree
|
||||
zerodegree := newSparseSet(f.NumBlocks()) // blocks with zero remaining degree
|
||||
|
||||
// Initialize indegree of each block
|
||||
for _, b := range f.Blocks {
|
||||
idToBlock[b.ID] = b
|
||||
indegree[b.ID] = len(b.Preds)
|
||||
if len(b.Preds) == 0 {
|
||||
zerodegree.add(b.ID)
|
||||
} else {
|
||||
posdegree.add(b.ID)
|
||||
}
|
||||
}
|
||||
|
||||
bid := f.Entry.ID
|
||||
blockloop:
|
||||
for {
|
||||
// add block to schedule
|
||||
b := idToBlock[bid]
|
||||
order = append(order, b)
|
||||
scheduled[bid] = true
|
||||
if len(order) == len(f.Blocks) {
|
||||
break
|
||||
}
|
||||
|
||||
for _, c := range b.Succs {
|
||||
indegree[c.ID]--
|
||||
if indegree[c.ID] == 0 {
|
||||
posdegree.remove(c.ID)
|
||||
zerodegree.add(c.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// Pick the next block to schedule
|
||||
// Pick among the successor blocks that have not been scheduled yet.
|
||||
// Just use degree for now. TODO(khr): use likely direction hints.
|
||||
bid = 0
|
||||
mindegree := f.NumBlocks()
|
||||
for _, c := range order[len(order)-1].Succs {
|
||||
if scheduled[c.ID] {
|
||||
continue
|
||||
}
|
||||
if indegree[c.ID] < mindegree {
|
||||
mindegree = indegree[c.ID]
|
||||
bid = c.ID
|
||||
}
|
||||
}
|
||||
if bid != 0 {
|
||||
continue
|
||||
}
|
||||
// TODO: improve this part
|
||||
// No successor of the previously scheduled block works.
|
||||
// Pick a zero-degree block if we can.
|
||||
for zerodegree.size() > 0 {
|
||||
cid := zerodegree.pop()
|
||||
if !scheduled[cid] {
|
||||
bid = cid
|
||||
continue blockloop
|
||||
}
|
||||
}
|
||||
// Still nothing, pick any block.
|
||||
for {
|
||||
cid := posdegree.pop()
|
||||
if !scheduled[cid] {
|
||||
bid = cid
|
||||
continue blockloop
|
||||
}
|
||||
}
|
||||
log.Panicf("no block available for layout")
|
||||
}
|
||||
f.Blocks = order
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue