> 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 <rd...@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_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) {