mirror of git://gcc.gnu.org/git/gcc.git
Vector peeling cost model 6/6
gcc/ChangeLog: 2017-05-24 Robin Dapp <rdapp@linux.vnet.ibm.com> * 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_misalignment parameter. (vect_enhance_data_refs_alignment): Fix unsupportable data ref treatment. From-SVN: r248680
This commit is contained in:
parent
4bfb347c02
commit
4d3d23fb7d
|
|
@ -1,3 +1,12 @@
|
||||||
|
2017-05-24 Robin Dapp <rdapp@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
* 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_misalignment parameter.
|
||||||
|
(vect_enhance_data_refs_alignment):
|
||||||
|
Fix unsupportable data ref treatment.
|
||||||
|
|
||||||
2017-05-30 Robin Dapp <rdapp@linux.vnet.ibm.com>
|
2017-05-30 Robin Dapp <rdapp@linux.vnet.ibm.com>
|
||||||
|
|
||||||
* tree-vect-data-refs.c (vect_get_data_access_cost):
|
* tree-vect-data-refs.c (vect_get_data_access_cost):
|
||||||
|
|
|
||||||
|
|
@ -1239,14 +1239,16 @@ vect_peeling_hash_get_most_frequent (_vect_peel_info **slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the costs of peeling NPEEL iterations checking data access costs
|
/* Get the costs of peeling NPEEL iterations checking data access costs
|
||||||
for all data refs. */
|
for all data refs. If UNKNOWN_MISALIGNMENT is true, we assume DR0's
|
||||||
|
misalignment will be zero after peeling. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vect_get_peeling_costs_all_drs (struct data_reference *dr0,
|
vect_get_peeling_costs_all_drs (struct data_reference *dr0,
|
||||||
unsigned int *inside_cost,
|
unsigned int *inside_cost,
|
||||||
unsigned int *outside_cost,
|
unsigned int *outside_cost,
|
||||||
stmt_vector_for_cost *body_cost_vec,
|
stmt_vector_for_cost *body_cost_vec,
|
||||||
unsigned int npeel, unsigned int vf)
|
unsigned int npeel,
|
||||||
|
bool unknown_misalignment)
|
||||||
{
|
{
|
||||||
gimple *stmt = DR_STMT (dr0);
|
gimple *stmt = DR_STMT (dr0);
|
||||||
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
|
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
|
||||||
|
|
@ -1274,7 +1276,7 @@ vect_get_peeling_costs_all_drs (struct data_reference *dr0,
|
||||||
|
|
||||||
int save_misalignment;
|
int save_misalignment;
|
||||||
save_misalignment = DR_MISALIGNMENT (dr);
|
save_misalignment = DR_MISALIGNMENT (dr);
|
||||||
if (dr == dr0 && npeel == vf / 2)
|
if (unknown_misalignment && dr == dr0)
|
||||||
SET_DR_MISALIGNMENT (dr, 0);
|
SET_DR_MISALIGNMENT (dr, 0);
|
||||||
else
|
else
|
||||||
vect_update_misalignment_for_peel (dr, dr0, npeel);
|
vect_update_misalignment_for_peel (dr, dr0, npeel);
|
||||||
|
|
@ -1305,7 +1307,7 @@ vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot,
|
||||||
epilogue_cost_vec.create (2);
|
epilogue_cost_vec.create (2);
|
||||||
|
|
||||||
vect_get_peeling_costs_all_drs (elem->dr, &inside_cost, &outside_cost,
|
vect_get_peeling_costs_all_drs (elem->dr, &inside_cost, &outside_cost,
|
||||||
&body_cost_vec, elem->npeel, 0);
|
&body_cost_vec, elem->npeel, false);
|
||||||
|
|
||||||
outside_cost += vect_get_known_peeling_cost
|
outside_cost += vect_get_known_peeling_cost
|
||||||
(loop_vinfo, elem->npeel, &dummy,
|
(loop_vinfo, elem->npeel, &dummy,
|
||||||
|
|
@ -1517,6 +1519,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
{
|
{
|
||||||
vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
|
vec<data_reference_p> datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
|
||||||
struct loop *loop = LOOP_VINFO_LOOP (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 *dr0 = NULL, *first_store = NULL;
|
||||||
struct data_reference *dr;
|
struct data_reference *dr;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
@ -1528,6 +1531,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
unsigned int npeel = 0;
|
unsigned int npeel = 0;
|
||||||
bool one_misalignment_known = false;
|
bool one_misalignment_known = false;
|
||||||
bool one_misalignment_unknown = 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 int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
|
||||||
unsigned possible_npeel_number = 1;
|
unsigned possible_npeel_number = 1;
|
||||||
tree vectype;
|
tree vectype;
|
||||||
|
|
@ -1599,6 +1604,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
&& !STMT_VINFO_GROUPED_ACCESS (stmt_info))
|
&& !STMT_VINFO_GROUPED_ACCESS (stmt_info))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
|
||||||
do_peeling = vector_alignment_reachable_p (dr);
|
do_peeling = vector_alignment_reachable_p (dr);
|
||||||
if (do_peeling)
|
if (do_peeling)
|
||||||
{
|
{
|
||||||
|
|
@ -1637,8 +1643,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
else
|
else
|
||||||
possible_npeel_number = vf / nelements;
|
possible_npeel_number = vf / nelements;
|
||||||
|
|
||||||
/* NPEEL_TMP is 0 when there is no misalignment, increment
|
/* NPEEL_TMP is 0 when there is no misalignment, but also
|
||||||
the peeling amount by one in order to ... */
|
allow peeling NELEMENTS. */
|
||||||
if (DR_MISALIGNMENT (dr) == 0)
|
if (DR_MISALIGNMENT (dr) == 0)
|
||||||
possible_npeel_number++;
|
possible_npeel_number++;
|
||||||
}
|
}
|
||||||
|
|
@ -1684,10 +1690,18 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
dr0 = dr;
|
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))
|
if (!first_store && DR_IS_WRITE (dr))
|
||||||
first_store = dr;
|
first_store = dr;
|
||||||
|
|
||||||
one_misalignment_unknown = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1732,7 +1746,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
vect_get_peeling_costs_all_drs (dr0,
|
vect_get_peeling_costs_all_drs (dr0,
|
||||||
&load_inside_cost,
|
&load_inside_cost,
|
||||||
&load_outside_cost,
|
&load_outside_cost,
|
||||||
&dummy, vf / 2, vf);
|
&dummy, vf / 2, true);
|
||||||
dummy.release ();
|
dummy.release ();
|
||||||
|
|
||||||
if (first_store)
|
if (first_store)
|
||||||
|
|
@ -1741,7 +1755,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
vect_get_peeling_costs_all_drs (first_store,
|
vect_get_peeling_costs_all_drs (first_store,
|
||||||
&store_inside_cost,
|
&store_inside_cost,
|
||||||
&store_outside_cost,
|
&store_outside_cost,
|
||||||
&dummy, vf / 2, vf);
|
&dummy, vf / 2, true);
|
||||||
dummy.release ();
|
dummy.release ();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1805,11 +1819,26 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
if (peel_for_known_alignment.peel_info.dr != NULL
|
if (peel_for_known_alignment.peel_info.dr != NULL
|
||||||
&& peel_for_unknown_alignment.inside_cost
|
&& peel_for_unknown_alignment.inside_cost
|
||||||
>= peel_for_known_alignment.inside_cost)
|
>= peel_for_known_alignment.inside_cost)
|
||||||
|
{
|
||||||
best_peel = peel_for_known_alignment;
|
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
|
/* Calculate the penalty for no peeling, i.e. leaving everything
|
||||||
unaligned.
|
unaligned.
|
||||||
TODO: use something like an adapted vect_get_peeling_costs_all_drs. */
|
TODO: Adapt vect_get_peeling_costs_all_drs and use here. */
|
||||||
unsigned nopeel_inside_cost = 0;
|
unsigned nopeel_inside_cost = 0;
|
||||||
unsigned nopeel_outside_cost = 0;
|
unsigned nopeel_outside_cost = 0;
|
||||||
|
|
||||||
|
|
@ -1842,6 +1871,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
have so far, don't perform any peeling. */
|
have so far, don't perform any peeling. */
|
||||||
if (nopeel_inside_cost <= best_peel.inside_cost)
|
if (nopeel_inside_cost <= best_peel.inside_cost)
|
||||||
do_peeling = false;
|
do_peeling = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (do_peeling)
|
if (do_peeling)
|
||||||
{
|
{
|
||||||
|
|
@ -2019,8 +2049,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum dr_alignment_support supportable_dr_alignment =
|
supportable_dr_alignment = vect_supportable_dr_alignment (dr, false);
|
||||||
vect_supportable_dr_alignment (dr, false);
|
|
||||||
|
|
||||||
if (!supportable_dr_alignment)
|
if (!supportable_dr_alignment)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue