mirror of
https://github.com/golang/go
synced 2024-11-21 16:24:40 -07:00
keep adjacent chains close together
This commit is contained in:
parent
2611f3d9aa
commit
9fd9a54977
@ -198,7 +198,13 @@ blockloop:
|
||||
// its own chain, then starting from hottest edge and repeatedly merge two proper
|
||||
// chains iff the edge dest is the first block of dest chain and edge src is the
|
||||
// last block of src chain. Once all edges are processed, the chains are sorted
|
||||
// by hottness and merge count and generate final block order.
|
||||
// by hottness and merge count and generate final block order. The algorithm is
|
||||
// summarized as follows:
|
||||
// - Initially every block is in its own chain.
|
||||
// - Sort edges by weight and move slow path to end.
|
||||
// - Merge proper chains until no more chains can be merged.
|
||||
// - Sort chains by hottness and priority.
|
||||
// - Generate final block order.
|
||||
|
||||
// chain is a linear sequence of blocks, where the first block is the entry block
|
||||
// and the last block is the exit block. The chain is used to represent a sequence
|
||||
@ -261,7 +267,7 @@ func (g *chainGraph) mergeChain(from, to *chain) {
|
||||
g.b2chain[block.ID] = to
|
||||
}
|
||||
to.blocks = append(to.blocks, from.blocks...)
|
||||
to.priority++ // increment
|
||||
to.priority++
|
||||
g.chains[from.id-1 /*ID always >0*/] = nil
|
||||
}
|
||||
|
||||
@ -277,6 +283,12 @@ func (g *chainGraph) print() {
|
||||
}
|
||||
fmt.Printf("id:%d priority:%d blocks:%v\n", ch.id, ch.priority, ch.blocks)
|
||||
}
|
||||
fmt.Printf("== BlockOrder:\n")
|
||||
blockOrder := make([]*Block, 0)
|
||||
for _, chain := range g.chains {
|
||||
blockOrder = append(blockOrder, chain.blocks...)
|
||||
}
|
||||
fmt.Printf("%v\n", blockOrder)
|
||||
}
|
||||
|
||||
func greedyBlockOrder(fn *Func) []*Block {
|
||||
@ -328,8 +340,11 @@ func greedyBlockOrder(fn *Func) []*Block {
|
||||
for _, edge := range graph.edges {
|
||||
c1 := graph.getChain(edge.src)
|
||||
c2 := graph.getChain(edge.dst)
|
||||
// [c1] edge [c2] ? Then merge c1 into c2 and remove entire c1 then
|
||||
if c1 != c2 && (edge.dst == c2.first() && edge.src == c1.last()) {
|
||||
if c1 == c2 {
|
||||
continue
|
||||
}
|
||||
// [..c1..] edge [..c2..] ? Then merge c1 into c2 and remove entire c1 then
|
||||
if edge.dst == c2.first() && edge.src == c1.last() {
|
||||
if fn.pass.debug > 2 {
|
||||
fmt.Printf("process %v merge %v to %v\n",
|
||||
edge, c2.blocks, c1.blocks)
|
||||
@ -383,6 +398,10 @@ func greedyBlockOrder(fn *Func) []*Block {
|
||||
if c1.priority != c2.priority {
|
||||
return c1.priority > c2.priority
|
||||
}
|
||||
// Keep adjacent chains close together
|
||||
if c1.id > c2.id {
|
||||
return false
|
||||
}
|
||||
// Non-terminated chain is considered
|
||||
if s1, s2 := len(c1.last().Succs), len(c2.last().Succs); s1 != s2 {
|
||||
return s1 > s2
|
||||
|
Loading…
Reference in New Issue
Block a user