コード例 #1
0
ファイル: util.c プロジェクト: tajkhan/clay
/**
 * clay_util_scop_export_body function:
 * Convert each extbody to a body structure
 * \param[in] scop
 */
void clay_util_scop_export_body(osl_scop_p scop) {
  if (scop == NULL)
    return;

  osl_statement_p stmt = scop->statement;
  osl_extbody_p ebody = NULL;
  osl_body_p body = NULL;
  osl_generic_p gen = NULL;

  while (stmt) {
    ebody = osl_generic_lookup(stmt->extension, OSL_URI_EXTBODY);
    if (ebody!=NULL) {

      body = osl_generic_lookup(stmt->extension, OSL_URI_BODY);
      if (body) {
        osl_generic_remove(&stmt->extension, OSL_URI_BODY);
      }
      body = osl_body_clone(ebody->body);
      gen = osl_generic_shell(body, osl_body_interface());
      osl_generic_add(&stmt->extension, gen);
      osl_generic_remove(&stmt->extension, OSL_URI_EXTBODY);
      ebody=NULL;
      body=NULL;
    }
    stmt = stmt->next;
  }
}
コード例 #2
0
ファイル: util.c プロジェクト: tajkhan/clay
/**
 * clay_util_statement_find_iterator function:
 * Return the index if iter is found in the original iterators list.
 * \param[in] scop
 * \param[in] iter       name of the original iterator we want to search
 * \return
 */
int clay_util_statement_find_iterator(osl_statement_p statement, char *iter) {
  osl_body_p body;
  osl_extbody_p extbody = NULL;
  
  extbody = osl_generic_lookup(statement->extension, OSL_URI_EXTBODY);
  if (extbody)
    body = extbody->body;
  else
    body = osl_generic_lookup(statement->extension, OSL_URI_BODY);

  char **ptr = body->iterators->string;
  int i = 0;
  
  while (*ptr != NULL) {
    if (strcmp(*ptr, iter) == 0)
      return i;
    ptr++;
    i++;
  }
  
  return -1;
}
コード例 #3
0
ファイル: scop.c プロジェクト: imenf/clan
/**
 * clan_scop_generate_scatnames function:
 * this function generates a scatnames extension for the scop passed as
 * an argument. Since Clan use a "2d+1" scattering strategy, the
 * scattering dimension names are generated by reusing the original
 * iterator names of the deepest statement and by inserting between those
 * names some beta vector elements (the Xth beta element is called bX).
 * \param[in,out] scop The scop to add a scatnames extension to.
 */
void clan_scop_generate_scatnames(osl_scop_p scop) {
  osl_statement_p current, deepest;
  osl_scatnames_p scatnames;
  osl_strings_p iterators = NULL;
  osl_strings_p names = NULL;
  osl_generic_p extension;
  osl_body_p body = NULL;
  char buffer[CLAN_MAX_STRING];
  int max_depth = -1;
  int i;

  // Find the deepest statement to reuse its original iterators.
  current = scop->statement;
  while (current != NULL) {
    if (current->domain->nb_output_dims > max_depth) {
      max_depth = current->domain->nb_output_dims;
      deepest = current;
      body = (osl_body_p)osl_generic_lookup(deepest->extension, OSL_URI_BODY);
      if (body)
        iterators = body->iterators;
    }
    current = current->next;
  }

  // It there are no scattering dimension, do nothing.
  if (max_depth <= 0)
    return;

  // Create the NULL-terminated list of scattering dimension names.
  names = osl_strings_malloc();
  for (i = 0; i < max_depth; i++) {
    sprintf(buffer, "b%d", i);
    osl_strings_add(names, buffer);
    osl_strings_add(names, iterators->string[i]);
  }
  sprintf(buffer, "b%d", max_depth);
  osl_strings_add(names, buffer);

  // Build the scatnames extension.
  scatnames = osl_scatnames_malloc();
  scatnames->names = names;

  // Build the generic extension and insert it to the extension list.
  extension = osl_generic_malloc();
  extension->interface = osl_scatnames_interface();
  extension->data = scatnames;
  osl_generic_add(&scop->extension, extension);
}
コード例 #4
0
ファイル: scop.c プロジェクト: imenf/clan
/**
 * clan_scop_update_coordinates function:
 * this function replaces the values in the coordinates extension of
 * each SCoP of the list 'scop' by those in the 'coordinates' array.
 * The rows of the coordinates array have the following meaning:
 * 0: line start, 1: line end, 2: column start, 3: column end,
 * 4: boolean set to 1 for an auto-discovered scop, 0 for user-scop.
 * The ith column of the coordinates array describes the coordinates
 * of the ith SCoP.
 * \param[in,out] scop        SCoP list to update the coordinates.
 * \param[in]     coordinates Array of coordinates.
 */
