@@ -291,12 +291,36 @@ func (g *chainGraph) print() {
291
291
fmt .Printf ("%v\n " , blockOrder )
292
292
}
293
293
294
- func greedyBlockOrder (fn * Func ) [] * Block {
294
+ func newChainGraph (fn * Func ) * chainGraph {
295
295
graph := & chainGraph {
296
296
chains : []* chain {},
297
297
edges : []* edge {},
298
298
b2chain : make ([]* chain , fn .NumBlocks (), fn .NumBlocks ()),
299
299
}
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 )
300
324
301
325
// Initially every block is in its own chain
302
326
for _ , block := range fn .Blocks {
@@ -377,6 +401,9 @@ func greedyBlockOrder(fn *Func) []*Block {
377
401
src := graph .getChain (edge .src )
378
402
dst := graph .getChain (edge .dst )
379
403
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
+ }
380
407
}
381
408
}
382
409
sort .SliceStable (graph .chains , func (i , j int ) bool {
@@ -389,10 +416,12 @@ func greedyBlockOrder(fn *Func) []*Block {
389
416
return false
390
417
}
391
418
// 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
396
425
}
397
426
// Higher merge count is considered
398
427
if c1 .priority != c2 .priority {
0 commit comments