@@ -2271,13 +2271,32 @@ static int ir_schedule_blocks_bottom_up(ir_ctx *ctx)
2271
2271
IR_ASSERT (src == ir_chain_head (chains , e -> from ) && chains [src ].tail == e -> from );
2272
2272
if (src != dst ) {
2273
2273
ir_join_chains (chains , src , dst );
2274
- } else if (ctx -> ir_base [ctx -> cfg_blocks [src ].start ].op == IR_LOOP_BEGIN
2275
- && ctx -> ir_base [ctx -> cfg_blocks [src ].end ].op == IR_IF
2276
- && ctx -> ir_base [ctx -> cfg_blocks [e -> from ].end ].op == IR_LOOP_END ) {
2277
- /* rotate loop moving the loop condition to the end */
2278
- uint32_t new_head = e -> from ;
2279
- chains [src ].head = new_head ;
2280
- chains [new_head ].head = new_head ;
2274
+ } else if (ctx -> cfg_blocks [e -> from ].successors_count < 2 ) {
2275
+ /* Try to rotate loop chian to finish it with a conditional branch */
2276
+ uint32_t tail = e -> from ;
2277
+ uint32_t prev = src ;
2278
+ uint32_t next = chains [prev ].next ;
2279
+ uint32_t best = 0 ;
2280
+
2281
+ while (prev != tail ) {
2282
+ if (ctx -> ir_base [ctx -> cfg_blocks [prev ].end ].op == IR_IF ) {
2283
+ if (ctx -> ir_base [ctx -> cfg_blocks [prev ].start ].op == IR_LOOP_BEGIN
2284
+ && ctx -> cfg_blocks [prev ].loop_depth > 1 ) {
2285
+ best = next ;
2286
+ break ;
2287
+ } else if (!best || bb_freq [next ] < bb_freq [best ]) {
2288
+ /* Find the successor of IF with the least frequency */
2289
+ best = next ;
2290
+ }
2291
+ }
2292
+ prev = next ;
2293
+ next = chains [next ].next ;
2294
+ }
2295
+ if (best ) {
2296
+ /* change the head of the chain */
2297
+ chains [src ].head = best ;
2298
+ chains [best ].head = best ;
2299
+ }
2281
2300
}
2282
2301
#if !IR_DEBUG_BB_SCHEDULE_GRAPH
2283
2302
e -> from = 0 ; /* reset "from" to avoid check on step #5 */
0 commit comments