void clan_scop_update_coordinates(osl_scop_p scop,
                                  int coordinates[5][CLAN_MAX_SCOPS]) {
  int i = 0;
  osl_coordinates_p old;

  while (scop != NULL) {
    if (i > CLAN_MAX_SCOPS)
      CLAN_error("too many SCoPs! Change CLAN_MAX_SCOPS and recompile Clan.");
    
    old = osl_generic_lookup(scop->extension, OSL_URI_COORDINATES);
    if (old == NULL)
      CLAN_error("coordinates extension not present");
    // When columns are at 0, it means the scop has not been autodetected.
    // - The line starts at +1 (after the pragma scop) if no autodetection,
    // - The column stops at -1 (previous read char) if autodetection.
    old->line_start   = coordinates[0][i] + ((coordinates[2][i] == 0)? 1 : 0);
    old->line_end     = coordinates[1][i];
    old->column_start = coordinates[2][i];
    old->column_end   = coordinates[3][i] - ((coordinates[3][i] > 0)? 1 : 0);
    i++;
    scop = scop->next;
  }
}
コード例 #5
0
ファイル: scop.c プロジェクト: MaddTheSane/haiku-buildtools
/**
 * osl_scop_print function:
 * this function prints the content of an osl_scop_t structure (*scop)
 * into a file (file, possibly stdout) in the OpenScop textual format.
 * \param file The file where the information has to be printed.
 * \param scop The scop structure whose information has to be printed.
 */
void osl_scop_print(FILE * file, osl_scop_p scop) {
  int parameters_backedup = 0;
  int arrays_backedup = 0;
  osl_strings_p parameters_backup = NULL;
  osl_strings_p arrays_backup = NULL;
  osl_names_p names;
  osl_arrays_p arrays;

  if (scop == NULL) {
    fprintf(file, "# NULL scop\n");
    return;
  }
  else {
    fprintf(file, "# [File generated by the OpenScop Library %s]\n",
            OSL_RELEASE);
  }

  if (osl_scop_integrity_check(scop) == 0)
    OSL_warning("OpenScop integrity check failed. Something may go wrong.");
  
  // Generate the names for the various dimensions.
  names = osl_scop_names(scop);

  while (scop != NULL) {
    // If possible, replace parameter names with scop parameter names.
    if (osl_generic_has_URI(scop->parameters, OSL_URI_STRINGS)) {
      parameters_backedup = 1;
      parameters_backup = names->parameters;
      names->parameters = scop->parameters->data;
    }

    // If possible, replace array names with arrays extension names.
    arrays = osl_generic_lookup(scop->extension, OSL_URI_ARRAYS);
    if (arrays != NULL) {
      arrays_backedup = 1;
      arrays_backup = names->arrays;
      names->arrays = osl_arrays_to_strings(arrays);
    }

    fprintf(file, "\n"OSL_TAG_START_SCOP"\n\n");
    fprintf(file, "# =============================================== "
                  "Global\n");
    fprintf(file, "# Language\n");
    fprintf(file, "%s\n\n", scop->language);

    fprintf(file, "# Context\n");
    osl_relation_pprint(file, scop->context, names);
    fprintf(file, "\n");

    osl_util_print_provided(file,
        osl_generic_has_URI(scop->parameters, OSL_URI_STRINGS),
        "Parameters are");
    osl_generic_print(file, scop->parameters);

    fprintf(file, "\n# Number of statements\n");
    fprintf(file, "%d\n\n",osl_statement_number(scop->statement));

    osl_statement_pprint(file, scop->statement, names);

    if (scop->extension) {
      fprintf(file, "# =============================================== "
                    "Extensions\n");
      osl_generic_print(file, scop->extension);
    }
    fprintf(file, "\n"OSL_TAG_END_SCOP"\n\n");
    
    // If necessary, switch back parameter names.
    if (parameters_backedup) {
      parameters_backedup = 0;
      names->parameters = parameters_backup;
    }

    // If necessary, switch back array names.
    if (arrays_backedup) {
      arrays_backedup = 0;
      osl_strings_free(names->arrays);
      names->arrays = arrays_backup;
    }

    scop = scop->next;
  }

  osl_names_free(names);
}
コード例 #6
0
ファイル: util.c プロジェクト: tajkhan/clay
/**
 * clay_util_foreach_access function:
 * Execute func on each access which corresponds to access_name
 * \param[in,out] scop
 * \param[in] beta
 * \param[in] access_name      The id to search
 * \param[in] func             The function to execute for each access
 *                             The function takes an osl_relation_list_p in 
 *                             parameter (the elt can be modified) and must 
 *                             return a define error or CLAY_SUCCESS
 * \param[in] args             args of `func'
 * \param[in] regenerate_body  If 1: after each call to func, 
 *                             clay_util_body_regenerate_access is also called
 * \return                     Return a define error or CLAY_SUCCESS
 */
