modified autogen.sh to remove reference to osl/
[converter.git] / source / scoplib2osl.c
blob282b13c3a80b650d84bbeb48f22f1508b31ca68e
1 #include "converter/converter.h"
2 #include "converter/old_candl_dependence.h"
3 #include "osl/scop.h"
4 #include "osl/body.h"
5 #include "osl/generic.h"
6 #include "osl/extensions/arrays.h"
7 #include "osl/extensions/dependence.h"
8 #include "osl/interface.h"
9 #include <string.h> // warnings for strup in macros.h: incomatible implicit
10 #include "osl/macros.h"
12 #include "scoplib/scop.h"
13 #include "scoplib/matrix.h"
15 #include "candl/statement.h" //candl_statement_usr_p
16 #include "candl/util.h" //candl_relation_get_line()
18 #include <stdio.h>
19 #include <stdlib.h>
23 /*
24 * converts a normal matrix: without output/local/etc dims
26 osl_relation_p convert_matrix_scoplib2osl( scoplib_matrix_p m){
28 int i=0;
29 int j=0;
30 osl_relation_p out_rln = NULL;
31 if(m==NULL)
32 return NULL;
34 //allocate according to matrix's precision ??? :^^
35 out_rln = osl_relation_malloc(m->NbRows, m->NbColumns);
36 out_rln->type = OSL_TYPE_CONTEXT; //TODO: set it outside??
38 //calc supplementary dimensions
39 out_rln->nb_parameters = m->NbColumns-2;
40 out_rln->nb_output_dims = 0;
41 out_rln->nb_input_dims = 0;
42 out_rln->nb_local_dims = 0;
44 //copy content
45 for(i=0; i< m->NbRows; i++)
46 for(j=0; j< m->NbColumns; j++){
47 convert_int_assign_scoplib2osl(out_rln->precision, &out_rln->m[i][j],
48 m->p[i][j] );
51 return out_rln;
55 /*
56 * converts a domain matrix from scoplib to osl
58 osl_relation_p convert_domain_scoplib2osl( scoplib_matrix_list_p m_list,
59 scoplib_matrix_p ctx){
60 osl_relation_p out_rln = NULL;
61 osl_relation_p last_rl = NULL;
62 if(m_list==NULL ||m_list->elt==NULL || ctx==NULL)
63 return NULL;
65 scoplib_matrix_list_p ml = m_list;
66 for( ; ml; ml = ml->next){
68 scoplib_matrix_p m = ml->elt;
69 osl_relation_p rl = convert_matrix_scoplib2osl(ml->elt);
70 rl->type = OSL_TYPE_DOMAIN; //TODO: set it outside??
71 //rl->precision = //TODO: get it from scoplib
73 //calc supplementary dimensions
74 rl->nb_parameters = ctx->NbColumns-2;
75 rl->nb_output_dims = m->NbColumns-rl->nb_parameters-2; // iteratiors
76 rl->nb_input_dims = 0; // none
77 rl->nb_local_dims = 0; //none
80 if(out_rln==NULL)
81 out_rln=last_rl=rl;
82 else{
83 last_rl->next = rl;
84 last_rl = last_rl->next;
88 return out_rln;
95 * converts a scattering matrix
97 * \param[in] m scoplib domain
98 * \param[in] ctx scoplib scop context)
99 * \return osl_relation_p the converted osl domain
101 osl_relation_p convert_scattering_scoplib2osl( scoplib_matrix_p m,
102 scoplib_matrix_p ctx){
104 int i=0;
105 int j=0;
106 int nb_parameters=0;
107 int nb_output_dims=0;
108 int nb_input_dims=0;
109 int nb_local_dims=0;
111 osl_relation_p out_rln = NULL;
112 if(m==NULL || ctx==NULL)
113 return NULL;
115 //calc supplementary dimensions
116 nb_parameters = ctx->NbColumns-2;
118 nb_output_dims = m->NbRows; // equals number of matrix rows
120 nb_input_dims = m->NbColumns-nb_parameters-2; // none
121 nb_local_dims = 0; //none
123 //alloc - precision set in the malloc function
124 int nb_cols = nb_parameters+nb_output_dims+nb_input_dims+nb_local_dims+2;
125 int nb_rows = m->NbRows;
126 out_rln = osl_relation_malloc(nb_rows, nb_cols);
127 out_rln->type = OSL_TYPE_SCATTERING; //TODO: set it outside??
128 out_rln->nb_parameters = nb_parameters;
129 out_rln->nb_output_dims = nb_output_dims; // iteratiors
130 out_rln->nb_input_dims = nb_input_dims; // none
131 out_rln->nb_local_dims = nb_local_dims; //none
132 //out_rln->precision = //TODO: get it from scoplib
134 //copy content
135 for(i=0; i< out_rln->nb_rows; i++)
136 for(j=0; j< out_rln->nb_columns; j++){
137 if(j==0) // eq/neq (first) column
138 convert_int_assign_scoplib2osl(out_rln->precision,&out_rln->m[i][j],
139 m->p[i][j]);
140 else if(j>0 && j<=(nb_output_dims)) // for output dimentions
141 if( j==(i+1) ) //identification diagonal
143 scoplib_int_t dummy;
144 SCOPVAL_init_set_si(dummy, -1);
145 convert_int_assign_scoplib2osl(out_rln->precision,&out_rln->m[i][j],
146 dummy);
147 SCOPVAL_clear(dummy);
149 else // non diagonal zeros
151 scoplib_int_t dummy;
152 SCOPVAL_init_set_si(dummy, 0);
153 convert_int_assign_scoplib2osl(out_rln->precision,&out_rln->m[i][j],
154 dummy);
155 SCOPVAL_clear(dummy);
157 else // input dimensions + parameters + constant
158 convert_int_assign_scoplib2osl(out_rln->precision,&out_rln->m[i][j],
159 m->p[i][j-nb_output_dims]);
162 return out_rln;
166 * Determine heuristically, whether a given reference is an array or a variable
167 * In scoplib matrix, [ 12 0 0 0 0 0 ]
168 * it is not clear whether A=...., or A[0]=....
169 * We try to look at all the references to A (id=12 here) in the scop,
170 * and we try to see if it is accessed as A[x] (x!=0) in any statement.
171 * If yes, we convert the above matrix into A[0].
172 * Otherwise, we translate it as A=..., though there is still a slight chance
173 * that it is A[0] and used as A[0] in all its occrences!
174 * Converter issues a warning in such a conversion.
176 * \param[in] id the identifier for the array reference
177 * \param[in] in_stmt pointer to a list of statements to search in
178 * \return 1 if the reference is an array, 0 otherwise
180 int is_array(int id, scoplib_statement_p in_stmt){
182 int is_array = 0;
184 if(in_stmt==NULL)
185 CONVERTER_error("NULL statemnet pointer passed when searching for array\n");
187 while(in_stmt){
189 // check in read accesses
190 if(in_stmt->read != NULL){
191 int i=0;
192 for(i=0; i< in_stmt->read->NbRows; i++){ //for all rows
193 if( SCOPVAL_get_si(in_stmt->read->p[i][0]) == id){ //if found our id
194 //check for multidimensionality
195 if(i< in_stmt->read->NbRows-1 &&
196 SCOPVAL_zero_p(in_stmt->read->p[i+1][0]) ){
197 is_array=1;
198 } //end if not last row
200 //one dimensional array; single row entry in matrix
201 int j=0;
202 for(j=1; j< in_stmt->read->NbColumns; j++){//search after the 1st col
203 if( !SCOPVAL_zero_p(in_stmt->read->p[i][j]) ) //1st index != 0
204 is_array=1;
207 } //end if our type of id
208 } //end for all rows
209 } // end if read!=NULL
211 // check in write accesses
212 if(in_stmt->write != NULL){
213 int i=0;
214 for(i=0; i< in_stmt->write->NbRows; i++){ //for all rows
215 if(SCOPVAL_get_si(in_stmt->write->p[i][0]) == id){ //if found our id
216 //check for multidimensionality
217 if(i< in_stmt->write->NbRows-1 &&
218 SCOPVAL_zero_p(in_stmt->write->p[i+1][0]) ){
219 is_array=1;
220 } //end if not last row
222 //one dimensional array; single row entry in matrix
223 int j=0;
224 for(j=1; j< in_stmt->write->NbColumns; j++){//after the 1st col
225 if( !SCOPVAL_zero_p(in_stmt->write->p[i][j]) ) //1st index != 0
226 is_array=1;
229 } //end if our type of id
230 } //end for all rows
231 } // end if write!=NULL
234 in_stmt = in_stmt->next; // go to next statemnet
237 // a return value of zero is not 100% sure (see description above)
238 // issue a warning when using that value
239 return is_array;
243 * given a scoplib access matrix containing access details, this fucntion
244 * extracts info(array_id, nb_dims, is_scalar) about each array accessed
246 * \param[in] m scoplib access matrix
247 * \param[in] in_stmt statements to search if the nature of access is doubtful
248 * \param[out] num_arrays holds the number of accesses in matrix
249 * \param[out] array_identities array_ids of the accesses in the matrix
250 * \param[out] array_dimensions number of dimensions for each array
251 * \param[out] is_array_bool 1/0 whether the access is a vector/scalar
252 * \return number of arrays detected in the input matrix
255 int convert_get_scoplib_access_dimensions( scoplib_matrix_p m,
256 scoplib_statement_p in_stmt, //needed for array search
257 int *num_arrays,
258 int **array_identities,
259 int **array_dimensions,
260 int **is_array_booleans){
262 int nb_arrays=0;
264 if(m==NULL)
265 return nb_arrays;
267 int i=0;
268 for(i=0; i < m->NbRows; i++) //count number of access arrays
269 if( !SCOPVAL_zero_p(m->p[i][0]) ){
270 nb_arrays++;
273 *num_arrays = nb_arrays;
276 int *array_id = malloc(nb_arrays*sizeof(int));
277 int *array_has_dims = malloc(nb_arrays*sizeof(int));
278 int *array_dims = malloc(nb_arrays*sizeof(int));
280 *array_identities = array_id;
281 *array_dimensions = array_dims;
282 *is_array_booleans= array_has_dims;
285 for(i=0; i< nb_arrays; i++)
286 array_has_dims[i]=0;
288 //get array infos
289 int array_start = 0;
290 nb_arrays=0;
291 array_id[nb_arrays] = SCOPVAL_get_si(m->p[0][0]); // get array_id
293 //check for zero/one/multi-dimonsional arrays
294 if(m->NbRows>1 && SCOPVAL_zero_p(m->p[1][0]) ){ //multi-dimensions
295 array_has_dims[nb_arrays] = 1;
297 else{ //last row, or single_row entry in matrix; at-most one dimension
298 int tmp=0;
299 int j=0;
300 for(j=1; j< m->NbColumns; j++)
301 if(SCOPVAL_get_si(m->p[0][j]) != 0 ) //1st dimension != 0
302 tmp=1;
304 if(tmp==0) // differentiate b/w: A=... & A[0]=....
305 tmp = is_array(SCOPVAL_get_si(m->p[0][0]), in_stmt);
307 if(tmp==0) //possible zero-dimension
308 CONVERTER_warning("Guessing access is zero-dimensional array\n");
310 array_has_dims[nb_arrays] = tmp;
315 for(i=1; i < m->NbRows; i++){ //findout the dimensionn of each array
316 if( !SCOPVAL_zero_p(m->p[i][0]) ){
317 array_dims[nb_arrays++] = i - array_start; //curr. array dims
318 array_id[nb_arrays] = SCOPVAL_get_si(m->p[i][0]); //next array_id
320 if(i<m->NbRows-1 && m->p[i+1][0] == 0){ //multi-dimensional case
321 array_has_dims[nb_arrays] = 1;
323 else{ //last row, or single_row entry in matrix; atmost one dimensin
324 int tmp=0;
325 int j=0;
326 for(j=1; j< m->NbColumns; j++)
327 if( !SCOPVAL_zero_p(m->p[i][j]) ) //1st dimension != [0]
328 tmp=1;
330 if(tmp==0) // differentiate b/w: A=... & A[0]=....
331 tmp = is_array(SCOPVAL_get_si(m->p[i][0]), in_stmt);
333 if(tmp==0) //possibly zero-dimensional array
334 CONVERTER_warning("Guessing access is zero-dimensional array\n");
336 array_has_dims[nb_arrays] = tmp;
341 array_start = i;
344 array_dims[nb_arrays++] = i - array_start; //last array dims
347 return nb_arrays;
352 * converts access matrix
354 * \param[in] in_matrix scoplib access matrix to convert
355 * \param[in] ctx scoplib context needed to calculate nb_parameters
356 * \param[in] in_stmt statements to verify vector/scalar nature of acccess
357 * \param[in] type scoplib access matrix type: read/write
358 * \return new osl access relations list
360 osl_relation_list_p convert_access_scoplib2osl( scoplib_matrix_p in_matrix,
361 scoplib_matrix_p ctx,
362 scoplib_statement_p in_stmt,
363 int type){
365 int i=0;
366 int j=0;
367 int k=0;
368 int nb_parameters=0;
369 int nb_output_dims=0;
370 int nb_input_dims=0;
371 int nb_local_dims=0;
373 osl_relation_list_p out_rln_list = NULL;
374 osl_relation_list_p last_rl_list = NULL;
375 scoplib_matrix_p m = NULL;
376 if(in_matrix==NULL || ctx==NULL)
377 return NULL;
379 //Empty matrix
380 if(in_matrix->NbRows==0)
381 return NULL;
383 //calc supplementary dimensions
384 nb_parameters = ctx->NbColumns-2;
386 m = in_matrix;
387 nb_output_dims = 0; //
391 int num_arrays=0;
392 int * array_id = NULL;
393 int * array_has_dims = NULL;
394 int * array_dims = NULL;
395 convert_get_scoplib_access_dimensions(in_matrix, in_stmt, &num_arrays,
396 &array_id, &array_dims,
397 &array_has_dims);
402 //copy each array into a separate access relation
403 int m_row = 0; // scoplib matrix's row_count
404 osl_relation_p rl = NULL;
405 for(i=0; i< num_arrays; i++){
408 //set parameters
409 nb_parameters = ctx->NbColumns -2;
410 nb_output_dims = array_dims[i]+array_has_dims[i]; //one for the array_id
411 nb_local_dims = 0;
412 nb_input_dims = m->NbColumns-nb_parameters-2;
414 int nb_cols = nb_parameters+nb_output_dims+nb_local_dims+nb_input_dims+2;
415 int nb_rows = array_dims[i]+array_has_dims[i];
416 //out_rln->precision = //TODO: get it from scoplib
417 rl = osl_relation_malloc(nb_rows, nb_cols);
418 rl->type = type; //TODO: set it outside??
419 rl->nb_parameters = nb_parameters;
420 rl->nb_output_dims = nb_output_dims; //
421 rl->nb_input_dims = nb_input_dims; //
422 rl->nb_local_dims = nb_local_dims; //none
428 // copy the array_id line
429 // takes care of access relation for zero-dimensional array as well
431 for(k=0; k< nb_cols; k++){
432 if(k==0) // eq/neq (first) column
434 scoplib_int_t dummy;
435 SCOPVAL_init_set_si(dummy, 0);
436 convert_int_assign_scoplib2osl(rl->precision, &rl->m[0][k],
437 dummy);
438 SCOPVAL_clear(dummy);
440 else if( k==(0+1) ) // Arr
442 scoplib_int_t dummy;
443 SCOPVAL_init_set_si(dummy, -1);
444 convert_int_assign_scoplib2osl(rl->precision, &rl->m[0][k],
445 dummy);
446 SCOPVAL_clear(dummy);
448 else if(k==(nb_cols-1)) //Arr_id
450 scoplib_int_t dummy;
451 SCOPVAL_init_set_si(dummy, array_id[i]);
452 convert_int_assign_scoplib2osl(rl->precision, &rl->m[0][k],
453 dummy);
454 SCOPVAL_clear(dummy);
456 else // non diagonal zeros
458 scoplib_int_t dummy;
459 SCOPVAL_init_set_si(dummy, 0);
460 convert_int_assign_scoplib2osl(rl->precision, &rl->m[0][k],
461 dummy);
462 SCOPVAL_clear(dummy);
466 if(array_has_dims[i]){ //one/multi-dimensional case
467 //for each row
468 for(j=0; j< array_dims[i]; j++,m_row++){
469 //for each column
470 for(k=0; k< nb_cols; k++){
471 if(k==0) // eq/neq (first) column
473 scoplib_int_t dummy;
474 SCOPVAL_init_set_si(dummy, 0);
475 convert_int_assign_scoplib2osl(rl->precision, &rl->m[j+1][k],
476 dummy);
477 SCOPVAL_clear(dummy);
479 else if(k>0 && k<=(nb_output_dims)){ // for output dimentions
480 if( k==(j+2) ) //identification diagonal
482 scoplib_int_t dummy;
483 SCOPVAL_init_set_si(dummy, -1);
484 convert_int_assign_scoplib2osl(rl->precision, &rl->m[j+1][k],
485 dummy);
486 SCOPVAL_clear(dummy);
488 else // non diagonal zeros
490 scoplib_int_t dummy;
491 SCOPVAL_init_set_si(dummy, 0);
492 convert_int_assign_scoplib2osl(rl->precision, &rl->m[j+1][k],
493 dummy);
494 SCOPVAL_clear(dummy);
497 else // input dimensions + parameters + constant
498 convert_int_assign_scoplib2osl(rl->precision, &rl->m[j+1][k],
499 m->p[m_row][k-nb_output_dims]);
502 } // end for each row
504 } // end if(array_has_dims)
505 else{ // zero-dimensional array handling
506 m_row++;
507 }// if(array_has_dims)
511 osl_relation_list_p tmp_rl_list = osl_relation_list_malloc();
512 tmp_rl_list->elt = rl;
513 if(out_rln_list==NULL) {
514 out_rln_list=last_rl_list=tmp_rl_list;
516 else{
517 last_rl_list->next = tmp_rl_list;
518 last_rl_list = last_rl_list->next;
521 } //for num_arrays
523 // free the above allocated arrays
524 if(array_id != NULL)
525 free(array_id);
526 if(array_has_dims != NULL)
527 free(array_has_dims);
528 if(array_dims != NULL)
529 free(array_dims);
531 return out_rln_list;
535 * converts scoplib statement body to osl generic
537 * \param[in] nb_iterators number of iterators for the statement
538 * \param[in] iter an array of iterator-names strings
539 * \param[in] body string containing statement body
540 * \return osl generic encapsulating the statment body
542 osl_generic_p convert_body_scoplib2osl(int nb_iterators, char **iter,
543 char* body){
544 int i=0;
545 if(iter==NULL && body==NULL)
546 return NULL;
548 osl_generic_p out_gen = osl_generic_malloc();
549 osl_body_p out_body = osl_body_malloc();
551 //iterators
552 char** iters_cpy = NULL;
553 OSL_malloc(iters_cpy, char **, sizeof(char *) * (nb_iterators+ 1));
554 iters_cpy[nb_iterators] = NULL;
555 if(iter!=NULL && *iter!=NULL){
556 for(i=0; i< nb_iterators; i++)
557 CONVERTER_strdup(iters_cpy[i], (const char*)iter[i]);
559 out_body->iterators = osl_strings_malloc();
560 out_body->iterators->string = iters_cpy;
562 //expression
563 if(body!=NULL){
564 char* expr_cpy = NULL;
565 OSL_strdup(expr_cpy, body);
566 out_body->expression = osl_strings_encapsulate(expr_cpy);
569 out_gen->data = out_body;
570 out_gen->interface = osl_body_interface();
572 //osl_body_print(stdout, out_body);
573 return out_gen;
579 * this functions converts a scoplib statement to the osl equivalent
581 * \param[in] in_stmt scoplib statement to be converted
582 * \param[in] ctx scoplib context needed to calculate nb_parameters
583 * \return new osl statement
585 osl_statement_p convert_statement_scoplib2osl( scoplib_statement_p in_stmt,
586 scoplib_matrix_p in_ctx){
587 if(in_stmt==NULL)
588 return NULL;
590 //allocate
591 osl_statement_p out_stmt = NULL;
592 osl_statement_p last_stmt = NULL;
593 osl_statement_p tmp_stmt = NULL;
595 scoplib_statement_p s = in_stmt;
596 for(; s; s= s->next){
598 tmp_stmt = osl_statement_malloc();
600 //domain
601 tmp_stmt->domain = convert_domain_scoplib2osl(s->domain, in_ctx);
603 //scattering
604 tmp_stmt->scattering = convert_scattering_scoplib2osl(s->schedule, in_ctx);
606 //access //TODO: make generic append(read) append(write) ?
607 tmp_stmt->access = convert_access_scoplib2osl(s->read, in_ctx, in_stmt,
608 OSL_TYPE_READ);
610 osl_relation_list_p tmp_rl = tmp_stmt->access;
611 for(; tmp_rl && tmp_rl->next; )
612 tmp_rl = tmp_rl->next;
613 if(!tmp_rl){
614 tmp_stmt->access = convert_access_scoplib2osl(s->write, in_ctx, in_stmt,
615 OSL_TYPE_WRITE);
617 else{
618 tmp_rl->next = convert_access_scoplib2osl(s->write, in_ctx, in_stmt,
619 OSL_TYPE_WRITE);
622 //body
623 tmp_stmt->body = convert_body_scoplib2osl(s->nb_iterators, s->iterators,
624 s->body);
626 //usr
627 tmp_stmt->usr = NULL;
629 //next
630 if(out_stmt==NULL){
631 out_stmt=last_stmt=tmp_stmt;
633 else{
634 last_stmt->next = tmp_stmt;
635 last_stmt = last_stmt->next;
640 return out_stmt;
645 * this function tests the equivalence of two osl relation_lists
647 * \param[in] l1 osl relation_list
648 * \param[in] l2 osl relation_list
649 * \return 1 if the two arguments are deemed equal, 0 otherwise
651 int convert_osl_relation_list_equal(osl_relation_list_p l1,
652 osl_relation_list_p l2) {
654 int l1_size = osl_relation_list_count(l1);
655 int l2_size = osl_relation_list_count(l2);
657 if(l1_size != l2_size){
658 CONVERTER_error("relation_list sizes are not the same\n");
659 //return 0;
662 for(; l1; l1 = l1->next){
663 osl_relation_list_p l_tmp = l2;
664 while (l_tmp != NULL) {
666 if (osl_relation_equal(l1->elt, l_tmp->elt))
667 break;
669 l_tmp = l_tmp->next;
671 if(l_tmp==NULL) // relation not found
672 return 0;
675 return 1;
680 * this functions checks the equality of two osl statements
682 * \param[in] s1 list of osl statements
683 * \param[in] s2 list of osl statements
684 * \return 1 if the two arguments are deemed equal, 0 otherwise
686 int convert_osl_statement_equal(osl_statement_p s1, osl_statement_p s2) {
688 if (s1 == s2)
689 return 1;
691 if (((s1->next != NULL) && (s2->next == NULL)) ||
692 ((s1->next == NULL) && (s2->next != NULL))) {
693 CONVERTER_info("number of statements is not the same");
694 return 0;
697 if ((s1->next != NULL) && (s2->next != NULL)) {
698 if (!convert_osl_statement_equal(s1->next, s2->next)) {
699 CONVERTER_info("statements are not the same");
700 return 0;
704 if (!osl_relation_equal(s1->domain, s2->domain)) {
705 CONVERTER_info("statement domains are not the same");
706 osl_relation_print(stdout, s1->domain);
707 osl_relation_print(stdout, s2->domain);
708 return 0;
711 if (!osl_relation_equal(s1->scattering, s2->scattering)) {
712 CONVERTER_info("statement scatterings are not the same");
713 osl_relation_print(stdout, s1->scattering);
714 osl_relation_print(stdout, s2->scattering);
715 return 0;
718 if (!convert_osl_relation_list_equal(s1->access, s2->access)) {
719 CONVERTER_info("statement accesses are not the same");
720 osl_relation_list_print(stdout, s1->access);
721 osl_relation_list_print(stdout, s2->access);
722 return 0;
725 if (!osl_generic_equal(s1->body, s2->body)) {
726 CONVERTER_info("statement bodies are not the same");
727 osl_generic_print(stdout, s1->body);
728 osl_generic_print(stdout, s2->body);
729 return 0;
732 return 1;
737 * this functions checks the equality of two osl scops
739 * \param[in] s1 osl scop
740 * \param[in] s2 osl scop
741 * \return 1 if the two arguments are deemed equal, 0 otherwise
743 int convert_osl_scop_equal(osl_scop_p s1, osl_scop_p s2) {
745 while ((s1 != NULL) && (s2 != NULL)) {
746 if (s1 == s2)
747 return 1;
749 if (s1->version != s2->version) {
750 CONVERTER_info("versions are not the same");
751 return 0;
753 //else
754 // printf("osl_scop versions equal\n");
756 if (strcmp(s1->language, s2->language) != 0) {
757 CONVERTER_info("languages are not the same");
758 return 0;
760 //else
761 // printf("osl_scop language equal\n");
763 if (!osl_relation_equal(s1->context, s2->context)) {
764 CONVERTER_info("contexts are not the same");
765 return 0;
767 //else
768 // printf("osl_scop context equal\n");
770 if (!osl_generic_equal(s1->parameters, s2->parameters)) {
771 CONVERTER_info("parameters are not the same");
772 return 0;
774 //else
775 // printf("osl_scop parameters equal\n");
777 if (!convert_osl_statement_equal(s1->statement, s2->statement)) {
778 CONVERTER_info("statements are not the same");
779 return 0;
781 //else
782 // printf("osl_scop statements equal\n");
784 //TODO: below
785 //if (!osl_interface_equal(s1->registry, s2->registry)) {
786 // CONVERTER_info("registries are not the same");
787 //return 0;
789 //else
790 // printf("osl_scop registry equal\n");
792 //if (!osl_generic_equal(s1->extension, s2->extension)) {
793 // CONVERTER_info("extensions are not the same");
794 //return 0;
796 //else
797 // printf("osl_scop extensions equal\n");
799 s1 = s1->next;
800 s2 = s2->next;
803 if (((s1 == NULL) && (s2 != NULL)) || ((s1 != NULL) && (s2 == NULL)))
804 return 0;
806 return 1;
811 * returns the number of refrences in read/write access until row
813 * \param[in] m scoplib access matrix
814 * \param[in] row number of row to search until (starting from 0)
815 * \return number of references found until 'row'th row
817 static
818 int get_num_refs(scoplib_matrix_p m, int row){
819 if(m==NULL)
820 return -1;
822 int num_ref = 0;
823 int i = 0;
824 for(i=0; i<=row; i++){
825 if( !SCOPVAL_zero_p(m->p[i][0]) )
826 num_ref++;
829 return num_ref;
835 * Read a scoplib dependence from a char_stream
836 * Convert it into osl_dependence
838 * This functions assumes that the statements have already been converted!!
840 * \param[in] str char stream containing the dependence
841 * \param[in] next store the updated char stream after reading the dependence
842 * \param[in] in_scop scop containing dependences to be converted
843 * \param[in] out_scop scop in which converted dependences will be stored
844 * both scops are used to access access related info
845 * \return converted osl dependence
849 static
850 osl_dependence_p convert_candl_dependence_read_one_dep_2(char* str, char** next,
851 scoplib_scop_p in_scop,
852 osl_scop_p out_scop)
854 candl_dependence_p old_dep = candl_dependence_malloc();
855 osl_dependence_p dep = osl_dependence_malloc();
856 char buffer[1024];
858 int i, j, k;
859 int id;
860 int id2;
861 /* # Description of dependence xxx */
862 for (; *str != '\n'; ++str);
863 ++str;
865 /* # type */
866 for (; *str != '\n'; ++str);
867 ++str;
869 /* {RAW,RAR,WAR,WAW} #(type) */
870 for (i = 0; *str != ' '; ++str, ++i)
871 buffer[i] = *str;
872 buffer[i] = '\0';
874 int s_acc_type = -1;
875 int t_acc_type = -1;
876 if (! strcmp(buffer, "RAW")){
877 dep->type = OSL_DEPENDENCE_RAW;
878 old_dep->type = OSL_DEPENDENCE_RAW;
879 s_acc_type = OSL_TYPE_WRITE;
880 t_acc_type = OSL_TYPE_READ;
882 else if (! strcmp(buffer, "RAR")){
883 dep->type = OSL_DEPENDENCE_RAR;
884 old_dep->type = OSL_DEPENDENCE_RAR;
885 s_acc_type = OSL_TYPE_READ;
886 t_acc_type = OSL_TYPE_READ;
888 else if (! strcmp(buffer, "WAR")){
889 dep->type = OSL_DEPENDENCE_WAR;
890 old_dep->type = OSL_DEPENDENCE_WAR;
891 s_acc_type = OSL_TYPE_READ;
892 t_acc_type = OSL_TYPE_WRITE;
894 else if (! strcmp(buffer, "WAW")){
895 dep->type = OSL_DEPENDENCE_WAW;
896 old_dep->type = OSL_DEPENDENCE_WAW;
897 s_acc_type = OSL_TYPE_WRITE;
898 t_acc_type = OSL_TYPE_WRITE;
900 else if (! strcmp(buffer, "RAW_SCALPRIV")){
901 dep->type = OSL_DEPENDENCE_RAW_SCALPRIV;
902 old_dep->type = OSL_DEPENDENCE_RAW_SCALPRIV;
903 s_acc_type = OSL_TYPE_WRITE;
904 t_acc_type = OSL_TYPE_READ;
907 for (; *str != '\n'; ++str);
908 ++str;
911 /* # From statement xxx */
912 for (; *str != '\n'; ++str);
913 ++str;
914 /* stmt-id */
915 for (i = 0; *str != '\n'; ++str, ++i)
916 buffer[i] = *str;
917 ++str;
918 buffer[i] = '\0';
919 id = atoi(buffer);
921 //ASSUMING that stmt sequence remains the same!!!!
922 osl_statement_p s = out_scop->statement;
923 scoplib_statement_p scoplib_s_stmt = in_scop->statement;
924 for (i = 0; i < id; ++i){
925 s=s->next;
926 scoplib_s_stmt = scoplib_s_stmt->next;
928 if(s==NULL)
929 printf("Coundnt find Statement\n");
930 else{
931 dep->stmt_source_ptr = s;
932 dep->label_source = id;
933 old_dep->label_source = id;
937 /* # To statement xxx */
938 for (; *str != '\n'; ++str);
939 ++str;
940 /* stmt-id */
941 for (i = 0; *str != '\n'; ++str, ++i)
942 buffer[i] = *str;
943 ++str;
944 buffer[i] = '\0';
945 id = atoi(buffer);
947 s = out_scop->statement;
948 scoplib_statement_p scoplib_t_stmt = in_scop->statement;
949 for (i = 0; i < id; ++i){
950 s=s->next;
951 scoplib_t_stmt = scoplib_t_stmt->next;
953 if(s==NULL)
954 printf("Coundnt find Statement\n");
955 else{
956 dep->stmt_target_ptr = s;
957 dep->label_target = id;
958 old_dep->label_target = id;
963 /* # Depth */
964 for (; *str != '\n'; ++str);
965 ++str;
966 /* depth */
967 for (i = 0; *str != '\n'; ++str, ++i)
968 buffer[i] = *str;
969 ++str;
970 buffer[i] = '\0';
971 dep->depth = atoi(buffer);
972 old_dep->depth = atoi(buffer);
974 /* # Array id */
975 for (; *str != '\n'; ++str);
976 ++str;
977 /* array-id */
978 for (i = 0; *str != '\n'; ++str, ++i)
979 buffer[i] = *str;
980 ++str;
981 buffer[i] = '\0';
982 id = atoi(buffer);
983 old_dep->array_id = id;
985 /* # src ref */
986 for (; *str != '\n'; ++str);
987 ++str;
988 /* src ref */
989 for (i = 0; *str != '\n'; ++str, ++i)
990 buffer[i] = *str;
991 ++str;
992 buffer[i] = '\0';
993 int src_ref = atoi(buffer);
994 old_dep->ref_source = src_ref;
996 /* # tgt ref */
997 for (; *str != '\n'; ++str);
998 ++str;
999 /* tgt ref */
1000 for (i = 0; *str != '\n'; ++str, ++i)
1001 buffer[i] = *str;
1002 ++str;
1003 buffer[i] = '\0';
1004 int tgt_ref = atoi(buffer);
1005 old_dep->ref_target = tgt_ref;
1008 int precision = out_scop->context->precision;
1009 // source reference
1010 // normally the access list order in converter is:
1011 // read->write->maywrite
1012 int osl_s_ref_index = -1;
1013 int osl_t_ref_index = -1;
1014 if(s_acc_type==OSL_TYPE_READ)
1015 osl_s_ref_index = get_num_refs(scoplib_s_stmt->read,
1016 old_dep->ref_source);
1017 else
1018 osl_s_ref_index = get_num_refs(scoplib_s_stmt->read,
1019 scoplib_s_stmt->read->NbRows-1) +
1020 get_num_refs(scoplib_s_stmt->write,
1021 old_dep->ref_source);
1023 dep->ref_source = osl_s_ref_index-1;
1024 osl_relation_list_p tmp_access = dep->stmt_source_ptr->access;
1025 for(i=0; i< dep->ref_source; i++)
1026 tmp_access = tmp_access->next;
1027 dep->ref_source_access_ptr = tmp_access->elt;
1029 //target reference
1030 // normally the access list order in converter is:
1031 // read->write->maywrite
1032 if(t_acc_type==OSL_TYPE_READ)
1033 osl_t_ref_index = get_num_refs(scoplib_t_stmt->read,
1034 old_dep->ref_target);
1035 else
1036 osl_t_ref_index = get_num_refs(scoplib_t_stmt->read,
1037 scoplib_t_stmt->read->NbRows-1) +
1038 get_num_refs(scoplib_t_stmt->write,
1039 old_dep->ref_target);
1041 dep->ref_target = osl_t_ref_index-1;
1042 tmp_access = dep->stmt_target_ptr->access;
1043 for(i=0; i< dep->ref_target; i++)
1044 tmp_access = tmp_access->next;
1045 dep->ref_target_access_ptr = tmp_access->elt;
1048 /* # Dependence domain */
1049 for (; *str != '\n'; ++str);
1050 ++str;
1052 /* nb-row nb-col */
1053 for (i = 0; *str != ' '; ++str, ++i)
1054 buffer[i] = *str;
1055 ++str;
1056 buffer[i] = '\0';
1057 id = atoi(buffer);
1058 for (i = 0; *str != '\n'; ++str, ++i)
1059 buffer[i] = *str;
1060 ++str;
1061 buffer[i] = '\0';
1062 id2 = atoi(buffer);
1064 // allocate memory for domain
1065 old_dep->domain = scoplib_matrix_malloc(id, id2);
1066 /* Read matrix elements. */
1067 for (j = 0; j < id; ++j)
1069 for (k = 0; k < id2; ++k)
1071 while (*str && *str == ' ')
1072 str++;
1073 for (i = 0; *str != '\n' && *str != ' '; ++str, ++i)
1074 buffer[i] = *str;
1075 buffer[i] = '\0';
1076 ++str;
1077 SCOPVAL_set_si(old_dep->domain->p[j][k], atoi(buffer));
1079 if (*(str - 1) != '\n')
1081 for (; *str != '\n'; ++str);
1082 ++str;
1085 /* Store the next character in the string to be analyzed. */
1086 *next = str;
1090 /* convert the domain */
1091 dep->domain = convert_dep_domain_scoplib2osl( old_dep, in_scop);
1095 /* Compute the system size */
1096 dep->source_nb_output_dims_domain =
1097 dep->stmt_source_ptr->domain->nb_output_dims;
1098 dep->source_nb_output_dims_access =
1099 dep->ref_source_access_ptr->nb_output_dims;
1101 dep->target_nb_output_dims_domain =
1102 dep->stmt_target_ptr->domain->nb_output_dims;
1103 dep->target_nb_output_dims_access =
1104 dep->ref_target_access_ptr->nb_output_dims;
1106 dep->source_nb_local_dims_domain =
1107 dep->stmt_source_ptr->domain->nb_local_dims;
1108 dep->source_nb_local_dims_access =
1109 dep->ref_source_access_ptr->nb_local_dims;
1110 dep->target_nb_local_dims_domain =
1111 dep->stmt_target_ptr->domain->nb_local_dims;
1112 dep->target_nb_local_dims_access =
1113 dep->ref_target_access_ptr->nb_local_dims;
1116 candl_dependence_free(old_dep);
1118 return dep;
1122 * Extract dependence from scoplib_scop tagoptions
1123 * convert them one by one in osl dependences
1124 * encapsulate them into an osl_generic
1126 * ASSUMPTION: 1. Statements have already been converted been scops
1127 * 2. The order of the statements is the same
1129 * \param[in] in_scop scoplib scop containing dependences
1130 * \param[in] out_scop osl scop : needed by dep_read_2()
1131 * \return generic containing list of converted osl dependences
1133 osl_generic_p convert_dep_scoplib2osl(scoplib_scop_p in_scop, osl_scop_p out_scop){
1135 osl_dependence_p first = NULL;
1136 osl_dependence_p currdep = NULL;
1138 if(in_scop == NULL)
1139 return NULL;
1141 //initialize the usr structure with depth, indices, etc.
1142 //the candl_statement_usr struct in statement->usr
1143 candl_statement_usr_init_all(out_scop);
1145 //search for candl tags in in_scop
1147 //below code copied from candl_dependence_read_from_scop()
1148 //candl_scoplib: dependence.c
1150 //search for dependence-polyhedra tags
1151 char* deps = scoplib_scop_tag_content(in_scop,
1152 "<dependence-polyhedra>",
1153 "</dependence-polyhedra>");
1155 //if not found dep tags
1156 if(deps == NULL)
1157 return NULL;
1159 /* Keep the starting address of the array. */
1160 char* base = deps;
1162 int i;
1163 int depcount;
1164 /* Get the number of dependences. */
1165 char buffer_nb[32];
1166 /* # Number of dependences */
1167 for (; *deps != '\n'; ++deps);
1169 ++deps;
1170 for (i = 0; *deps != '\n'; ++i, ++deps)
1171 buffer_nb[i] = *deps;
1172 buffer_nb[i] = '\0';
1173 int nbdeps = atoi (buffer_nb);
1175 char* next;
1177 ++deps;
1178 /* For each of them, read 1 and shift of the read size. */
1179 for (depcount = 0; depcount < nbdeps; ++depcount)
1181 osl_dependence_p adep =
1182 convert_candl_dependence_read_one_dep_2(deps, &next, in_scop, out_scop);
1183 if (first == NULL)
1184 currdep = first = adep;
1185 else
1187 currdep->next = adep;
1188 currdep = currdep->next;
1190 deps = next;
1193 /* Be clean. */
1194 free(base);
1196 osl_generic_p ext = NULL;
1197 if(first!=NULL){
1198 ext = osl_generic_shell(first, osl_dependence_interface());
1200 return ext;
1205 * Translates scoplib_scop to osl_scop
1206 * : pointer to osl_scop if successful
1208 * \param[in] in_scop scoplib scop to convert
1209 * \return new osl scop, NULL if unsuccessful
1211 *TODO: later extend it to scop_linked_list
1213 osl_scop_p convert_scop_scoplib2osl( scoplib_scop_p inscop){
1215 int i=0;
1216 if(inscop==NULL){
1217 CONVERTER_warning("Received NULL scop\n");
1218 return NULL; //
1221 //scop integrety check
1222 //if(){}
1224 //allocate output_scop
1225 osl_scop_p output_scop = NULL;
1226 osl_scop_p tmp_scop = osl_scop_malloc();
1229 //context
1230 if(inscop->context){
1231 tmp_scop->context = convert_matrix_scoplib2osl(inscop->context);
1233 else{
1234 return output_scop; //NULL
1237 //parameters
1238 if(inscop->nb_parameters > 0 && inscop->parameters!=NULL ){
1240 char** params_cpy = NULL;
1241 OSL_malloc(params_cpy, char **,
1242 sizeof(char *) * (inscop->nb_parameters+ 1));
1243 params_cpy[inscop->nb_parameters] = NULL;
1244 for(i=0; i< inscop->nb_parameters; i++){
1245 OSL_strdup(params_cpy[i], inscop->parameters[i]);
1247 osl_strings_p params = osl_strings_malloc();
1248 params->string = params_cpy;
1250 tmp_scop->parameters = osl_generic_malloc();
1251 tmp_scop->parameters->data = params;
1252 tmp_scop->parameters->interface = osl_strings_interface();
1254 else
1255 CONVERTER_warning("No parameters detected\n");
1257 //statement
1258 if(inscop->statement){
1259 tmp_scop->statement = convert_statement_scoplib2osl(inscop->statement,
1260 inscop->context);
1262 else{
1263 CONVERTER_error("NULL statement in inscop\n");
1264 return output_scop; //NULL
1268 //optiontags
1269 //arrays
1270 char* content = scoplib_scop_tag_content (inscop, "<arrays>", "</arrays>");
1271 if(content==NULL)
1272 tmp_scop->extension = NULL;
1273 else{ // create an extension
1274 char* content_cpy = content;
1275 osl_arrays_p arrays = osl_arrays_sread( &content_cpy );
1276 tmp_scop->extension = osl_generic_malloc();
1277 tmp_scop->extension->data = arrays;
1278 tmp_scop->extension->interface = osl_arrays_interface();
1281 if(content!=NULL);
1282 free(content);
1285 //get dependence dependence
1286 osl_generic_p ext = convert_dep_scoplib2osl(inscop, tmp_scop);
1287 ext->next = tmp_scop->extension;
1288 tmp_scop->extension = ext;
1290 output_scop = tmp_scop;
1291 return output_scop;