1
0
mirror of https://github.com/golang/go synced 2024-11-22 04:54:42 -07:00

keep adjacent chains close together

This commit is contained in:
Yi Yang 2024-06-27 15:56:44 +08:00
parent 2611f3d9aa
commit 9fd9a54977

View File

@ -198,7 +198,13 @@ blockloop:
// its own chain, then starting from hottest edge and repeatedly merge two proper // 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 // 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 // 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 // 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 // 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 g.b2chain[block.ID] = to
} }
to.blocks = append(to.blocks, from.blocks...) to.blocks = append(to.blocks, from.blocks...)
to.priority++ // increment to.priority++
g.chains[from.id-1 /*ID always >0*/] = nil 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("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 { func greedyBlockOrder(fn *Func) []*Block {
@ -328,8 +340,11 @@ func greedyBlockOrder(fn *Func) []*Block {
for _, edge := range graph.edges { for _, edge := range graph.edges {
c1 := graph.getChain(edge.src) c1 := graph.getChain(edge.src)
c2 := graph.getChain(edge.dst) c2 := graph.getChain(edge.dst)
// [c1] edge [c2] ? Then merge c1 into c2 and remove entire c1 then if c1 == c2 {
if c1 != c2 && (edge.dst == c2.first() && edge.src == c1.last()) { 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 { if fn.pass.debug > 2 {
fmt.Printf("process %v merge %v to %v\n", fmt.Printf("process %v merge %v to %v\n",
edge, c2.blocks, c1.blocks) edge, c2.blocks, c1.blocks)
@ -383,6 +398,10 @@ func greedyBlockOrder(fn *Func) []*Block {
if c1.priority != c2.priority { if c1.priority != c2.priority {
return 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 // Non-terminated chain is considered
if s1, s2 := len(c1.last().Succs), len(c2.last().Succs); s1 != s2 { if s1, s2 := len(c1.last().Succs), len(c2.last().Succs); s1 != s2 {
return s1 > s2 return s1 > s2