int clay_util_foreach_access(osl_scop_p scop,
                             clay_array_p beta,
                             unsigned int access_name,
                             int (*func)(osl_relation_list_p, void*),
                             void *args,
                             int regenerate_body) {

  osl_statement_p stmt = scop->statement;
  osl_relation_list_p access;
  osl_relation_p a;
  osl_extbody_p ebody = NULL;
  osl_body_p body = NULL;
  osl_generic_p gen= NULL;
  int count_access;
  int found = 0;
  int ret;

  // TODO : global vars ?
  osl_arrays_p arrays;
  osl_scatnames_p scatnames;
  osl_strings_p params;
  arrays = osl_generic_lookup(scop->extension, OSL_URI_ARRAYS);
  scatnames = osl_generic_lookup(scop->extension, OSL_URI_SCATNAMES);
  params = osl_generic_lookup(scop->parameters, OSL_URI_STRINGS);

  if (!arrays || !scatnames || !params)
    CLAY_warning("no arrays or scatnames extension");

  stmt = clay_beta_find(scop->statement, beta);
  if (!stmt)
    return CLAY_ERROR_BETA_NOT_FOUND;

  // for each access in the beta, we search the access_name
  while (stmt != NULL) {
    if (clay_beta_check(stmt, beta)) {
      access = stmt->access;
      count_access = 0;

      while (access) {
        a = access->elt;

        if (osl_relation_get_array_id(a) == access_name) {
          found = 1;

          ebody = osl_generic_lookup(stmt->extension, OSL_URI_EXTBODY);
          if (ebody==NULL) {
            CLAY_error("extbody uri not found on this statement");
            fprintf(stderr, "%s\n",
              ebody->body->expression->string[0]);
          }

          // call the function
          ret = (*func)(access, args);
          if (ret != CLAY_SUCCESS) {
            fprintf(stderr, "%s\n",
              ebody->body->expression->string[0]);
            return ret;
          }

          // re-generate the body
          if (regenerate_body) {
            clay_util_body_regenerate_access(
                ebody,
                access->elt,
                count_access,
                arrays,
                scatnames,
                params);


            //synchronize extbody with body
            body = osl_generic_lookup(stmt->extension, OSL_URI_BODY);
            if (body) {
              osl_generic_remove(&stmt->extension, OSL_URI_BODY);
              body = osl_body_clone(ebody->body);
              gen = osl_generic_shell(body, osl_body_interface());
              osl_generic_add(&stmt->extension, gen);
            }
          }
        }

        ebody = NULL;
        body  = NULL;
        access = access->next;
        count_access++;
      }
    }
    stmt = stmt->next;
  }

  if (!found)
   fprintf(stderr,"[Clay] Warning: access number %d not found\n", access_name);

  return CLAY_SUCCESS;
}
コード例 #7
0
ファイル: scop.c プロジェクト: imenf/clan
/**
 * clan_scop_insert_pragmas function:
 * inserts "#pragma scop" and "#pragma endscop" in a source file
 * around the SCoPs related in the input SCoP list that have no
 * surrounding pragmas in the file.
 * \param[in] scop     The list of SCoPS.
 * \param[in] filename Name of the file where to insert pragmas.
 * \param[in] test     0 to insert, 1 to leave the result in the
 *                     CLAN_AUTOPRAGMA_FILE temporary file.
 */
