Added support for statement extensions
[converter.git] / source / old_candl_dependence.c
blob029b305451870627122fcf82f0ff2bad64de6868
1 //
2 // initially copied from Candl
3 //
4 /**------ ( ----------------------------------------------------------**
5 ** )\ CAnDL **
6 **----- / ) --------------------------------------------------------**
7 ** ( * ( dependence.c **
8 **---- \#/ --------------------------------------------------------**
9 ** .-"#'-. First version: september 18th 2003 **
10 **--- |"-.-"| -------------------------------------------------------**
11 | |
12 | |
13 ******** | | *************************************************************
14 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
15 ******************************************************************************
16 * *
17 * Copyright (C) 2003-2008 Cedric Bastoul *
18 * *
19 * This is free software; you can redistribute it and/or modify it under the *
20 * terms of the GNU Lesser General Public License as published by the Free *
21 * Software Foundation; either version 3 of the License, or (at your option) *
22 * any later version. *
23 * *
24 * This software is distributed in the hope that it will be useful, but *
25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
27 * for more details. *
28 * *
29 * You should have received a copy of the GNU Lesser General Public License *
30 * along with software; if not, write to the Free Software Foundation, Inc., *
31 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
32 * *
33 * CAnDL, the Chunky Dependence Analyzer *
34 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
35 * *
36 ******************************************************************************/
37 /**
38 * \file dependence.c
39 * \author Cedric Bastoul and Louis-Noel Pouchet
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45 //#include <candl/candl.h>
47 #include "osl/scop.h" //
48 #include "osl/macros.h" // for access types
49 #include "osl/extensions/dependence.h" //
50 #include "converter/old_candl_dependence.h"
51 #include "converter/converter.h"
53 #include <assert.h>
55 #ifdef CANDL_SUPPORTS_ISL
56 # undef Q // Thank you polylib...
57 # include <isl/int.h>
58 # include <isl/constraint.h>
59 # include <isl/ctx.h>
60 # include <isl/set.h>
61 #endif
65 /******************************************************************************
66 * Memory deallocation function *
67 ******************************************************************************/
70 /* candl_dependence_free function:
71 * This function frees the allocated memory for a CandlDependence structure.
72 * - 18/09/2003: first version.
74 void candl_dependence_free(candl_dependence_p dependence)
76 candl_dependence_p next;
78 while (dependence != NULL)
80 next = dependence->next;
81 //TODO: candl_matrix==scoplib_matrix??
82 scoplib_matrix_free(dependence->domain);
83 free(dependence);
84 dependence = next;
89 /******************************************************************************
90 * Memory Allocation functions *
91 ******************************************************************************/
94 /**
95 * candl_dependence_malloc function:
96 * This function allocates the memory space for a CandlDependence structure and
97 * sets its fields with default values. Then it returns a pointer to the
98 * allocated space.
99 * - 07/12/2005: first version.
101 candl_dependence_p candl_dependence_malloc()
103 candl_dependence_p dependence;
105 /* Memory allocation for the CandlDependence structure. */
106 dependence = (candl_dependence_p) malloc(sizeof(CandlDependence));
107 if (dependence == NULL)
108 CONVERTER_error(" Error: memory overflow");
110 /* We set the various fields with default values. */
111 dependence->depth = CANDL_UNSET;
112 dependence->type = CANDL_UNSET;
113 dependence->array_id = CANDL_UNSET;
114 dependence->label_source = CANDL_UNSET;
115 dependence->label_target = CANDL_UNSET;
116 dependence->ref_source = CANDL_UNSET;
117 dependence->ref_target = CANDL_UNSET;
118 dependence->domain = NULL;
119 dependence->next = NULL;
120 dependence->usr = NULL;
122 return dependence;
126 /******************************************************************************
127 * Processing functions *
128 ******************************************************************************/
131 * copied from:
132 * candl_program_p candl_program_convert_scop(scoplib_scop_p scop, int** indices)
133 * TODO: replace mallocs by scoplib_mallocs
136 int** convert_get_stmt_indices(scoplib_statement_p s, int nparams){
138 int i, j, k, l;
140 if(s==NULL)
141 return NULL;
143 scoplib_statement_p stmt = s;
145 int nstmt = 0;
146 for( ; stmt; stmt = stmt->next, nstmt++)
149 int** index_2d_array = (int**) malloc(nstmt * sizeof(int*));
151 int max = 0;
152 int max_loop_depth = 128;
153 int cur_index[max_loop_depth];
154 int last[max_loop_depth];
156 for (i = 0; i < max_loop_depth; ++i)
158 cur_index[i] = i;
159 last[i] = 0;
162 int idx = 0;
163 for( idx=0, stmt=s; stmt; stmt=stmt->next, ++idx){
165 int stmt_depth = stmt->domain->elt->NbColumns - 2 - nparams;
166 index_2d_array[idx] = (int*) malloc(stmt_depth * sizeof(int));
168 /* Iterator indices must be computed from the scattering matrix. */
169 scoplib_matrix_p m = stmt->schedule;
170 if (m == NULL)
171 CONVERTER_error("Error: No scheduling matrix and no loop "
172 "indices specification");
174 /* FIXME: Sort the statements in their execution order. */
175 /* It must be a 2d+1 identity scheduling matrix, and
176 statements must be sorted in their execution order. */
177 /* Check that it is a identity matrix. */
178 int error = 0;
179 if (m->NbRows != 2 * stmt_depth + 1)
180 error = 1;
181 else
182 for (l = 0; l < m->NbRows; ++l)
184 for (k = 1; k < m->NbColumns - 1; ++k)
185 switch (SCOPVAL_get_si(m->p[l][k]))
187 case 0:
188 if (l % 2 && k == (l / 2) + 1) error = 1;
189 break;
190 case 1:
191 if ((l % 2 && k != (l / 2) + 1) || (! l % 2)) error = 1;
192 break;
193 default:
194 error = 1;
195 break;
197 if (l % 2 && SCOPVAL_get_si(m->p[l][k]))
198 error = 1;
200 if (error)
201 CONVERTER_error("Error: schedule is not identity 2d+1 shaped.\n"
202 "Consider using the <indices> option tag to declare "
203 " iterator indices");
205 /* Compute the value of the iterator indices. */
206 for (j = 0; j < stmt_depth; ++j)
208 int val = SCOPVAL_get_si(m->p[2 * j][m->NbColumns - 1]);
209 if (last[j] < val)
211 last[j] = val;
212 for (k = j + 1; k < max_loop_depth; ++k)
213 last[k] = 0;
214 for (k = j; k < max_loop_depth; ++k)
215 cur_index[k] = max + (k - j) + 1;
216 break;
220 int* index = index_2d_array[idx];
221 for (j = 0; j < stmt_depth; ++j)
222 index[j] = cur_index[j];
225 max = max < cur_index[j - 1] ? cur_index[j - 1] : max;
227 } //end for each statement
229 return index_2d_array;
233 * Returns a string containing the dependence, formatted to fit the
234 * .scop representation.
237 static
238 char*
239 convert_candl_program_deps_to_string(CandlDependence* dependence)
241 CandlDependence* tmp = dependence;
242 int refs = 0, reft = 0;
243 int i, j, k;
244 int nb_deps;
245 int buffer_size = 2048;
246 int szbuff;
247 char* buffer = (char*) malloc(buffer_size * sizeof(char));
248 char buff[1024];
249 char* type;
250 char* pbuffer;
252 //printf("pointer buffer=%x\n",buffer);
253 for (tmp = dependence, nb_deps = 0; tmp; tmp = tmp->next, ++nb_deps)
255 sprintf(buffer, "# Number of dependences\n%d\n", nb_deps);
256 if (nb_deps)
258 for (tmp = dependence, nb_deps = 1; tmp; tmp = tmp->next, ++nb_deps)
260 /* Compute the type of the dependence, and the array id
261 accessed. */
262 switch (tmp->type)
264 case CANDL_UNSET:
265 type = "UNSET";
266 break;
267 case CANDL_RAW:
268 type = "RAW #(flow)";
269 refs = tmp->array_id; //already set outside
270 reft = tmp->array_id;
271 break;
272 case CANDL_WAR:
273 type = "WAR #(anti)";
274 refs = tmp->array_id;
275 reft = tmp->array_id;
276 break;
277 case CANDL_WAW:
278 type = "WAW #(output)";
279 refs = tmp->array_id;
280 reft = tmp->array_id;
281 break;
282 case CANDL_RAR:
283 type = "RAR #(input)";
284 refs = tmp->array_id;
285 reft = tmp->array_id;
286 break;
287 case CANDL_RAW_SCALPRIV:
288 type = "RAW_SCALPRIV #(scalar priv)";
289 refs = tmp->array_id;
290 reft = tmp->array_id;
291 break;
292 default:
293 exit(1);
294 break;
296 /* Quick consistency check. */
297 if (refs != reft)
298 CONVERTER_error("Internal error. refs != reft\n");
300 /* Output dependence information. */
301 sprintf(buff, "# Description of dependence %d\n"
302 "# type\n%s\n# From statement id\n%d\n"
303 "# To statement id\n%d\n# Depth \n%d\n# Array id\n%d\n"
304 "# Source ref index\n%d\n# Target ref index\n%d\n"
305 "# Dependence domain\n%d %d\n", nb_deps, type,
306 tmp->label_source, tmp->label_target, tmp->depth,
307 refs, tmp->ref_source, tmp->ref_target,
308 tmp->domain->NbRows, tmp->domain->NbColumns);
310 strcat(buffer, buff);
312 /* Output dependence domain. */
313 pbuffer = buffer + strlen(buffer);
314 for (i = 0; i < tmp->domain->NbRows; ++i)
316 for (j = 0; j < tmp->domain->NbColumns; ++j)
318 sprintf(buff, "%ld ", SCOPVAL_get_si(tmp->domain->p[i][j]));
319 szbuff = strlen(buff);
320 if (szbuff == 2)
321 *(pbuffer++) = ' ';
322 for (k = 0; k < szbuff; ++k)
323 *(pbuffer++) = buff[k];
325 *(pbuffer++) = '\n';
327 *(pbuffer++) = '\0';
328 /* Increase the buffer size if needed. Conservatively assume a
329 dependence is never larger than 2k. */
330 szbuff = strlen(buffer);
331 if (szbuff + 2048 > buffer_size)
333 buffer = (char*) realloc(buffer, (buffer_size *= 2) *
334 sizeof(char));
335 if (buffer == NULL)
336 CONVERTER_error("Error: memory overflow");
337 buffer[szbuff] = '\0';
343 return buffer;
348 * Update the scop option tag with the dependence list.
350 * \param[in/out] scop scop to be updated
351 * \param[in] dependence dependence list
352 * \return void
354 void convert_candl_dependence_update_scop_with_deps(scoplib_scop_p scop,
355 CandlDependence* dependence)
357 char* start;
358 char* stop;
359 char* content;
360 char* olddeps = NULL;
361 char* newdeps;
362 char* newopttags;
363 char* curr;
364 char* tmp;
365 int size = 0;
366 int size_newdeps;
367 int size_olddeps = 0;
368 int size_optiontags;
370 start = stop = scop->optiontags;
371 /* Get the candl tag, if any. */
372 content = scoplib_scop_tag_content(scop, "<candl>", "</candl>");
373 if (content)
375 /* Get the dependence tag, if any. */
376 olddeps = scoplib_scop_tag_content_from_string
377 (content, "<dependence-polyhedra>", "</dependence-polyhedra>");
378 /* Seek for the correct start/stop characters to insert
379 dependences. */
380 if (olddeps)
382 size = size_olddeps = strlen(olddeps);
383 while (start && *start && strncmp(start, olddeps, size))
384 ++start;
385 stop = start + size;
387 else
389 size = strlen(content);
390 while (start && *start && strncmp(start, content, size))
391 ++start;
392 stop = start;
397 /* Convert the program dependences to dotscop representation. */
398 newdeps = convert_candl_program_deps_to_string(dependence);
400 /* Compute the new size of the full options tags, and allocate a new
401 string. */
402 size_newdeps = newdeps ? strlen(newdeps) : 0;
404 size_optiontags = scop->optiontags ? strlen(scop->optiontags) : 0;
406 if (content == NULL)
407 size = strlen("<candl>\n") + strlen("</candl>\n") +
408 strlen("<dependence-polyhedra>\n")
409 + strlen("</dependence-polyhedra>\n");
410 else if (olddeps == NULL)
411 size = strlen("<dependence-polyhedra>\n") +
412 strlen("</dependence-polyhedra>\n");
413 else
414 size = 0;
415 newopttags = (char*) malloc((size_newdeps + size_optiontags
416 - size_olddeps + size + 1)
417 * sizeof(char));
420 if (newopttags == NULL)
421 CONVERTER_error("Error: memory overflow");
422 curr = newopttags;
424 /* Copy the beginning of the options. */
425 for (tmp = scop->optiontags; tmp != start; ++tmp)
426 *(curr++) = *tmp;
427 *curr = '\0';
428 //printf("pointer curr, after copy start: %x\n", curr);
429 /* Copy the candl tags, if needed. */
430 if (content == NULL)
432 strcat(newopttags, "<candl>\n");
433 curr += strlen("<candl>\n");
435 if (olddeps == NULL)
437 strcat(newopttags, "<dependence-polyhedra>\n");
438 curr += strlen("<dependence-polyhedra>\n");
442 /* Copy the program dependences. */
443 for (tmp = newdeps; tmp && *tmp; ++tmp)
444 *(curr++) = *tmp;
445 *curr = '\0';
449 /* Copy the candl tags, if needed. */
450 if (olddeps == NULL)
452 strcat(curr, "</dependence-polyhedra>\n");
453 curr += strlen("</dependence-polyhedra>\n");
455 if (content == NULL)
457 strcat(curr, "</candl>\n");
458 curr += strlen("</candl>\n");
462 /* Copy the remainder of the options. */
463 for (tmp = stop; tmp && *tmp; ++tmp)
464 *(curr++) = *tmp;
465 *curr = '\0';
469 if (scop->optiontags)
470 free(scop->optiontags);
471 scop->optiontags = newopttags;
473 /* Be clean. */
474 if (content)
475 free(content);
476 if (olddeps)
477 free(olddeps);
479 if (newdeps){
480 free(newdeps);
489 * Convert osl_scop_dependence into scoplib_scop_dependence
491 * look for dependency extensions in osl_scop
492 * if found, convert them into candl-scoplib_dependencis
493 * insert them into the tagoptions part of the scoplib_scop
495 * \param[in] inscop input osl scop
496 * \param[in/out] outscop to be upadated scoplib_scop
497 * \return void
499 void convert_dep_osl2scoplib(osl_scop_p inscop, scoplib_scop_p outscop){
500 int i=0;
501 scoplib_statement_p s = NULL;
502 scoplib_statement_p t = NULL;
504 if(inscop==NULL || outscop==NULL)
505 return; //warning?
507 //look for candl-osl dependencies inscop
508 osl_dependence_p gen_dep = osl_generic_lookup(inscop->extension,
509 OSL_URI_DEPENDENCE);
510 if(gen_dep==NULL)
511 return; //no depnedence_structure found
514 //convert dependencies
515 CandlDependence *cdep = NULL;
516 CandlDependence *last = NULL;
517 for( ; gen_dep; gen_dep = gen_dep->next){
520 CandlDependence * tmp = candl_dependence_malloc();
522 // get source statement
523 tmp->label_source = gen_dep->label_source;
524 for(i=0, s=outscop->statement; i<gen_dep->label_source; i++, s=s->next)
527 // get target statement
528 tmp->label_target = gen_dep->label_target;
529 for(i=0, t=outscop->statement; i<gen_dep->label_target; i++, t=t->next)
532 // accordint to dep_type, figure out array_s and array_t
533 // get type
534 scoplib_matrix_p array_s = NULL; //TODO: scoplib_matrix == pipmatrix??
535 scoplib_matrix_p array_t = NULL;
536 int s_acc_type = -1;
537 int t_acc_type = -1;
538 switch(gen_dep->type){
539 case OSL_DEPENDENCE_RAW:
540 tmp->type = CANDL_RAW;
541 array_s = s->write;
542 array_t = t->read;
543 s_acc_type = OSL_TYPE_WRITE;
544 t_acc_type = OSL_TYPE_READ;
545 break;
547 case OSL_DEPENDENCE_RAR:
548 tmp->type = CANDL_RAR;
549 array_s = s->read;
550 array_t = t->read;
551 s_acc_type = OSL_TYPE_READ;
552 t_acc_type = OSL_TYPE_READ;
553 break;
555 case OSL_DEPENDENCE_WAR:
556 tmp->type = CANDL_WAR;
557 array_s = s->read;
558 array_t = t->write;
559 s_acc_type = OSL_TYPE_READ;
560 t_acc_type = OSL_TYPE_WRITE;
561 break;
563 case OSL_DEPENDENCE_WAW:
564 tmp->type = CANDL_WAW;
565 array_s = s->write;
566 array_t = t->write;
567 s_acc_type = OSL_TYPE_WRITE;
568 t_acc_type = OSL_TYPE_WRITE;
569 break;
571 case OSL_DEPENDENCE_RAW_SCALPRIV:
572 tmp->type = CANDL_RAW_SCALPRIV;
573 array_s = s->write;
574 array_t = t->read;
575 s_acc_type = OSL_TYPE_WRITE;
576 t_acc_type = OSL_TYPE_READ;
577 break;
579 default:
580 CONVERTER_error("Unknown type for dependency in scoplib_scop\n");
581 break;
584 //get depth
585 tmp->depth = gen_dep->depth;
590 int s_ref_index= 0;
591 //get array_id
592 osl_relation_list_p in_acc = gen_dep->stmt_source_ptr->access;
593 for(i=0; in_acc && i< gen_dep->ref_source; i++){
595 if(s_acc_type==in_acc->elt->type){
596 s_ref_index += in_acc->elt->nb_output_dims==1?
597 in_acc->elt->nb_output_dims :
598 in_acc->elt->nb_output_dims-1;
599 } //special case
600 else if(s_acc_type==OSL_TYPE_WRITE &&
601 in_acc->elt->type==OSL_TYPE_MAY_WRITE)
602 s_ref_index += in_acc->elt->nb_output_dims==1?
603 in_acc->elt->nb_output_dims :
604 in_acc->elt->nb_output_dims-1;
606 in_acc=in_acc->next;
608 int src_arr_id = osl_int_get_si(in_acc->elt->precision,
609 in_acc->elt->m[0][in_acc->elt->nb_columns-1]);
611 int t_ref_index= 0;
612 in_acc = gen_dep->stmt_target_ptr->access;
613 for(i=0; in_acc && i< gen_dep->ref_target; i++){
615 if(t_acc_type==in_acc->elt->type){
616 t_ref_index += in_acc->elt->nb_output_dims==1?
617 in_acc->elt->nb_output_dims :
618 in_acc->elt->nb_output_dims-1;
619 } //special case
620 else if(t_acc_type==OSL_TYPE_WRITE &&
621 in_acc->elt->type==OSL_TYPE_MAY_WRITE)
622 t_ref_index += in_acc->elt->nb_output_dims==1?
623 in_acc->elt->nb_output_dims :
624 in_acc->elt->nb_output_dims-1;
626 in_acc=in_acc->next;
628 int tgt_arr_id = osl_int_get_si(in_acc->elt->precision,
629 in_acc->elt->m[0][in_acc->elt->nb_columns-1]);
633 if(src_arr_id != tgt_arr_id)
634 CONVERTER_error("osl_dep different src and target references\n");
635 else
636 tmp->array_id = src_arr_id;
641 tmp->ref_source = s_ref_index;
642 tmp->ref_target = t_ref_index; //
646 tmp->domain = convert_dep_domain_osl2scoplib(gen_dep);
649 //update the dependence list
650 if(cdep==NULL)
651 cdep = last = tmp;
652 else{
653 last->next = tmp;
654 last = last->next;
661 //update outscop with dependencies
662 convert_candl_dependence_update_scop_with_deps(outscop, cdep);
664 if(cdep) candl_dependence_free(cdep);
669 * this functions converts an osl dependence domain to scoplib dep domain
671 * \param[in] in_dep osl dependence
672 * \return scoplib_matrix containing scoplib dependence domain
674 scoplib_matrix_p convert_dep_domain_osl2scoplib(osl_dependence_p in_dep){
676 // allocate out_domain
677 int s_dom_output_dims = in_dep->source_nb_output_dims_domain;
678 int s_acc_output_dims = in_dep->source_nb_output_dims_access;
679 int t_dom_output_dims = in_dep->target_nb_output_dims_domain;
680 int t_acc_output_dims = in_dep->target_nb_output_dims_access;
682 /* Compute osl domain indexes */
683 int nb_par = in_dep->stmt_source_ptr->domain->nb_parameters;
684 int nb_local_dims = in_dep->source_nb_local_dims_domain +
685 in_dep->source_nb_local_dims_access +
686 in_dep->target_nb_local_dims_domain +
687 in_dep->target_nb_local_dims_access;
688 int nb_output_dims = in_dep->source_nb_output_dims_domain +
689 in_dep->source_nb_output_dims_access;
690 int nb_input_dims = in_dep->target_nb_output_dims_domain +
691 in_dep->target_nb_output_dims_access;
693 int osl_ind_source_local_domain = 1 + nb_output_dims + nb_input_dims;
694 int osl_ind_source_local_access = osl_ind_source_local_domain +
695 in_dep->source_nb_local_dims_domain;
696 int osl_ind_target_local_domain = osl_ind_source_local_access +
697 in_dep->source_nb_local_dims_access;
698 int osl_ind_target_local_access = osl_ind_target_local_domain +
699 in_dep->target_nb_local_dims_domain;
700 int osl_ind_params = osl_ind_target_local_access +
701 in_dep->target_nb_local_dims_access;
703 /* Compute scoplib domain indexes */
704 // num_output_dims same for osl==scoplib??
705 int slib_ind_target_domain = 1 + in_dep->source_nb_output_dims_domain;
706 int slib_ind_params = slib_ind_target_domain +
707 in_dep->target_nb_output_dims_domain;
709 int rows, cols =0;
711 int nb_pars = in_dep->stmt_source_ptr->domain->nb_parameters;
712 int s_dom_rows =in_dep->stmt_source_ptr->domain->nb_rows;
713 int t_dom_rows =in_dep->stmt_target_ptr->domain->nb_rows;
714 int s_acc_rows = in_dep->ref_source_access_ptr->nb_rows - 1;
717 int depth = in_dep->depth;
720 rows = s_dom_rows+t_dom_rows+
721 (s_acc_rows==0? 1: s_acc_rows) //special case for 0-dimention array(scalar)
722 +depth;
723 //cols: 2 => eq + const
724 cols = s_dom_output_dims+t_dom_output_dims+nb_pars+2;
726 scoplib_matrix_p m = scoplib_matrix_malloc(rows, cols);
728 int i=0;
729 int j=0;
730 int osl_constraint = 0;
731 int scoplib_constraint = 0;
732 int osl_index=0;
733 int scoplib_index=0;
736 // copy source domain
737 osl_relation_p s_domain = in_dep->stmt_source_ptr->domain;
738 for(i=0; i< s_domain->nb_rows; i++){
740 //copy first column + start of matrix
741 for (j=0;j<=s_dom_output_dims; j++)
742 convert_int_assign_osl2scoplib(&(m->p[scoplib_constraint][j]),
743 in_dep->domain->precision,
744 in_dep->domain->m[osl_constraint][j] );
747 // copy localdims - not supprted by converter
748 if(s_domain->nb_local_dims)
749 CONVERTER_error("local dimensions in domain not supproted\n");
752 // copy params + constant
753 osl_index = osl_ind_params;
754 scoplib_index = slib_ind_params;
755 for (j=0; j<nb_pars+1; j++)
756 convert_int_assign_osl2scoplib(
757 &(m->p[scoplib_constraint][scoplib_index+j]),
758 in_dep->domain->precision,
759 in_dep->domain->m[osl_constraint][osl_index+j]);
761 osl_constraint++;
762 scoplib_constraint++;
765 // copy target domain
766 osl_relation_p t_domain = in_dep->stmt_target_ptr->domain;
767 for(i=0; i< t_domain->nb_rows; i++){
769 //copy first column
770 convert_int_assign_osl2scoplib(&(m->p[scoplib_constraint][0]),
771 in_dep->domain->precision,
772 in_dep->domain->m[osl_constraint][0]);
773 //start of matrix
774 osl_index = 1 + nb_output_dims;
775 scoplib_index = slib_ind_target_domain;
776 for (j=0;j<t_dom_output_dims; j++)
777 convert_int_assign_osl2scoplib(
778 &(m->p[scoplib_constraint][scoplib_index+j]),
779 in_dep->domain->precision,
780 in_dep->domain->m[osl_constraint][osl_index+j]);
782 // copy local dims - not supported in converter
783 if(t_domain->nb_local_dims)
784 CONVERTER_error("local dimensions in domain not supproted\n");
786 // copy params + constant
787 osl_index = osl_ind_params;
788 scoplib_index = slib_ind_params;
789 for (j=0; j<nb_pars+1; j++)
790 convert_int_assign_osl2scoplib(
791 &(m->p[scoplib_constraint][scoplib_index+j]),
792 in_dep->domain->precision,
793 in_dep->domain->m[osl_constraint][osl_index+j]);
795 scoplib_constraint++;
796 osl_constraint++;
799 // copy source as well as target access
800 int osl_s_index = 0;
801 int osl_t_index = 0;
802 int scoplib_s_index = 0;
803 int scoplib_t_index = 0;
805 osl_relation_p s_access = in_dep->ref_source_access_ptr;
806 osl_relation_p t_access = in_dep->ref_target_access_ptr;
808 osl_constraint++; //skip the array_id line
809 // s_acc_rows calculated skipping array_id line
810 //TODO: see the array_id line skipping again!!
811 for(i=0; i < s_acc_rows; i++){
813 osl_s_index = 1;
814 osl_t_index = 1 + nb_output_dims;
815 scoplib_s_index = 1;
816 scoplib_t_index = slib_ind_target_domain;
818 for (j=0; j<s_access->nb_input_dims; j++){
819 convert_int_assign_osl2scoplib(
820 &(m->p[scoplib_constraint][scoplib_s_index+j]),
821 in_dep->domain->precision,
822 in_dep->domain->m[osl_constraint][osl_s_index+j]);
825 for (j=0; j<t_access->nb_input_dims; j++){ //t_acc_dims==s_acc_dims
826 convert_int_assign_osl2scoplib(
827 &(m->p[scoplib_constraint][scoplib_t_index+j]),
828 in_dep->domain->precision,
829 in_dep->domain->m[osl_constraint+s_access->nb_rows][osl_t_index+j]);
832 //copy local dimensions - not supported by converter
833 if(s_access->nb_local_dims || t_access->nb_local_dims)
834 CONVERTER_error("local dimensions in Access not supproted\n");
836 // copy params + constant
837 osl_index = osl_ind_params;
838 scoplib_index = slib_ind_params;
839 for (j=0; j<nb_pars+1; j++){
840 //get src params
841 int isrc_param = osl_int_get_si(in_dep->domain->precision,
842 in_dep->domain->m[osl_constraint][osl_index+j]);
843 //get tgt params
844 int itgt_param = osl_int_get_si(in_dep->domain->precision,
845 in_dep->domain->m[osl_constraint+s_access->nb_rows][osl_index+j]);
846 //convert ints to scoplib_int_t
847 scoplib_int_t tgt_param;
848 scoplib_int_t src_param;
849 SCOPVAL_init_set_si(tgt_param, itgt_param);
850 SCOPVAL_init_set_si(src_param, isrc_param);
852 SCOPVAL_oppose(tgt_param, tgt_param);
853 //TODO:ask Cédric: why subtraction??
854 SCOPVAL_subtract((m->p[scoplib_constraint][scoplib_index+j]),
855 src_param,
856 tgt_param);
858 SCOPVAL_clear(tgt_param);
859 SCOPVAL_clear(src_param);
862 scoplib_constraint++;
863 osl_constraint++;
866 // copy access equalities -> not in CANDL-scoplib??
867 // skip min_depth
868 int min_depth = CONVERTER_min(s_access->nb_output_dims,
869 t_access->nb_output_dims);
871 osl_constraint += s_access->nb_rows + min_depth;
873 if(s_acc_rows==0) scoplib_constraint++; //TODO: explain this
876 // copy depth
877 osl_s_index = 1;
878 osl_t_index = 1 + nb_output_dims;
879 scoplib_s_index = 1;
880 scoplib_t_index = slib_ind_target_domain;
881 for(i=0; i< depth; i++){
882 // copy first column
884 convert_int_assign_osl2scoplib(&(m->p[scoplib_constraint][0]),
885 in_dep->domain->precision,
886 in_dep->domain->m[osl_constraint][0]);
888 // copy subscript equalities
889 convert_int_assign_osl2scoplib(&(m->p[scoplib_constraint][scoplib_s_index+i]),
890 in_dep->domain->precision,
891 in_dep->domain->m[osl_constraint][osl_s_index+i]);
892 convert_int_assign_osl2scoplib(&(m->p[scoplib_constraint][scoplib_t_index+i]),
893 in_dep->domain->precision,
894 in_dep->domain->m[osl_constraint][osl_t_index+i]);
896 // copy params -> not applicable here
898 // copy const == last column
899 convert_int_assign_osl2scoplib(&(m->p[scoplib_constraint][m->NbColumns-1]),
900 in_dep->domain->precision,
901 in_dep->domain->m[osl_constraint][in_dep->domain->nb_columns-1]);
903 osl_constraint++;
904 scoplib_constraint++;
907 // return new domain
908 return m;
913 * for a scoplib reference access
914 * returns the number of output dimensions (including the array_id)
916 * \param[in] access scoplib access matrix
917 * \param[in] ref_index index for the target array in access matrix
918 * \return number of dimensions for target array
920 int get_scoplib_access_output_dims(scoplib_matrix_p access, int ref_index){
922 if( access == NULL )
923 return 0;
925 /* We calculate the number of dimensions of the considered array. */
926 int nb_dimensions = 1; //TODO: check this out!!!!
927 while ( ((ref_index + nb_dimensions + 1) <= access->NbRows) &&
928 SCOPVAL_zero_p(access->p[ref_index + nb_dimensions][0]) )
929 nb_dimensions ++ ;
931 //check for zero-dimension array (scalar)
932 int i=0;
933 int has_dimension = 0;
934 if(nb_dimensions == 1)
935 for(i=1; i< access->NbColumns; i++)
936 if( !SCOPVAL_zero_p(access->p[ref_index][i]) ) //it's non-scalar
937 has_dimension = 1; ; //
939 if(nb_dimensions > 1) //normal case
940 nb_dimensions ++ ;//add one for the array_id dimension
941 else if(nb_dimensions==1 && has_dimension) //single dimension array
942 nb_dimensions ++ ;//add one for the array_id dimension
943 //else //TODO: scalar
944 // nb_dimensions ++ ;//add one for the array_id dimension
946 return nb_dimensions;
952 * given a reference sequence number n, this function returns the index in the
953 * scoplib access matrix for the nth reference
954 * ref_number starts from 1
956 * \param[in] m scoplib_access_matrix
957 * \param[in] ref_number sequence number for ref in the matrix
958 * \return nth reference's index
960 int get_scoplib_ref_index( scoplib_matrix_p m, int ref_number){
961 int i=0;
962 for(i=0; i<m->NbRows ; i++){
963 if(m->p[i][0] != 0)
964 ref_number--;
966 if(ref_number==0)
967 break;
970 return i;
975 * given an index, returns the statement at that index
976 * index starting from zero
978 * \param[in] in_scop scop containing the statmeent list
979 * \param[in] index statement index
980 * \return statemetn at 'index"
982 scoplib_statement_p get_statement( scoplib_scop_p in_scop, int index){
984 if( in_scop == NULL )
985 return NULL;
987 scoplib_statement_p stmt = in_scop->statement;
988 int i=0;
989 for( i=0; i< index; i++)
990 stmt = stmt->next;
992 return stmt;
998 * given a dependence type, returns the correct (read/write)
999 * access_lists from source/target statements.
1001 * \param[in] type dependence type
1002 * \param[in] s source statement
1003 * \param[in] t target statement
1004 * \param[out] access_s list of relevant accesses for source statement
1005 * \param[out] access_t list of relevant accesses for target statement
1006 * \return void
1008 void get_dependence_accesses (int type,
1009 scoplib_statement_p s, scoplib_statement_p t,
1010 scoplib_matrix_t **access_s,
1011 scoplib_matrix_t ** access_t){
1013 if(s==NULL || t==NULL)
1014 CONVERTER_error("Null statement pointer passed\n");
1016 switch (type)
1018 case CANDL_RAW:
1019 case CANDL_RAW_SCALPRIV:
1020 *access_s = s->write;
1021 *access_t = t->read;
1022 break;
1023 case CANDL_WAR:
1024 *access_s = s->read;
1025 *access_t = t->write;
1026 break;
1027 case CANDL_WAW:
1028 *access_s = s->write;
1029 *access_t = t->write;
1030 break;
1031 case CANDL_RAR:
1032 *access_s = s->read;
1033 *access_t = t->read;
1034 break;
1035 default:
1036 CONVERTER_error("Unknown dependence type encountered.\n");
1037 break;
1040 return;
1046 * this function converts a scoplib dependence domain to its osl equivalent
1048 * \param[in] in_dep scoplib dependence
1049 * \param[in] in_dep scoplib scop
1050 * \return equivalent coverted osl dependence domain
1051 * return osl_dependence domain
1053 osl_relation_p convert_dep_domain_scoplib2osl(candl_dependence_p in_dep,
1054 scoplib_scop_p in_scop){
1056 if(in_dep == NULL)
1057 return NULL;
1059 // arrays_output_dims
1060 scoplib_statement_p stmt_s = get_statement(in_scop, in_dep->label_source);
1061 scoplib_statement_p stmt_t = get_statement(in_scop, in_dep->label_target);
1063 // get the corresponding access
1064 scoplib_matrix_p s_array = NULL;
1065 scoplib_matrix_p t_array = NULL;
1066 get_dependence_accesses (in_dep->type, stmt_s, stmt_t, &s_array, &t_array);
1069 int s_arr_output_dims = get_scoplib_access_output_dims(s_array,
1070 in_dep->ref_source);
1071 int t_arr_output_dims = get_scoplib_access_output_dims(t_array,
1072 in_dep->ref_target);
1074 // calculate min_depth
1075 int min_depth = CONVERTER_min(s_arr_output_dims, t_arr_output_dims);
1077 // calculate the number of row and cols for osl_domain
1078 int nb_par = in_scop->context->NbColumns-2;
1079 int s_dom_output_dims = stmt_s->domain->elt->NbColumns - nb_par -2;
1080 int t_dom_output_dims = stmt_t->domain->elt->NbColumns - nb_par -2;
1081 int osl_output_dims = s_dom_output_dims + s_arr_output_dims;
1082 int osl_input_dims = t_dom_output_dims + t_arr_output_dims;
1083 int osl_local_dims = 0; //local dims not supported by converter
1086 int nrows = stmt_s->domain->elt->NbRows + stmt_t->domain->elt->NbRows +
1087 s_arr_output_dims + t_arr_output_dims +
1088 min_depth + in_dep->depth;
1090 int ncols = osl_output_dims +
1091 osl_input_dims +
1092 osl_local_dims +
1093 nb_par + 2;
1096 osl_relation_p m = osl_relation_malloc(nrows, ncols);
1097 scoplib_matrix_p dom = in_dep->domain;
1100 //calculate certain indexes
1101 //scoplib
1102 int scoplib_t_dom_index = 1 + s_dom_output_dims;
1103 int scoplib_param_index = scoplib_t_dom_index + t_dom_output_dims;
1105 //osl
1106 int osl_s_acc_index = 1 + s_dom_output_dims;
1107 int osl_t_dom_index = osl_s_acc_index + s_arr_output_dims;
1108 int osl_t_acc_index = osl_t_dom_index + t_dom_output_dims;
1109 int osl_s_loc_dom_index = osl_t_acc_index + t_arr_output_dims;
1110 int osl_param_index = osl_s_loc_dom_index + osl_local_dims;
1113 //fill in the values related to source domain
1114 int scoplib_constraint = 0; //row index scoplib_domain
1115 int osl_constraint = 0; //row index for osl_domain
1117 int i=0;
1118 int j=0;
1120 // fill in source domain
1121 for(i=0; i< stmt_s->domain->elt->NbRows; i++){
1122 // copy first column
1123 // copy matrix start
1124 int osl_index = 0;
1125 int scoplib_index = 0;
1126 for(j=0; j<=s_dom_output_dims; j++){
1127 convert_int_assign_scoplib2osl(m->precision,
1128 &m->m[osl_constraint][osl_index+j],
1129 dom->p[scoplib_constraint][scoplib_index+j]);
1132 // copy local dims - not supported
1134 // copy params + const
1135 osl_index = osl_param_index;
1136 scoplib_index = scoplib_param_index;
1137 for(j=0; j< nb_par+1; j++){
1138 convert_int_assign_scoplib2osl(m->precision,
1139 &m->m[osl_constraint][osl_index+j],
1140 dom->p[scoplib_constraint][scoplib_index+j]);
1143 osl_constraint++;
1144 scoplib_constraint++;
1151 //fill in the values related to target domain
1152 for(i=0; i< stmt_t->domain->elt->NbRows; i++){
1153 // copy first column
1154 convert_int_assign_scoplib2osl(m->precision,
1155 &m->m[osl_constraint][0],
1156 dom->p[scoplib_constraint][0]);
1158 // copy matrix start
1159 int osl_index = osl_t_dom_index;
1160 int scoplib_index = scoplib_t_dom_index;
1161 for(j=0; j<t_dom_output_dims; j++){
1162 convert_int_assign_scoplib2osl(m->precision,
1163 &m->m[osl_constraint][osl_index+j],
1164 dom->p[scoplib_constraint][scoplib_index+j]);
1167 // copy local dims - not supported
1169 // copy params + const
1170 osl_index = osl_param_index;
1171 scoplib_index = scoplib_param_index;
1172 for(j=0; j< nb_par+1; j++){
1173 convert_int_assign_scoplib2osl(m->precision,
1174 &m->m[osl_constraint][osl_index+j],
1175 dom->p[scoplib_constraint][scoplib_index+j]);
1178 osl_constraint++;
1179 scoplib_constraint++;
1186 int scoplib_constraint_backup = scoplib_constraint;
1187 // fill in values related to source access
1188 for(i=0; i< s_arr_output_dims; i++){
1189 if(i==0){ // creating the Array_ID line first
1190 // copy first column
1191 osl_int_set_si(m->precision,
1192 &m->m[osl_constraint][0], 0);
1194 //set the output dims
1195 int osl_index = osl_s_acc_index;
1196 osl_int_set_si(m->precision,
1197 &m->m[osl_constraint][osl_index+i], -1); //using "i"
1199 //copy const
1200 long int value = -1;
1201 value = SCOPVAL_get_si(s_array->p[in_dep->ref_source][0]);
1202 osl_int_set_si(m->precision,
1203 &m->m[osl_constraint][m->nb_columns-1], value);
1205 osl_constraint++;
1207 else{ // the rest of the dimensions
1208 // copy first column
1209 convert_int_assign_scoplib2osl(m->precision,
1210 &m->m[osl_constraint][0],
1211 dom->p[scoplib_constraint][0]);
1213 //set the output dims
1214 int osl_index = osl_s_acc_index;
1215 int scoplib_index = -1;
1216 osl_int_set_si(m->precision,
1217 &m->m[osl_constraint][osl_index+i], -1);//using "i"
1219 //copy the input dims
1220 osl_index = 1;
1221 scoplib_index = 1;
1222 for(j=0; j< s_dom_output_dims; j++){
1223 convert_int_assign_scoplib2osl(m->precision,
1224 &m->m[osl_constraint][osl_index+j],
1225 dom->p[scoplib_constraint][scoplib_index+j]);
1228 //copy the params
1229 // params and cosnt copied from access relation!!
1230 osl_index = osl_param_index;
1231 scoplib_index = scoplib_param_index;
1232 int scoplib_index_acc_param = s_array->NbColumns - nb_par - 1;//1 -> const
1233 for(j=0; j< nb_par; j++){
1234 convert_int_assign_scoplib2osl(m->precision,
1235 &m->m[osl_constraint][osl_index+j],
1236 s_array->p[in_dep->ref_source+i-1][scoplib_index_acc_param+j]);
1239 //copy const
1240 long int value = -1;
1241 value =
1242 SCOPVAL_get_si(s_array->p[in_dep->ref_source+i-1][s_array->NbColumns-1]);
1243 osl_int_set_si(m->precision,
1244 &m->m[osl_constraint][m->nb_columns-1], value);
1246 osl_constraint++;
1247 scoplib_constraint++;
1254 scoplib_constraint = scoplib_constraint_backup;
1255 // fill in target access
1256 for(i=0; i< t_arr_output_dims; i++){
1257 if(i==0){ // create the Array_ID line first
1258 // copy first column
1259 osl_int_set_si(m->precision,
1260 &m->m[osl_constraint][0], 0);
1262 //set the output dims
1263 int osl_index = osl_t_acc_index;
1264 osl_int_set_si(m->precision,
1265 &m->m[osl_constraint][osl_index+i], //using "i"
1266 1); //1: as target is -ve of source
1268 //copy const
1269 scoplib_int_t value;
1270 SCOPVAL_init_set_si(value, -1);
1271 SCOPVAL_oppose(value, t_array->p[in_dep->ref_target][0]); //target is -ve
1272 osl_int_set_si(m->precision,
1273 &m->m[osl_constraint][m->nb_columns-1],
1274 SCOPVAL_get_si(value) );
1276 SCOPVAL_clear(value);
1278 osl_constraint++;
1280 else{ // rest of the values
1281 // copy first column
1282 convert_int_assign_scoplib2osl(m->precision,
1283 &m->m[osl_constraint][0],
1284 dom->p[scoplib_constraint][0]);
1286 //set the output dims
1287 int osl_index = osl_t_acc_index;
1288 int scoplib_index = -1;
1289 osl_int_set_si(m->precision,
1290 &m->m[osl_constraint][osl_index+i], //using "i"
1291 1); //1: as target is -ve of source
1293 //copy the input dims
1294 osl_index = osl_t_dom_index;
1295 scoplib_index = scoplib_t_dom_index;
1296 for(j=0; j< t_dom_output_dims; j++){
1297 convert_int_assign_scoplib2osl(m->precision,
1298 &m->m[osl_constraint][osl_index+j],
1299 dom->p[scoplib_constraint][scoplib_index+j]);
1302 //copy the params
1303 osl_index = osl_param_index;
1304 scoplib_index = scoplib_param_index;
1305 int scoplib_index_acc_param = t_array->NbColumns - nb_par - 1;//1 -> const
1306 for(j=0; j< nb_par; j++){
1307 convert_int_assign_scoplib2osl(m->precision,
1308 &m->m[osl_constraint][osl_index+j],
1309 t_array->p[in_dep->ref_target+i-1][scoplib_index_acc_param+j]);
1311 osl_int_oppose(m->precision,
1312 &m->m[osl_constraint][osl_index+j],
1313 m->m[osl_constraint][osl_index+j]);
1316 //copy const
1317 int value = -255;
1318 if(i==0)
1319 value = SCOPVAL_get_si(t_array->p[in_dep->ref_target][0]);
1320 else
1321 value = SCOPVAL_get_si(t_array->p[in_dep->ref_target+i-1][t_array->NbColumns-1]);
1323 osl_int_set_si(m->precision,
1324 &m->m[osl_constraint][m->nb_columns-1],
1325 value);
1326 osl_int_oppose(m->precision,
1327 &m->m[osl_constraint][m->nb_columns-1],
1328 m->m[osl_constraint][m->nb_columns-1]);
1330 osl_constraint++;
1331 scoplib_constraint++;
1338 //fill in the access identities
1339 int osl_index = osl_s_acc_index;
1340 int osl_index_2 = osl_t_acc_index;
1341 for(i=0; i< min_depth; i++){
1342 osl_int_set_si(m->precision, &m->m[osl_constraint][osl_index+i], -1);
1343 osl_int_set_si(m->precision, &m->m[osl_constraint][osl_index_2+i], 1);
1344 osl_constraint++;
1347 if(s_arr_output_dims == 1) //TODO: add eq counterpart in reverse direction
1348 scoplib_constraint++;
1350 // fill in precedence constraints
1351 osl_index = 1;
1352 osl_index_2 = osl_t_dom_index;
1353 int scoplib_index = 1;
1354 int scoplib_index_2 = scoplib_t_dom_index;
1355 for(i=0; i< in_dep->depth; i++){
1356 // copy first column
1357 convert_int_assign_scoplib2osl(m->precision,
1358 &m->m[osl_constraint][0],
1359 dom->p[scoplib_constraint][0]);
1362 convert_int_assign_scoplib2osl(m->precision,
1363 &m->m[osl_constraint][osl_index+i],
1364 dom->p[scoplib_constraint][scoplib_index+i]);
1365 convert_int_assign_scoplib2osl(m->precision,
1366 &m->m[osl_constraint][osl_index_2+i],
1367 dom->p[scoplib_constraint][scoplib_index_2+i]);
1369 //last column
1370 convert_int_assign_scoplib2osl(m->precision,
1371 &m->m[osl_constraint][m->nb_columns-1],
1372 dom->p[scoplib_constraint][dom->NbColumns-1]);
1374 osl_constraint++;
1375 scoplib_constraint++;
1380 m->nb_parameters = nb_par;
1381 m->nb_input_dims = osl_input_dims;
1382 m->nb_output_dims = osl_output_dims;
1383 m->nb_local_dims = osl_local_dims;
1385 return m;