Example #1
0
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;
}
Example #2
0
/**
 * @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;
}
Example #3
0
/**
 * 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;
}