void clan_scop_insert_pragmas(osl_scop_p scop, char* filename, int test) {
  int i, j, n = 0;
  int infos[5][CLAN_MAX_SCOPS];
  int tmp[5];
  osl_coordinates_p coordinates;
  FILE* input, *output;
  size_t size;
  char buffer[BUFSIZ];
  
  // Get coordinate information from the list of SCoPS.
  while (scop != NULL) {
    coordinates = osl_generic_lookup(scop->extension, OSL_URI_COORDINATES);
    infos[0][n] = coordinates->line_start;
    infos[1][n] = coordinates->line_end;
    infos[2][n] = coordinates->column_start;
    infos[3][n] = coordinates->column_end + 1;
    infos[4][n] = clan_scop_no_pragma(filename, coordinates->line_start);
    n++;
    scop = scop->next;
  }

  // Dirty and inefficient bubble sort to ensure the SCoP ordering is correct
  // (this is ensured in Clan, but not if it is called from outside...).
  for (i = n - 2; i >= 0; i--) {
    for (j = 0; j <= i; j++) {
      if (infos[0][j] > infos[0][j+1]) {
        tmp[0]=infos[0][j]; infos[0][j]=infos[0][j+1]; infos[0][j+1]=tmp[0];
        tmp[1]=infos[1][j]; infos[1][j]=infos[1][j+1]; infos[1][j+1]=tmp[1];
        tmp[2]=infos[2][j]; infos[2][j]=infos[2][j+1]; infos[2][j+1]=tmp[2];
        tmp[3]=infos[3][j]; infos[3][j]=infos[3][j+1]; infos[3][j+1]=tmp[3];
        tmp[4]=infos[4][j]; infos[4][j]=infos[4][j+1]; infos[4][j+1]=tmp[4];
      }
    }
  }

  // Quick check that there is no scop interleaving.
  for (i = 0; i < n - 1; i++)
    if (infos[1][i] > infos[0][i+1])
      CLAN_error("SCoP interleaving");

  // Generate the temporary file with the pragma inserted.
  if (!(input = fopen(filename, "r")))
    CLAN_error("unable to read the input file");
  clan_scop_print_autopragma(input, n, infos);
  fclose(input);

  // Replace the original file, or keep the temporary file.
  if (!test) {
    if (!(input = fopen(CLAN_AUTOPRAGMA_FILE, "rb")))
      CLAN_error("unable to read the temporary file");

    if (!(output = fopen(filename, "wb")))
      CLAN_error("unable to write the output file");

    while ((size = fread(buffer, 1, BUFSIZ, input))) {
        fwrite(buffer, 1, size, output);
    }

    fclose(input);
    fclose(output);
  }
}
コード例 #8
0
ファイル: vectorization.c プロジェクト: Ced/substrate
/**
 * @brief Allocate and construct the vectorization profile by analyzing the
 * osl_statement.
 *
 * @param[in] scop The scop of the analyzed osl_statement.
 * @param[in] statement The analyzed osl_statement.
 *
 * @return A constructed vectorization profile.
 */
struct substrate_vectorization_profile substrate_vectorization_profile_constructor(
       struct osl_scop * scop,
       struct osl_statement * statement)
{
    struct substrate_vectorization_profile res = {NULL,0};
    
