Skip to content

Commit 36f564c

Browse files
committed
fix before precedence relation
"before" precedence relation should be transitive, such that if a is before b, and b is before c, then a should before c
1 parent 9fd9a54 commit 36f564c

File tree

1 file changed

+34
-5
lines changed

1 file changed

+34
-5
lines changed

src/cmd/compile/internal/ssa/layout.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,36 @@ func (g *chainGraph) print() {
291291
fmt.Printf("%v\n", blockOrder)
292292
}
293293

294-
func greedyBlockOrder(fn *Func) []*Block {
294+
func newChainGraph(fn *Func) *chainGraph {
295295
graph := &chainGraph{
296296
chains: []*chain{},
297297
edges: []*edge{},
298298
b2chain: make([]*chain, fn.NumBlocks(), fn.NumBlocks()),
299299
}
300+
return graph
301+
}
302+
303+
// isBefore returns true if block a is before block b in the block order. The
304+
// "before" precedence relation is transitive, i.e., if a is before b and b is
305+
// before c, then a is before c.
306+
func isBefore(before map[*chain][]*chain, visited map[*chain]bool, a, b *chain) bool {
307+
if _, ok := visited[a]; ok {
308+
return false
309+
}
310+
visited[a] = true
311+
for _, c := range before[a] {
312+
if c == b {
313+
return true
314+
}
315+
if isBefore(before, visited, c, b) {
316+
return true
317+
}
318+
}
319+
return false
320+
}
321+
322+
func greedyBlockOrder(fn *Func) []*Block {
323+
graph := newChainGraph(fn)
300324

301325
// Initially every block is in its own chain
302326
for _, block := range fn.Blocks {
@@ -377,6 +401,9 @@ func greedyBlockOrder(fn *Func) []*Block {
377401
src := graph.getChain(edge.src)
378402
dst := graph.getChain(edge.dst)
379403
before[src] = append(before[src], dst)
404+
if fn.pass.debug > 2 {
405+
fmt.Printf("%v comes before %v\n", src.blocks, dst.blocks)
406+
}
380407
}
381408
}
382409
sort.SliceStable(graph.chains, func(i, j int) bool {
@@ -389,10 +416,12 @@ func greedyBlockOrder(fn *Func) []*Block {
389416
return false
390417
}
391418
// Respect precedence relation
392-
for _, b := range before[c1] {
393-
if b == c2 {
394-
return true
395-
}
419+
visited := make(map[*chain]bool)
420+
if isBefore(before, visited, c1, c2) {
421+
return true
422+
}
423+
if isBefore(before, visited, c2, c1) {
424+
return false
396425
}
397426
// Higher merge count is considered
398427
if c1.priority != c2.priority {

0 commit comments

Comments
 (0)