/** * @brief Aggregate two osl_generic together (cloning the necessary structures). * The parameters are not modified. If two generics are found, only one is kept (like a union). * * @param gen1 A pointer to the first osl_generic. * @param gen2 A pointer to the first osl_generic. * * @return The aggregation of two osl_generic. */ struct osl_generic * substrate_osl_generic_fusion( struct osl_generic * gen1, struct osl_generic * gen2) { struct osl_generic * res = NULL, *tmp1 = NULL, *tmp2 = NULL; struct osl_generic * new_generic = NULL; tmp1 = gen1; while(tmp1 != NULL) { tmp2 = substrate_osl_generic_lookup(gen2, tmp1->interface->URI); if(tmp2 == NULL) { osl_generic_add(&res, substrate_osl_generic_nclone(tmp1,1)); } else if(osl_generic_equal(tmp1, tmp2)) { if(strcmp(tmp1->interface->URI,"body") == 0) { new_generic = osl_generic_malloc(); new_generic->interface = osl_body_interface(); new_generic->next = NULL; new_generic->data = substrate_osl_body_fusion(tmp1->data,tmp2->data); osl_generic_add(&res, new_generic); } else { osl_generic_add(&res, substrate_osl_generic_nclone(tmp1,1)); } } else { if(strcmp(tmp1->interface->URI,"body") == 0) { new_generic = osl_generic_malloc(); new_generic->interface = osl_body_interface(); new_generic->next = NULL; new_generic->data = substrate_osl_body_fusion(tmp1->data,tmp2->data); osl_generic_add(&res, new_generic); } else { OSL_warning("Can't fusion the generic structures : don't know how."); fprintf(stderr,"URI : %s\n", tmp1->interface->URI); } } tmp1 = tmp1->next; } return res; }
/** * 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; } }
/** * 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; }