    unsigned int i = 0;
    
    struct osl_relation_list *relation_list_cursor = NULL;
    struct osl_relation *relation_cursor = NULL;
    unsigned col = 0;
    unsigned line = 0;
    osl_int_t val;
    unsigned common_iterators_vectorized_dim[statement->domain->nb_output_dims];
    int precision = statement->domain->precision;

    struct candl_options *candl_options = NULL;
    struct osl_dependence *candl_dep = NULL, *candl_dep_cursor = NULL;
    struct osl_scop *candl_scop = NULL;


    //Preparing and allocating the vectorization structure.
    res.size = statement->domain->nb_output_dims;
    res.vectorizable_loops = (bool*) malloc(res.size * sizeof(bool));
    memset(res.vectorizable_loops,false,res.size);

    //For every possible iterator, we select only those that are used in the
    //vectorized output dimension (the first if column major, last if row major).
    //
    //If an access relation of the statement doesn't used the i^th iterator,
    //then this iterator can be used to vectorize the statement.
    for(i=0 ; i<res.size ; i++)
    {
        common_iterators_vectorized_dim[i] = true;
        relation_list_cursor = statement->access;
        while((relation_list_cursor != NULL) && (common_iterators_vectorized_dim[i]))
        {
            relation_cursor = relation_list_cursor->elt;
            while((relation_cursor != NULL) && (common_iterators_vectorized_dim[i]))
            {
                col = g_substrate_options.row_major ? relation_cursor->nb_output_dims-1 : 1;
                line = candl_util_relation_get_line(relation_cursor, col);

                val = relation_cursor->m[line][1 + relation_cursor->nb_output_dims + i];
                common_iterators_vectorized_dim[i] = !osl_int_zero(precision, val);
                
                relation_cursor = relation_cursor->next;
            }
            relation_list_cursor = relation_list_cursor->next;
        }
    }

    //Creating a dummy scop with only the current analyzed statement for candl.
    //Also reset the beta depth of the statement, because it's supposed to be
    //alone now.
    candl_scop = substrate_osl_scop_nclone_except_statement(scop, 1);
    candl_scop->statement = osl_statement_nclone(statement,1);
    substrate_reset_beta_depth(candl_scop->statement);

    //Initiating candl, then using it to generate the dependences,
    //and finally extracting them to use later.
    candl_options = candl_options_malloc();
    candl_scop_usr_init(candl_scop);
    candl_dependence_add_extension(candl_scop, candl_options);
    candl_dep = osl_generic_lookup(candl_scop->extension, OSL_URI_DEPENDENCE);

    for(i=0 ; i<res.size; i++)
    {
        if( common_iterators_vectorized_dim[i] == false ) continue;

        res.vectorizable_loops[i] = true;
        candl_dep_cursor = candl_dep;
        while( (candl_dep_cursor != NULL) && (res.vectorizable_loops[i]) )
        {
            if(candl_dependence_is_loop_carried(candl_dep_cursor, i))
            {
                switch(candl_dep_cursor->type)
                {
                    //If the dependence is RaR (which should not be encountered because
                    //we only analyze the self-dependence of the statement) or WaR,
                    //then we don't care : these types doesn't prevent vectorization.
                    case OSL_DEPENDENCE_RAR :
                    case OSL_DEPENDENCE_WAR :
                        break;
                    
                    //If a dependence is RaW or WaW, the i^th cannot be vectorized
                    //because these type of dependence prevent it.
                    case OSL_DEPENDENCE_RAW :
                    case OSL_DEPENDENCE_WAW :
                        res.vectorizable_loops[i] = false;
                        break;
                    default :
                        OSL_error("In function substrate_vectorization_profile_constructor :"
                                " an osl_dependence without a type has been encountered");
                        break;
                }
            }
            candl_dep_cursor = candl_dep_cursor->next;
        }
    }

    candl_options_free(candl_options);
    candl_scop_usr_cleanup(candl_scop);
    osl_scop_free(candl_scop);

    return res;
}