static bool tree_ssa_ifcombine_bb (basic_block inner_cond_bb) { basic_block then_bb = NULL, else_bb = NULL; if (!recognize_if_then_else (inner_cond_bb, &then_bb, &else_bb)) return false; /* Recognize && and || of two conditions with a common then/else block which entry edges we can merge. That is: if (a || b) ; and if (a && b) ; This requires a single predecessor of the inner cond_bb. */ if (single_pred_p (inner_cond_bb)) { basic_block outer_cond_bb = single_pred (inner_cond_bb); /* The && form is characterized by a common else_bb with the two edges leading to it mergable. The latter is guaranteed by matching PHI arguments in the else_bb and the inner cond_bb having no side-effects. */ if (recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb) && same_phi_args_p (outer_cond_bb, inner_cond_bb, else_bb) && bb_no_side_effects_p (inner_cond_bb)) { /* We have <outer_cond_bb> if (q) goto inner_cond_bb; else goto else_bb; <inner_cond_bb> if (p) goto ...; else goto else_bb; ... <else_bb> ... */ return ifcombine_ifandif (inner_cond_bb, outer_cond_bb); } /* The || form is characterized by a common then_bb with the two edges leading to it mergable. The latter is guaranteed by matching PHI arguments in the then_bb and the inner cond_bb having no side-effects. */ if (recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb) && same_phi_args_p (outer_cond_bb, inner_cond_bb, then_bb) && bb_no_side_effects_p (inner_cond_bb)) { /* We have <outer_cond_bb> if (q) goto then_bb; else goto inner_cond_bb; <inner_cond_bb> if (q) goto then_bb; else goto ...; <then_bb> ... */ return ifcombine_iforif (inner_cond_bb, outer_cond_bb); } } return false; }
static bool tree_ssa_ifcombine_bb_1 (basic_block inner_cond_bb, basic_block outer_cond_bb, basic_block then_bb, basic_block else_bb, basic_block phi_pred_bb) { /* The && form is characterized by a common else_bb with the two edges leading to it mergable. The latter is guaranteed by matching PHI arguments in the else_bb and the inner cond_bb having no side-effects. */ if (phi_pred_bb != else_bb && recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &else_bb) && same_phi_args_p (outer_cond_bb, phi_pred_bb, else_bb) && bb_no_side_effects_p (inner_cond_bb)) { /* We have <outer_cond_bb> if (q) goto inner_cond_bb; else goto else_bb; <inner_cond_bb> if (p) goto ...; else goto else_bb; ... <else_bb> ... */ return ifcombine_ifandif (inner_cond_bb, false, outer_cond_bb, false, false); } /* And a version where the outer condition is negated. */ if (phi_pred_bb != else_bb && recognize_if_then_else (outer_cond_bb, &else_bb, &inner_cond_bb) && same_phi_args_p (outer_cond_bb, phi_pred_bb, else_bb) && bb_no_side_effects_p (inner_cond_bb)) { /* We have <outer_cond_bb> if (q) goto else_bb; else goto inner_cond_bb; <inner_cond_bb> if (p) goto ...; else goto else_bb; ... <else_bb> ... */ return ifcombine_ifandif (inner_cond_bb, false, outer_cond_bb, true, false); } /* The || form is characterized by a common then_bb with the two edges leading to it mergable. The latter is guaranteed by matching PHI arguments in the then_bb and the inner cond_bb having no side-effects. */ if (phi_pred_bb != then_bb && recognize_if_then_else (outer_cond_bb, &then_bb, &inner_cond_bb) && same_phi_args_p (outer_cond_bb, phi_pred_bb, then_bb) && bb_no_side_effects_p (inner_cond_bb)) { /* We have <outer_cond_bb> if (q) goto then_bb; else goto inner_cond_bb; <inner_cond_bb> if (q) goto then_bb; else goto ...; <then_bb> ... */ return ifcombine_ifandif (inner_cond_bb, true, outer_cond_bb, true, true); } /* And a version where the outer condition is negated. */ if (phi_pred_bb != then_bb && recognize_if_then_else (outer_cond_bb, &inner_cond_bb, &then_bb) && same_phi_args_p (outer_cond_bb, phi_pred_bb, then_bb) && bb_no_side_effects_p (inner_cond_bb)) { /* We have <outer_cond_bb> if (q) goto inner_cond_bb; else goto then_bb; <inner_cond_bb> if (q) goto then_bb; else goto ...; <then_bb> ... */ return ifcombine_ifandif (inner_cond_bb, true, outer_cond_bb, false, true); } return false; }