/* Compute the union of all the constraints in domain. */ isl_union_set *nfm_union_domain_union_domains(isl_ctx *ctx, struct nfm_union_domain *union_domain) { isl_union_set *union_set; assert(union_domain); assert(union_domain->domain); IF_DEBUG(fprintf(stdout, " Starting the union function.\n")); nfm_union_domain *head = union_domain; union_set = isl_union_set_empty(nfm_domain_get_space(ctx, union_domain->domain)); IF_DEBUG(fprintf(stdout, " Initial value for the union set is:")); IF_DEBUG(isl_union_set_dump(union_set)); while (head != NULL) { nfm_domain *domain = head->domain; isl_bset_list *bset_list = nfm_domain_intersect_constraints(ctx, domain); IF_DEBUG(fprintf(stdout, " The constraints at this iteration," " represented as a set, are:")); IF_DEBUG(isl_bset_list_dump(bset_list)); while (bset_list != NULL) { union_set = isl_union_set_union(union_set, isl_union_set_from_set( isl_set_from_basic_set( bset_list->bset))); bset_list = bset_list->next; } IF_DEBUG(fprintf(stdout, " Results of the union:")); IF_DEBUG(isl_union_set_dump(union_set)); head = head->next; } IF_DEBUG(fprintf(stdout, " End of the union function.\n")); return union_set; }
/** * Converts a SCoP as extracted by PolyOpt's auto-scop detection * into ISL representation. * * bugs/limitations: * (a) not robust to union of iteration domains in scoplib * (b) code is leaking, need proper copy constructor that duplicates all * ISL structures. */ int PolyOptISLRepresentation::convertScoplibToISL (scoplib_scop_p scop) { int i; isl_union_map* all_reads = NULL; isl_union_map* all_writes = NULL; isl_union_map* all_scheds = NULL; isl_ctx* ctxt = isl_ctx_alloc(); // 1. Prepare the arrays of unique names for statements and arrays. char buffer[32]; int nb_statements; scoplib_statement_p s; for (nb_statements = 0, s = scop->statement; s; s = s->next, nb_statements++) ; char* stmt_names[nb_statements]; for (i = 0; i < nb_statements; ++i) { sprintf (buffer, "S_%d", i); stmt_names[i] = strdup (buffer); } char* array_names[scop->nb_arrays]; for (i = 0; i < scop->nb_arrays; ++i) array_names[i] = strdup (((SgVariableSymbol*)(scop->arrays[i]))->get_name().str()); isl_union_map* umap; int stmt_id; for (s = scop->statement, stmt_id = 0; s; s = s->next, ++stmt_id) { isl_union_map* all_reads_stmt = NULL; isl_union_map* all_writes_stmt = NULL; isl_space* sp = NULL; for (i = 0; i < scop->nb_arrays; ++i) { sp = build_isl_space (scop, s, i+1, ctxt); // 1. Handle access matrices. scoplib_matrix_p m; int k; for (k = 0, m = s->read, umap = all_reads_stmt; k < 2; k++, m = s->write, umap = all_writes_stmt) { isl_map* acc_map = NULL; int row_pos = 0; do { acc_map = build_access_function (scop, s, m, sp, ctxt, &row_pos, i+1); if (acc_map) { acc_map = isl_map_set_tuple_name (acc_map, isl_dim_in, stmt_names[stmt_id]); acc_map = isl_map_set_tuple_name (acc_map, isl_dim_out, array_names[i]); if (umap == NULL) umap = isl_union_map_from_map (isl_map_copy (acc_map)); else umap = isl_union_map_union (umap, isl_union_map_from_map (isl_map_copy (acc_map))); isl_map_free (acc_map); } } while (acc_map != NULL); if (k == 0) all_reads_stmt = umap; else all_writes_stmt = umap; } } // Store the union of access functions of statement i. stmt_accfunc_read.push_back (all_reads_stmt); stmt_accfunc_write.push_back (all_writes_stmt); // 2. Handle iteration domains. isl_set* dom = build_iteration_domain (scop, s, sp, ctxt); dom = isl_set_set_tuple_name (dom, stmt_names[stmt_id]); if (all_reads_stmt != NULL) all_reads_stmt = isl_union_map_intersect_domain (isl_union_map_copy (all_reads_stmt), isl_union_set_from_set (isl_set_copy (dom))); if (all_writes_stmt != NULL) all_writes_stmt = isl_union_map_intersect_domain (all_writes_stmt, isl_union_set_from_set (isl_set_copy (dom))); // Store the iteration domain of statement i. stmt_iterdom.push_back (dom); // Store the union of access functions of statement i after intersection by domain. stmt_read_domain.push_back (all_reads_stmt); stmt_write_domain.push_back (all_writes_stmt); // Unionize the result. if (all_reads == NULL) all_reads = isl_union_map_copy (all_reads_stmt); else all_reads = isl_union_map_union (all_reads, isl_union_map_copy (all_reads_stmt)); if (all_writes == NULL) all_writes = isl_union_map_copy (all_writes_stmt); else all_writes = isl_union_map_union (all_writes, isl_union_map_copy (all_writes_stmt)); // isl_union_map_free (all_reads_stmt); // isl_union_map_free (all_writes_stmt); // 3. Handle schedules. isl_map* sched = build_schedule (scop, s, sp, ctxt); sched = isl_map_set_tuple_name (sched, isl_dim_in, stmt_names[stmt_id]); if (all_scheds == NULL) all_scheds = isl_union_map_from_map (isl_map_copy (sched)); else all_scheds = isl_union_map_union (all_scheds, isl_union_map_from_map (isl_map_copy (sched))); // Store the schedule of statement i. stmt_schedule.push_back (sched); // 4. Finalize info about the statement. stmt_body.push_back (((SgNode*)(s->body))->unparseToCompleteString()); stmt_body_ir.push_back ((SgNode*)(s->body)); } // // Debug. // isl_printer* pr = isl_printer_to_file (ctxt, stdout); // std::cout << "UNION MAP READS" << std::endl; // isl_printer_print_union_map(pr, all_reads); // printf ("\n"); // std::cout << "UNION MAP WRITES" << std::endl; // isl_printer_print_union_map(pr, all_writes); // printf ("\n"); // std::cout << "UNION MAP SCHEDULES" << std::endl; // isl_printer_print_union_map(pr, all_scheds); // printf ("\n"); for (std::vector<std::string>::iterator i = stmt_body.begin(); i != stmt_body.end(); ++i) std::cout << "stmt body: " << *i << std::endl; // Finalize SCoP representation. scop_nb_arrays = scop->nb_arrays; scop_nb_statements = stmt_schedule.size(); scop_reads = all_reads; scop_writes = all_writes; scop_scheds = all_scheds; return EXIT_SUCCESS; }