@@ -256,7 +256,7 @@ func (g *chainGraph) getChain(b *Block) *chain {
256
256
257
257
// mergeChain merges the "from" chain into the "to" chain. The from chain is
258
258
// removed then.
259
- func (g * chainGraph ) mergeChain (to , from * chain ) {
259
+ func (g * chainGraph ) mergeChain (from , to * chain ) {
260
260
for _ , block := range from .blocks {
261
261
g .b2chain [block .ID ] = to
262
262
}
@@ -321,28 +321,20 @@ func greedyBlockOrder(fn *Func) []*Block {
321
321
// If the weights are the same, then keep the original order, this
322
322
// ensures that adjacent edges are accessed sequentially, which has
323
323
// a noticeable impact on performance
324
- return e1 .weight >= e2 .weight
324
+ return e1 .weight > e2 .weight
325
325
})
326
326
327
327
// Merge proper chains until no more chains can be merged
328
328
for _ , edge := range graph .edges {
329
- src := graph .getChain (edge .src )
330
- dst := graph .getChain (edge .dst )
331
- if src == dst {
332
- // Loop detected, "rotate" the loop from [..,header,body,latch] to
333
- // [..,body,latch,header]
334
- for idx , block := range src .blocks {
335
- if block == edge .dst && block .Kind != BlockPlain /*already rotated?*/ {
336
- c := append (src .blocks [0 :idx ], src .blocks [idx + 1 :]... )
337
- c = append (c , block )
338
- src .blocks = c
339
- break
340
- }
329
+ c1 := graph .getChain (edge .src )
330
+ c2 := graph .getChain (edge .dst )
331
+ // [c1] edge [c2] ? Then merge c1 into c2 and remove entire c1 then
332
+ if c1 != c2 && (edge .dst == c2 .first () && edge .src == c1 .last ()) {
333
+ if fn .pass .debug > 2 {
334
+ fmt .Printf ("process %v merge %v to %v\n " ,
335
+ edge , c2 .blocks , c1 .blocks )
341
336
}
342
- continue
343
- }
344
- if edge .dst == dst .first () && edge .src == src .last () {
345
- graph .mergeChain (src , dst )
337
+ graph .mergeChain (c2 , c1 )
346
338
}
347
339
}
348
340
i := 0
@@ -413,7 +405,7 @@ func greedyBlockOrder(fn *Func) []*Block {
413
405
}
414
406
if len (blockOrder ) != len (fn .Blocks ) {
415
407
graph .print ()
416
- fn .Fatalf ("miss blocks in final order" )
408
+ fn .Fatalf ("miss blocks in final order: %v %v" , blockOrder , fn . Blocks )
417
409
}
418
410
if entryChain := graph .getChain (fn .Entry ); entryChain != graph .chains [0 ] ||
419
411
entryChain .first () != fn .Entry {
0 commit comments