static bool split_paths () { bool changed = false; loop_p loop; loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); initialize_original_copy_tables (); calculate_dominance_info (CDI_DOMINATORS); FOR_EACH_LOOP (loop, LI_FROM_INNERMOST) { /* Only split paths if we are optimizing this loop for speed. */ if (!optimize_loop_for_speed_p (loop)) continue; /* See if there is a block that we can duplicate to split the path to the loop latch. */ basic_block bb = find_block_to_duplicate_for_splitting_paths (loop->latch); /* BB is the merge point for an IF-THEN-ELSE we want to transform. Essentially we want to create a duplicate of bb and redirect the first predecessor of BB to the duplicate (leaving the second predecessor as is. This will split the path leading to the latch re-using BB to avoid useless copying. */ if (bb && is_feasible_trace (bb)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Duplicating join block %d into predecessor paths\n", bb->index); basic_block pred0 = EDGE_PRED (bb, 0)->src; transform_duplicate (pred0, bb); changed = true; } } loop_optimizer_finalize (); free_original_copy_tables (); return changed; }
static bool split_paths () { bool changed = false; loop_p loop; loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS); initialize_original_copy_tables (); calculate_dominance_info (CDI_DOMINATORS); FOR_EACH_LOOP (loop, LI_FROM_INNERMOST) { /* Only split paths if we are optimizing this loop for speed. */ if (!optimize_loop_for_speed_p (loop)) continue; /* See if there is a block that we can duplicate to split the path to the loop latch. */ basic_block bb = find_block_to_duplicate_for_splitting_paths (loop->latch); /* BB is the merge point for an IF-THEN-ELSE we want to transform. Essentially we want to create a duplicate of bb and redirect the first predecessor of BB to the duplicate (leaving the second predecessor as is. This will split the path leading to the latch re-using BB to avoid useless copying. */ if (bb && is_feasible_trace (bb)) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Duplicating join block %d into predecessor paths\n", bb->index); basic_block pred0 = EDGE_PRED (bb, 0)->src; transform_duplicate (pred0, bb); changed = true; /* If BB has an outgoing edge marked as IRREDUCIBLE, then duplicating BB may result in an irreducible region turning into a natural loop. Long term we might want to hook this into the block duplication code, but as we've seen with similar changes for edge removal, that can be somewhat risky. */ if (EDGE_SUCC (bb, 0)->flags & EDGE_IRREDUCIBLE_LOOP || EDGE_SUCC (bb, 1)->flags & EDGE_IRREDUCIBLE_LOOP) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Join block %d has EDGE_IRREDUCIBLE_LOOP set. " "Scheduling loop fixups.\n", bb->index); loops_state_set (LOOPS_NEED_FIXUP); } } } loop_optimizer_finalize (); free_original_copy_tables (); return changed; }