> So what did actually change? I'd rather not diff the diffs. Can you
> provide an incremental change, aka p6 that would apply to the
> previous series instead?
-p6.diff attached which also addresses Richard's remark regarding vf/2.
Note that this applies to the old series but the old series itself (-p3)
doesn't apply to trunk anymore (because of the change in
vect_enhance_data_refs_alignment).
Regards
Robin
--
gcc/ChangeLog:
2017-05-24 Robin Dapp <[email protected]>
* tree-vect-data-refs.c (vect_get_peeling_costs_all_drs):
Introduce unknown_misalignment parameter and remove vf.
(vect_peeling_hash_get_lowest_cost):
Pass unknown_misalignemtn parameter.
(vect_enhance_data_refs_alignment):
Fix unsupportable data ref treatment.
*** /tmp/qBXCWe_tree-vect-data-refs.c 2017-05-24 13:44:37.939055376 +0200
--- gcc/tree-vect-data-refs.c 2017-05-24 13:44:12.039055376 +0200
***************
*** 1239,1252 ****
}
/* Get the costs of peeling NPEEL iterations checking data access costs
! for all data refs. */
static void
vect_get_peeling_costs_all_drs (struct data_reference *dr0,
unsigned int *inside_cost,
unsigned int *outside_cost,
stmt_vector_for_cost *body_cost_vec,
! unsigned int npeel, unsigned int vf)
{
gimple *stmt = DR_STMT (dr0);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
--- 1239,1254 ----
}
/* Get the costs of peeling NPEEL iterations checking data access costs
! for all data refs. If UNKNOWN_MISALIGNMENT is true, we assume DR0's
! misalignment will be zero after peeling. */
static void
vect_get_peeling_costs_all_drs (struct data_reference *dr0,
unsigned int *inside_cost,
unsigned int *outside_cost,
stmt_vector_for_cost *body_cost_vec,
! unsigned int npeel,
! bool unknown_misalignment)
{
gimple *stmt = DR_STMT (dr0);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
***************
*** 1274,1280 ****
int save_misalignment;
save_misalignment = DR_MISALIGNMENT (dr);
! if (dr == dr0 && npeel == vf / 2)
SET_DR_MISALIGNMENT (dr, 0);
else
vect_update_misalignment_for_peel (dr, dr0, npeel);
--- 1276,1282 ----
int save_misalignment;
save_misalignment = DR_MISALIGNMENT (dr);
! if (unknown_misalignment && dr == dr0)
SET_DR_MISALIGNMENT (dr, 0);
else
vect_update_misalignment_for_peel (dr, dr0, npeel);
***************
*** 1305,1311 ****
epilogue_cost_vec.create (2);
vect_get_peeling_costs_all_drs (elem->dr, &inside_cost, &outside_cost,
! &body_cost_vec, elem->npeel, 0);
outside_cost += vect_get_known_peeling_cost
(loop_vinfo, elem->npeel, &dummy,
--- 1307,1313 ----
epilogue_cost_vec.create (2);
vect_get_peeling_costs_all_drs (elem->dr, &inside_cost, &outside_cost,
! &body_cost_vec, elem->npeel, false);
outside_cost += vect_get_known_peeling_cost
(loop_vinfo, elem->npeel, &dummy,
***************
*** 1517,1522 ****
--- 1519,1525 ----
{
vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ enum dr_alignment_support supportable_dr_alignment;
struct data_reference *dr0 = NULL, *first_store = NULL;
struct data_reference *dr;
unsigned int i, j;
***************
*** 1528,1533 ****
--- 1531,1538 ----
unsigned int npeel = 0;
bool one_misalignment_known = false;
bool one_misalignment_unknown = false;
+ bool one_dr_unsupportable = false;
+ struct data_reference *unsupportable_dr = NULL;
unsigned int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
unsigned possible_npeel_number = 1;
tree vectype;
***************
*** 1599,1604 ****
--- 1604,1610 ----
&& !STMT_VINFO_GROUPED_ACCESS (stmt_info))
continue;
+ supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
do_peeling = vector_alignment_reachable_p (dr);
if (do_peeling)
{
***************
*** 1637,1644 ****
else
possible_npeel_number = vf / nelements;
! /* NPEEL_TMP is 0 when there is no misalignment, increment
! the peeling amount by one in order to ... */
if (DR_MISALIGNMENT (dr) == 0)
possible_npeel_number++;
}
--- 1643,1650 ----
else
possible_npeel_number = vf / nelements;
! /* NPEEL_TMP is 0 when there is no misalignment, but also
! allow peeling NELEMENTS. */
if (DR_MISALIGNMENT (dr) == 0)
possible_npeel_number++;
}
***************
*** 1684,1693 ****
dr0 = dr;
}
if (!first_store && DR_IS_WRITE (dr))
first_store = dr;
-
- one_misalignment_unknown = true;
}
}
else
--- 1690,1707 ----
dr0 = dr;
}
+ one_misalignment_unknown = true;
+
+ /* Check for data refs with unsupportable alignment that
+ can be peeled. */
+ if (!supportable_dr_alignment)
+ {
+ one_dr_unsupportable = true;
+ unsupportable_dr = dr;
+ }
+
if (!first_store && DR_IS_WRITE (dr))
first_store = dr;
}
}
else
***************
*** 1732,1738 ****
vect_get_peeling_costs_all_drs (dr0,
&load_inside_cost,
&load_outside_cost,
! &dummy, vf / 2, vf);
dummy.release ();
if (first_store)
--- 1746,1752 ----
vect_get_peeling_costs_all_drs (dr0,
&load_inside_cost,
&load_outside_cost,
! &dummy, vf / 2, true);
dummy.release ();
if (first_store)
***************
*** 1741,1747 ****
vect_get_peeling_costs_all_drs (first_store,
&store_inside_cost,
&store_outside_cost,
! &dummy, vf / 2, vf);
dummy.release ();
}
else
--- 1755,1761 ----
vect_get_peeling_costs_all_drs (first_store,
&store_inside_cost,
&store_outside_cost,
! &dummy, vf / 2, true);
dummy.release ();
}
else
***************
*** 1805,1847 ****
if (peel_for_known_alignment.peel_info.dr != NULL
&& peel_for_unknown_alignment.inside_cost
>= peel_for_known_alignment.inside_cost)
! best_peel = peel_for_known_alignment;
! /* Calculate the penalty for no peeling, i.e. leaving everything
! unaligned.
! TODO: use something like an adapted vect_get_peeling_costs_all_drs. */
! unsigned nopeel_inside_cost = 0;
! unsigned nopeel_outside_cost = 0;
! stmt_vector_for_cost dummy;
! dummy.create (2);
! FOR_EACH_VEC_ELT (datarefs, i, dr)
! vect_get_data_access_cost (dr, &nopeel_inside_cost,
! &nopeel_outside_cost, &dummy);
! dummy.release ();
!
! /* Add epilogue costs. As we do not peel for alignment here, no prologue
! costs will be recorded. */
! stmt_vector_for_cost prologue_cost_vec, epilogue_cost_vec;
! prologue_cost_vec.create (2);
! epilogue_cost_vec.create (2);
! int dummy2;
! nopeel_outside_cost += vect_get_known_peeling_cost
! (loop_vinfo, 0, &dummy2,
! &LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo),
! &prologue_cost_vec, &epilogue_cost_vec);
! prologue_cost_vec.release ();
! epilogue_cost_vec.release ();
! npeel = best_peel.peel_info.npeel;
! dr0 = best_peel.peel_info.dr;
! /* If no peeling is not more expensive than the best peeling we
! have so far, don't perform any peeling. */
! if (nopeel_inside_cost <= best_peel.inside_cost)
! do_peeling = false;
if (do_peeling)
{
--- 1819,1877 ----
if (peel_for_known_alignment.peel_info.dr != NULL
&& peel_for_unknown_alignment.inside_cost
>= peel_for_known_alignment.inside_cost)
! {
! best_peel = peel_for_known_alignment;
! /* If the best peeling for known alignment has NPEEL == 0, perform no
! peeling at all except if there is an unsupportable dr that we can
! align. */
! if (best_peel.peel_info.npeel == 0 && !one_dr_unsupportable)
! do_peeling = false;
! }
! /* If there is an unsupportable data ref, prefer this over all choices so far
! since we'd have to discard a chosen peeling except when it accidentally
! aligned the unsupportable data ref. */
! if (one_dr_unsupportable)
! dr0 = unsupportable_dr;
! else if (do_peeling)
! {
! /* Calculate the penalty for no peeling, i.e. leaving everything
! unaligned.
! TODO: Adapt vect_get_peeling_costs_all_drs and use here. */
! unsigned nopeel_inside_cost = 0;
! unsigned nopeel_outside_cost = 0;
! stmt_vector_for_cost dummy;
! dummy.create (2);
! FOR_EACH_VEC_ELT (datarefs, i, dr)
! vect_get_data_access_cost (dr, &nopeel_inside_cost,
! &nopeel_outside_cost, &dummy);
! dummy.release ();
! /* Add epilogue costs. As we do not peel for alignment here, no prologue
! costs will be recorded. */
! stmt_vector_for_cost prologue_cost_vec, epilogue_cost_vec;
! prologue_cost_vec.create (2);
! epilogue_cost_vec.create (2);
!
! int dummy2;
! nopeel_outside_cost += vect_get_known_peeling_cost
! (loop_vinfo, 0, &dummy2,
! &LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo),
! &prologue_cost_vec, &epilogue_cost_vec);
! prologue_cost_vec.release ();
! epilogue_cost_vec.release ();
! npeel = best_peel.peel_info.npeel;
! dr0 = best_peel.peel_info.dr;
!
! /* If no peeling is not more expensive than the best peeling we
! have so far, don't perform any peeling. */
! if (nopeel_inside_cost <= best_peel.inside_cost)
! do_peeling = false;
! }
if (do_peeling)
{
***************
*** 2019,2026 ****
break;
}
! enum dr_alignment_support supportable_dr_alignment =
! vect_supportable_dr_alignment (dr, false);
if (!supportable_dr_alignment)
{
--- 2049,2055 ----
break;
}
! supportable_dr_alignment = vect_supportable_dr_alignment (dr, false);
if (!supportable_dr_alignment)
{