2 // initially copied from Candl
4 /**------ ( ----------------------------------------------------------**
6 **----- / ) --------------------------------------------------------**
7 ** ( * ( dependence.c **
8 **---- \#/ --------------------------------------------------------**
9 ** .-"#'-. First version: september 18th 2003 **
10 **--- |"-.-"| -------------------------------------------------------**
13 ******** | | *************************************************************
14 * CAnDL '-._,-' the Chunky Analyzer for Dependences in Loops (experimental) *
15 ******************************************************************************
17 * Copyright (C) 2003-2008 Cedric Bastoul *
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. *
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 *
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 *
33 * CAnDL, the Chunky Dependence Analyzer *
34 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
36 ******************************************************************************/
39 * \author Cedric Bastoul and Louis-Noel Pouchet
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"
55 #ifdef CANDL_SUPPORTS_ISL
56 # undef Q // Thank you polylib...
58 # include <isl/constraint.h>
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
);
89 /******************************************************************************
90 * Memory Allocation functions *
91 ******************************************************************************/
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
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
;
126 /******************************************************************************
127 * Processing functions *
128 ******************************************************************************/
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
){
143 scoplib_statement_p stmt
= s
;
146 for( ; stmt
; stmt
= stmt
->next
, nstmt
++)
149 int** index_2d_array
= (int**) malloc(nstmt
* sizeof(int*));
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
)
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
;
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. */
179 if (m
->NbRows
!= 2 * stmt_depth
+ 1)
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
]))
188 if (l
% 2 && k
== (l
/ 2) + 1) error
= 1;
191 if ((l
% 2 && k
!= (l
/ 2) + 1) || (! l
% 2)) error
= 1;
197 if (l
% 2 && SCOPVAL_get_si(m
->p
[l
][k
]))
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]);
212 for (k
= j
+ 1; k
< max_loop_depth
; ++k
)
214 for (k
= j
; k
< max_loop_depth
; ++k
)
215 cur_index
[k
] = max
+ (k
- j
) + 1;
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.
239 convert_candl_program_deps_to_string(CandlDependence
* dependence
)
241 CandlDependence
* tmp
= dependence
;
242 int refs
= 0, reft
= 0;
245 int buffer_size
= 2048;
247 char* buffer
= (char*) malloc(buffer_size
* sizeof(char));
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
);
258 for (tmp
= dependence
, nb_deps
= 1; tmp
; tmp
= tmp
->next
, ++nb_deps
)
260 /* Compute the type of the dependence, and the array id
268 type
= "RAW #(flow)";
269 refs
= tmp
->array_id
; //already set outside
270 reft
= tmp
->array_id
;
273 type
= "WAR #(anti)";
274 refs
= tmp
->array_id
;
275 reft
= tmp
->array_id
;
278 type
= "WAW #(output)";
279 refs
= tmp
->array_id
;
280 reft
= tmp
->array_id
;
283 type
= "RAR #(input)";
284 refs
= tmp
->array_id
;
285 reft
= tmp
->array_id
;
287 case CANDL_RAW_SCALPRIV
:
288 type
= "RAW_SCALPRIV #(scalar priv)";
289 refs
= tmp
->array_id
;
290 reft
= tmp
->array_id
;
296 /* Quick consistency check. */
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
);
322 for (k
= 0; k
< szbuff
; ++k
)
323 *(pbuffer
++) = buff
[k
];
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) *
336 CONVERTER_error("Error: memory overflow");
337 buffer
[szbuff
] = '\0';
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
354 void convert_candl_dependence_update_scop_with_deps(scoplib_scop_p scop
,
355 CandlDependence
* dependence
)
360 char* olddeps
= NULL
;
367 int size_olddeps
= 0;
370 start
= stop
= scop
->optiontags
;
371 /* Get the candl tag, if any. */
372 content
= scoplib_scop_tag_content(scop
, "<candl>", "</candl>");
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
382 size
= size_olddeps
= strlen(olddeps
);
383 while (start
&& *start
&& strncmp(start
, olddeps
, size
))
389 size
= strlen(content
);
390 while (start
&& *start
&& strncmp(start
, content
, size
))
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
402 size_newdeps
= newdeps
? strlen(newdeps
) : 0;
404 size_optiontags
= scop
->optiontags
? strlen(scop
->optiontags
) : 0;
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");
415 newopttags
= (char*) malloc((size_newdeps
+ size_optiontags
416 - size_olddeps
+ size
+ 1)
420 if (newopttags
== NULL
)
421 CONVERTER_error("Error: memory overflow");
424 /* Copy the beginning of the options. */
425 for (tmp
= scop
->optiontags
; tmp
!= start
; ++tmp
)
428 //printf("pointer curr, after copy start: %x\n", curr);
429 /* Copy the candl tags, if needed. */
432 strcat(newopttags
, "<candl>\n");
433 curr
+= strlen("<candl>\n");
437 strcat(newopttags
, "<dependence-polyhedra>\n");
438 curr
+= strlen("<dependence-polyhedra>\n");
442 /* Copy the program dependences. */
443 for (tmp
= newdeps
; tmp
&& *tmp
; ++tmp
)
449 /* Copy the candl tags, if needed. */
452 strcat(curr
, "</dependence-polyhedra>\n");
453 curr
+= strlen("</dependence-polyhedra>\n");
457 strcat(curr
, "</candl>\n");
458 curr
+= strlen("</candl>\n");
462 /* Copy the remainder of the options. */
463 for (tmp
= stop
; tmp
&& *tmp
; ++tmp
)
469 if (scop
->optiontags
)
470 free(scop
->optiontags
);
471 scop
->optiontags
= newopttags
;
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
499 void convert_dep_osl2scoplib(osl_scop_p inscop
, scoplib_scop_p outscop
){
501 scoplib_statement_p s
= NULL
;
502 scoplib_statement_p t
= NULL
;
504 if(inscop
==NULL
|| outscop
==NULL
)
507 //look for candl-osl dependencies inscop
508 osl_dependence_p gen_dep
= osl_generic_lookup(inscop
->extension
,
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
534 scoplib_matrix_p array_s
= NULL
; //TODO: scoplib_matrix == pipmatrix??
535 scoplib_matrix_p array_t
= NULL
;
538 switch(gen_dep
->type
){
539 case OSL_DEPENDENCE_RAW
:
540 tmp
->type
= CANDL_RAW
;
543 s_acc_type
= OSL_TYPE_WRITE
;
544 t_acc_type
= OSL_TYPE_READ
;
547 case OSL_DEPENDENCE_RAR
:
548 tmp
->type
= CANDL_RAR
;
551 s_acc_type
= OSL_TYPE_READ
;
552 t_acc_type
= OSL_TYPE_READ
;
555 case OSL_DEPENDENCE_WAR
:
556 tmp
->type
= CANDL_WAR
;
559 s_acc_type
= OSL_TYPE_READ
;
560 t_acc_type
= OSL_TYPE_WRITE
;
563 case OSL_DEPENDENCE_WAW
:
564 tmp
->type
= CANDL_WAW
;
567 s_acc_type
= OSL_TYPE_WRITE
;
568 t_acc_type
= OSL_TYPE_WRITE
;
571 case OSL_DEPENDENCE_RAW_SCALPRIV
:
572 tmp
->type
= CANDL_RAW_SCALPRIV
;
575 s_acc_type
= OSL_TYPE_WRITE
;
576 t_acc_type
= OSL_TYPE_READ
;
580 CONVERTER_error("Unknown type for dependency in scoplib_scop\n");
585 tmp
->depth
= gen_dep
->depth
;
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;
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;
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]);
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;
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;
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");
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
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
;
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)
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
);
730 int osl_constraint
= 0;
731 int scoplib_constraint
= 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
]);
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
++){
770 convert_int_assign_osl2scoplib(&(m
->p
[scoplib_constraint
][0]),
771 in_dep
->domain
->precision
,
772 in_dep
->domain
->m
[osl_constraint
][0]);
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
++;
799 // copy source as well as target access
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
++){
814 osl_t_index
= 1 + nb_output_dims
;
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
++){
841 int isrc_param
= osl_int_get_si(in_dep
->domain
->precision
,
842 in_dep
->domain
->m
[osl_constraint
][osl_index
+j
]);
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
]),
858 SCOPVAL_clear(tgt_param
);
859 SCOPVAL_clear(src_param
);
862 scoplib_constraint
++;
866 // copy access equalities -> not in CANDL-scoplib??
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
878 osl_t_index
= 1 + nb_output_dims
;
880 scoplib_t_index
= slib_ind_target_domain
;
881 for(i
=0; i
< depth
; i
++){
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]);
904 scoplib_constraint
++;
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
){
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]) )
931 //check for zero-dimension array (scalar)
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
){
962 for(i
=0; i
<m
->NbRows
; 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
)
987 scoplib_statement_p stmt
= in_scop
->statement
;
989 for( i
=0; i
< index
; i
++)
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
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");
1019 case CANDL_RAW_SCALPRIV
:
1020 *access_s
= s
->write
;
1021 *access_t
= t
->read
;
1024 *access_s
= s
->read
;
1025 *access_t
= t
->write
;
1028 *access_s
= s
->write
;
1029 *access_t
= t
->write
;
1032 *access_s
= s
->read
;
1033 *access_t
= t
->read
;
1036 CONVERTER_error("Unknown dependence type encountered.\n");
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
){
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
+
1096 osl_relation_p m
= osl_relation_malloc(nrows
, ncols
);
1097 scoplib_matrix_p dom
= in_dep
->domain
;
1100 //calculate certain indexes
1102 int scoplib_t_dom_index
= 1 + s_dom_output_dims
;
1103 int scoplib_param_index
= scoplib_t_dom_index
+ t_dom_output_dims
;
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
1120 // fill in source domain
1121 for(i
=0; i
< stmt_s
->domain
->elt
->NbRows
; i
++){
1122 // copy first column
1123 // copy matrix start
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
]);
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
]);
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"
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
);
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
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
]);
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
]);
1240 long int value
= -1;
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
);
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
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
);
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
]);
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
]);
1319 value
= SCOPVAL_get_si(t_array
->p
[in_dep
->ref_target
][0]);
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],
1326 osl_int_oppose(m
->precision
,
1327 &m
->m
[osl_constraint
][m
->nb_columns
-1],
1328 m
->m
[osl_constraint
][m
->nb_columns
-1]);
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);
1347 if(s_arr_output_dims
== 1) //TODO: add eq counterpart in reverse direction
1348 scoplib_constraint
++;
1350 // fill in precedence constraints
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
]);
1370 convert_int_assign_scoplib2osl(m
->precision
,
1371 &m
->m
[osl_constraint
][m
->nb_columns
-1],
1372 dom
->p
[scoplib_constraint
][dom
->NbColumns
-1]);
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
;