static int row_preceeds(osl_relation_p relation, int row_i, int row_j) { int k; for (k = 0; k < relation->nb_columns; k++) { if (osl_int_gt(relation->precision, relation->m[row_i][k], relation->m[row_j][k])) { return 0; } else if (!osl_int_eq(relation->precision, relation->m[row_i][k], relation->m[row_j][k])) { return 1; } } return 1; }
/** * @brief Rate the reuse between two reuse profile. * * How the rating works : * - This function try to see if the two reuse profiles have some access relations of the * same array/variable (by comparing the array_id of their array_profiles). * - If we find some, that means that we could potentially aggregate the array profiles, * and that some equivalence classes could be aggregated, * so we call \a substrate_rate_array_profiles to rate them. * - If not, we count the total number of all the equivalence classes of of the array profiles. * * In the end, the rating will be equal to : number of references in the aggregated * equivalence classes / total number of reference of the reuse profile. * * @param[in] rp1 The first reuse profile used for the rating. * @param[in] rp2 The second reuse profile used for the rating. * * @return A rating between 0 and 1 (0 meaning that there isn't any reuse, and 1 meaning * a perfect reuse). */ double substrate_rate_reuse_profiles( struct substrate_reuse_profile rp1, struct substrate_reuse_profile rp2) { struct reuse_rate rating = {0,0}, tmp = {0,0}; unsigned int i1 = 0, i2 = 0; //We look for match in array id. //If we find one, we rate the array profile. //If not, we know that 0 references in equivalence classes can be aggregated, //and we need to count the number of references in the equivalence classes. // //After these loops, we know about all the array match between rp1 and rp2, and all the //"no-match" of rp1 in rp2. But we don't know about the "no-match" of rp2 in rp1, so //we need another loop nest to count references of rp2 for array that don't have a match //in rp1. for(i1=0; i1<rp1.size ; i1++) { for(i2=0 ; i2<rp2.size ; i2++) { if(osl_int_eq( rp1.array_profiles[i1].array_id_precision, rp1.array_profiles[i1].array_id, rp2.array_profiles[i2].array_id)) { tmp = substrate_rate_array_profiles( rp1.array_profiles[i1], rp2.array_profiles[i2]); break; } } if(i2 >= rp2.size) { tmp.nb_same_class_refs = 0; tmp.nb_total_refs = substrate_array_profile_count_access(rp1.array_profiles[i1]); } rating.nb_same_class_refs += tmp.nb_same_class_refs; rating.nb_total_refs += tmp.nb_total_refs; } for(i2=0 ; i2<rp2.size ; i2++) { for(i1=0; i1<rp1.size ; i1++) { if(osl_int_eq( rp1.array_profiles[i1].array_id_precision, rp1.array_profiles[i1].array_id, rp2.array_profiles[i2].array_id)) { break; } } if(i1 >= rp1.size) { rating.nb_total_refs += substrate_array_profile_count_access(rp2.array_profiles[i2]); } } return (double)rating.nb_same_class_refs / (double)rating.nb_total_refs; }
/** * candl_util_statement_commute function: * This function returns 1 if the two statements given as parameter commute, * 0 otherwise. It uses the statement type information to answer the question. * - 09/12/2005: first version. */ int candl_util_statement_commute(osl_statement_p statement1, osl_statement_p statement2) { candl_statement_usr_p usr1, usr2; int type1, type2; int precision = statement1->domain->precision; int row_1, row_2; usr1 = statement1->usr; usr2 = statement2->usr; type1 = usr1->type; type2 = usr2->type; /* In the case of self-dependence, a statement commutes with hitself if * it is a reduction. */ if ((statement1 == statement2) && ((type1 == OSL_DEPENDENCE_P_REDUCTION) || (type1 == OSL_DEPENDENCE_M_REDUCTION) || (type1 == OSL_DEPENDENCE_T_REDUCTION))) return 1; /* Two statement commute when they are a reduction of the same type (or if * their left and right members are the same, but it's not exploited here). * The type may differ if it is either minus or plus-reduction. Furthermore, * they have to write onto the same array (and only one array). */ if ((type1 == OSL_DEPENDENCE_P_REDUCTION && type2 == OSL_DEPENDENCE_P_REDUCTION) || (type1 == OSL_DEPENDENCE_M_REDUCTION && type2 == OSL_DEPENDENCE_M_REDUCTION) || (type1 == OSL_DEPENDENCE_T_REDUCTION && type2 == OSL_DEPENDENCE_T_REDUCTION) || (type1 == OSL_DEPENDENCE_P_REDUCTION && type2 == OSL_DEPENDENCE_M_REDUCTION) || (type1 == OSL_DEPENDENCE_M_REDUCTION && type2 == OSL_DEPENDENCE_P_REDUCTION)) { /* Here we check that there is one, only one and the same array. */ if (count_nb_access(statement1, OSL_TYPE_WRITE) > 1 || count_nb_access(statement2, OSL_TYPE_WRITE) > 1) return 0; /* search the first osl_write access */ osl_relation_list_p access1 = statement1->access; osl_relation_list_p access2 = statement2->access; for (; access1 != NULL && access2 != NULL ; access1 = access1->next, access2 = access2->next) if (access1->elt->type == OSL_TYPE_WRITE) break; if (access1 == NULL || access2 == NULL || access2->elt->type != OSL_TYPE_WRITE || access2->elt->nb_output_dims != access1->elt->nb_output_dims) { osl_statement_dump(stderr, statement1); osl_statement_dump(stderr, statement2); CANDL_error("These statements haven't the same access array or access is NULL"); } /* Check if the first dim (the Arr column) is the same */ row_1 = candl_relation_get_line(access1->elt, 0); row_2 = candl_relation_get_line(access2->elt, 0); if (!osl_int_eq(precision, access1->elt->m[row_1][access1->elt->nb_columns - 1], access2->elt->m[row_2][access2->elt->nb_columns - 1])) return 0; return 1; } return 0; }