static rtx_expr_list * extract_mentioned_regs (rtx x) { rtx_expr_list *mentioned_regs = NULL; subrtx_var_iterator::array_type array; FOR_EACH_SUBRTX_VAR (iter, array, x, NONCONST) { rtx x = *iter; if (REG_P (x)) mentioned_regs = alloc_EXPR_LIST (0, x, mentioned_regs); }
/* Unswitch single LOOP. COND_CHECKED holds list of conditions we already unswitched on and are therefore known to be true in this LOOP. NUM is number of unswitchings done; do not allow it to grow too much, it is too easy to create example on that the code would grow exponentially. Returns true LOOP was unswitched. */ static bool unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { basic_block *bbs; struct loop *nloop; unsigned i; rtx cond, rcond = NULL_RTX, conds, rconds, acond, cinsn; int repeat; edge e; HOST_WIDE_INT iterations; /* Do not unswitch too much. */ if (num > PARAM_VALUE (PARAM_MAX_UNSWITCH_LEVEL)) { if (dump_file) fprintf (dump_file, ";; Not unswitching anymore, hit max level\n"); return false; } /* Only unswitch innermost loops. */ if (loop->inner) { if (dump_file) fprintf (dump_file, ";; Not unswitching, not innermost loop\n"); return false; } /* We must be able to duplicate loop body. */ if (!can_duplicate_loop_p (loop)) { if (dump_file) fprintf (dump_file, ";; Not unswitching, can't duplicate loop\n"); return false; } /* The loop should not be too large, to limit code growth. */ if (num_loop_insns (loop) > PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS)) { if (dump_file) fprintf (dump_file, ";; Not unswitching, loop too big\n"); return false; } /* Do not unswitch in cold areas. */ if (optimize_loop_for_size_p (loop)) { if (dump_file) fprintf (dump_file, ";; Not unswitching, not hot area\n"); return false; } /* Nor if the loop usually does not roll. */ iterations = estimated_loop_iterations_int (loop); if (iterations >= 0 && iterations <= 1) { if (dump_file) fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n"); return false; } do { repeat = 0; cinsn = NULL_RTX; /* Find a bb to unswitch on. */ bbs = get_loop_body (loop); iv_analysis_loop_init (loop); for (i = 0; i < loop->num_nodes; i++) if ((cond = may_unswitch_on (bbs[i], loop, &cinsn))) break; if (i == loop->num_nodes) { free (bbs); return false; } if (cond != const0_rtx && cond != const_true_rtx) { rcond = reversed_condition (cond); if (rcond) rcond = canon_condition (rcond); /* Check whether the result can be predicted. */ for (acond = cond_checked; acond; acond = XEXP (acond, 1)) simplify_using_condition (XEXP (acond, 0), &cond, NULL); } if (cond == const_true_rtx) { /* Remove false path. */ e = FALLTHRU_EDGE (bbs[i]); remove_path (e); free (bbs); repeat = 1; } else if (cond == const0_rtx) { /* Remove true path. */ e = BRANCH_EDGE (bbs[i]); remove_path (e); free (bbs); repeat = 1; } } while (repeat); /* We found the condition we can unswitch on. */ conds = alloc_EXPR_LIST (0, cond, cond_checked); if (rcond) rconds = alloc_EXPR_LIST (0, rcond, cond_checked); else rconds = cond_checked; if (dump_file) fprintf (dump_file, ";; Unswitching loop\n"); /* Unswitch the loop on this condition. */ nloop = unswitch_loop (loop, bbs[i], copy_rtx_if_shared (cond), cinsn); gcc_assert (nloop); /* Invoke itself on modified loops. */ unswitch_single_loop (nloop, rconds, num + 1); unswitch_single_loop (loop, conds, num + 1); free_EXPR_LIST_node (conds); if (rcond) free_EXPR_LIST_node (rconds); free (bbs); return true; }