may be preferred. */
basic_block anchor = loop_preheader_edge (loop)->src;
if (skip_vector)
- split_edge (loop_preheader_edge (loop));
+ {
+ split_edge (loop_preheader_edge (loop));
+
+ /* Due to the order in which we peel prolog and epilog, we first
+ propagate probability to the whole loop. The purpose is to
+ avoid adjusting probabilities of both prolog and vector loops
+ separately. Note in this case, the probability of epilog loop
+ needs to be scaled back later. */
+ basic_block bb_before_loop = loop_preheader_edge (loop)->src;
+ scale_bbs_frequencies_int (&bb_before_loop, 1, prob_vector,
+ REG_BR_PROB_BASE);
+ scale_loop_profile (loop, prob_vector, bound);
+ }
tree niters_prolog = build_int_cst (type, 0);
source_location loop_loc = find_loop_location (loop);
guard_cond = fold_build2 (EQ_EXPR, boolean_type_node,
niters_prolog, build_int_cst (type, 0));
guard_bb = loop_preheader_edge (prolog)->src;
+ basic_block bb_after_prolog = loop_preheader_edge (loop)->src;
guard_to = split_edge (loop_preheader_edge (loop));
guard_e = slpeel_add_loop_guard (guard_bb, guard_cond,
guard_to, guard_bb,
e = EDGE_PRED (guard_to, 0);
e = (e != guard_e ? e : EDGE_PRED (guard_to, 1));
slpeel_update_phi_nodes_for_guard1 (prolog, loop, guard_e, e);
+
+ scale_bbs_frequencies_int (&bb_after_prolog, 1, prob_prolog,
+ REG_BR_PROB_BASE);
scale_loop_profile (prolog, prob_prolog, bound_prolog);
}
/* Update init address of DRs. */
e = EDGE_PRED (guard_to, 0);
e = (e != guard_e ? e : EDGE_PRED (guard_to, 1));
slpeel_update_phi_nodes_for_guard1 (first_loop, epilog, guard_e, e);
- scale_loop_profile (epilog, prob_vector, bound_scalar);
+
+ /* Simply propagate profile info from guard_bb to guard_to which is
+ a merge point of control flow. */
+ guard_to->frequency = guard_bb->frequency;
+ guard_to->count = guard_bb->count;
+ single_succ_edge (guard_to)->count = guard_to->count;
+ /* Scale probability of epilog loop back. */
+ int scale_up = REG_BR_PROB_BASE * REG_BR_PROB_BASE / prob_vector;
+ scale_loop_frequencies (epilog, scale_up, REG_BR_PROB_BASE);
}
+ basic_block bb_before_epilog = loop_preheader_edge (epilog)->src;
tree niters_vector_mult_vf;
/* If loop is peeled for non-zero constant times, now niters refers to
orig_niters - prolog_peeling, it won't overflow even the orig_niters
inverse_probability (prob_epilog));
slpeel_update_phi_nodes_for_guard2 (loop, epilog, guard_e,
single_exit (epilog));
+ /* Only need to handle basic block before epilog loop if it's not
+ the guard_bb, which is the case when skip_vector is true. */
+ if (guard_bb != bb_before_epilog)
+ {
+ prob_epilog = (combine_probabilities (prob_vector, prob_epilog)
+ + inverse_probability (prob_vector));
+
+ scale_bbs_frequencies_int (&bb_before_epilog, 1, prob_epilog,
+ REG_BR_PROB_BASE);
+ }
scale_loop_profile (epilog, prob_epilog, bound);
}
else