OpenScop  0.9.0
loop.c
Go to the documentation of this file.
1 
2  /*+-----------------------------------------------------------------**
3  ** OpenScop Library **
4  **-----------------------------------------------------------------**
5  ** extensions/loop.c **
6  **-----------------------------------------------------------------**
7  ** First version: 03/06/2013 **
8  **-----------------------------------------------------------------**
9 
10 
11  *****************************************************************************
12  * OpenScop: Structures and formats for polyhedral tools to talk together *
13  *****************************************************************************
14  * ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__, *
15  * / / / // // // // / / / // // / / // / /|,_, *
16  * / / / // // // // / / / // // / / // / / / /\ *
17  * |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/ \ *
18  * | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\ \ /\ *
19  * | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\ *
20  * | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \ \ *
21  * | P |n| l | = | s | t |=| = |d| = | = | = | | |=| o | | \# \ \ *
22  * | H | | y | | e | o | | = |l| | | = | | | | G | | \ \ \ *
23  * | I | | | | e | | | | | | | | | | | | | \ \ \ *
24  * | T | | | | | | | | | | | | | | | | | \ \ \ *
25  * | E | | | | | | | | | | | | | | | | | \ \ \ *
26  * | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | / \* \ \ *
27  * | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/ \ \ / *
28  * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
29  * *
30  * Copyright (C) 2008 University Paris-Sud 11 and INRIA *
31  * *
32  * (3-clause BSD license) *
33  * Redistribution and use in source and binary forms, with or without *
34  * modification, are permitted provided that the following conditions *
35  * are met: *
36  * *
37  * 1. Redistributions of source code must retain the above copyright notice, *
38  * this list of conditions and the following disclaimer. *
39  * 2. Redistributions in binary form must reproduce the above copyright *
40  * notice, this list of conditions and the following disclaimer in the *
41  * documentation and/or other materials provided with the distribution. *
42  * 3. The name of the author may not be used to endorse or promote products *
43  * derived from this software without specific prior written permission. *
44  * *
45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *
46  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
47  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
48  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *
49  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *
50  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
51  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
52  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
53  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *
54  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
55  * *
56  * OpenScop Library, a library to manipulate OpenScop formats and data *
57  * structures. Written by: *
58  * Cedric Bastoul <Cedric.Bastoul@u-psud.fr> and *
59  * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr> *
60  * *
61  *****************************************************************************/
62 
63 #include <stdlib.h>
64 #include <stdio.h>
65 #include <string.h>
66 #include <ctype.h>
67 
68 #include <osl/macros.h>
69 #include <osl/util.h>
70 #include <osl/strings.h>
71 #include <osl/interface.h>
72 #include <osl/extensions/loop.h>
73 
74 
75 /*+***************************************************************************
76  * Structure display function *
77  *****************************************************************************/
78 
79 
91 void osl_loop_idump(FILE * file, osl_loop_p loop, int level) {
92  int i, j, first = 1, number=1;
93 
94  // Go to the right level.
95  for (j = 0; j < level; j++)
96  fprintf(file, "|\t");
97 
98  if (loop != NULL)
99  fprintf(file, "+-- osl_loop_t\n");
100  else
101  fprintf(file, "+-- NULL loop\n");
102 
103  while (loop != NULL) {
104  // Go to the right level.
105  if (!first) {
106  // Go to the right level.
107  for (j = 0; j < level; j++)
108  fprintf(file, "|\t");
109 
110  fprintf(file, "| osl_loop_t (node %d)\n", number);
111  } else {
112  first = 0;
113  }
114 
115  // A blank line.
116  for (j = 0; j <= level+1; j++)
117  fprintf(file, "|\t");
118  fprintf(file, "\n");
119 
120  // Display the number of names.
121  for (j = 0; j <= level; j++)
122  fprintf(file, "|\t");
123  fprintf(file, "+--iterator: %s\n", loop->iter);
124 
125  for (j = 0; j <= level; j++)
126  fprintf(file, "|\t");
127  fprintf(file, "+--nb_stmts: %d\n", loop->nb_stmts);
128 
129  // Display the id/name.
130  for (j = 0; j <= level; j++)
131  fprintf(file, "|\t");
132  fprintf(file, "+--stmt_ids:");
133  for(i = 0; i < loop->nb_stmts; i++) {
134  // Go to the right level.
135  fprintf(file, "%2d, ", loop->stmt_ids[i]);
136  }
137  fprintf(file, "\n");
138 
139 
140  for (j = 0; j <= level; j++)
141  fprintf(file, "|\t");
142  fprintf(file, "+--private_vars: %s\n", loop->private_vars);
143 
144  for (j = 0; j <= level; j++)
145  fprintf(file, "|\t");
146  fprintf(file, "+--directive: %d\n", loop->directive);
147 
148  loop = loop->next;
149  number++;
150 
151  // Next line.
152  if (loop != NULL) {
153  for (j = 0; j <= level; j++)
154  fprintf(file, "|\t");
155  fprintf(file, "V\n");
156  }
157  }
158 
159  // The last line.
160  for (j = 0; j <= level; j++)
161  fprintf(file, "|\t");
162  fprintf(file, "\n");
163 }
164 
165 
174 void osl_loop_dump(FILE * file, osl_loop_p loop) {
175  osl_loop_idump(file, loop, 0);
176 }
177 
178 
187  int i;
188  int nloop = 0;
189  int high_water_mark = OSL_MAX_STRING;
190  char *string = NULL;
191  char buffer[OSL_MAX_STRING];
192 
193  OSL_malloc(string, char *, high_water_mark * sizeof(char));
194  string[0] = '\0';
195 
196  sprintf(buffer, "# Number of loops\n%d\n",osl_loop_count(loop));
197  osl_util_safe_strcat(&string, buffer, &high_water_mark);
198 
199  while (loop != NULL) {
200  sprintf(buffer, "# ===========================================\n");
201  osl_util_safe_strcat(&string, buffer, &high_water_mark);
202 
203  sprintf(buffer, "# Loop number %d \n", ++nloop);
204  osl_util_safe_strcat(&string, buffer, &high_water_mark);
205 
206  sprintf(buffer, "# Iterator name\n");
207  osl_util_safe_strcat(&string, buffer, &high_water_mark);
208  sprintf(buffer, "%s\n", loop->iter);
209  osl_util_safe_strcat(&string, buffer, &high_water_mark);
210 
211  sprintf(buffer, "# Number of stmts\n");
212  osl_util_safe_strcat(&string, buffer, &high_water_mark);
213  sprintf(buffer, "%d\n", loop->nb_stmts);
214  osl_util_safe_strcat(&string, buffer, &high_water_mark);
215 
216  if (loop->nb_stmts) {
217  sprintf(buffer, "# Statement identifiers\n");
218  osl_util_safe_strcat(&string, buffer, &high_water_mark);
219  }
220  for (i = 0; i < loop->nb_stmts; i++) {
221  sprintf(buffer, "%d\n", loop->stmt_ids[i]);
222  osl_util_safe_strcat(&string, buffer, &high_water_mark);
223  }
224 
225  sprintf(buffer, "# Private variables\n");
226  osl_util_safe_strcat(&string, buffer, &high_water_mark);
227  sprintf(buffer, "%s\n", loop->private_vars);
228  osl_util_safe_strcat(&string, buffer, &high_water_mark);
229 
230  sprintf(buffer, "# Directive\n");
231  osl_util_safe_strcat(&string, buffer, &high_water_mark);
232  sprintf(buffer, "%d\n", loop->directive);
233  osl_util_safe_strcat(&string, buffer, &high_water_mark);
234 
235  loop = loop->next;
236  }
237 
238  OSL_realloc(string, char *, (strlen(string) + 1) * sizeof(char));
239  return string;
240 }
241 
242 
243 /*****************************************************************************
244  * Reading function *
245  *****************************************************************************/
246 
247 
259 osl_loop_p osl_loop_sread(char **input) {
260  int i;
261  int nb_loops;
262  osl_loop_p head;
263  osl_loop_p loop;
264 
265  if (input == NULL) {
266  OSL_debug("no loop optional tag");
267  return NULL;
268  }
269 
270  // Find the number of names provided.
271  nb_loops = osl_util_read_int(NULL, input);
272  if(nb_loops == 0)
273  return NULL;
274 
275  // Allocate the array of id and names.
276  head = loop = osl_loop_malloc();
277 
278  while (nb_loops != 0) {
279 
280  loop->iter = osl_util_read_string(NULL, input);
281  loop->nb_stmts = osl_util_read_int(NULL, input);
282 
283  OSL_malloc(loop->stmt_ids, int *, loop->nb_stmts * sizeof(int));
284  for (i = 0; i < loop->nb_stmts; i++)
285  loop->stmt_ids[i] = osl_util_read_int(NULL, input);
286 
287  loop->private_vars = osl_util_read_line(NULL, input);
288  if (!strcmp(loop->private_vars, "(null)")) {
289  free(loop->private_vars);
290  loop->private_vars=NULL;
291  }
292 
293  loop->directive = osl_util_read_int(NULL, input);
294 
295  nb_loops--;
296  if (nb_loops != 0) {
297  loop->next = osl_loop_malloc ();
298  loop = loop->next;
299  }
300  }
301 
302  return head;
303 }
304 
305 
306 /*+***************************************************************************
307  * Memory allocation/deallocation function *
308  *****************************************************************************/
309 
310 
321  osl_loop_p loop;
322 
323  OSL_malloc(loop, osl_loop_p, sizeof(osl_loop_t));
324  loop->iter = NULL;
325  loop->nb_stmts = 0;
326  loop->stmt_ids = NULL;
327  loop->private_vars = NULL;
328  loop->directive = 0;
329  loop->next = NULL;
330 
331  return loop;
332 }
333 
334 
342 
343  while (loop != NULL) {
344  osl_loop_p tmp = loop;
345 
346  if (loop->iter) free(loop->iter);
347  if (loop->stmt_ids) free(loop->stmt_ids);
348  if (loop->private_vars) free(loop->private_vars);
349 
350  loop = loop->next;
351 
352  free(tmp);
353  }
354 }
355 
356 
357 /*+***************************************************************************
358  * Processing functions *
359  *****************************************************************************/
360 
361 
371  int i;
372  osl_loop_p clone;
373 
374  if (loop == NULL)
375  return NULL;
376 
377  clone = osl_loop_malloc();
378  OSL_strdup(clone->iter, loop->iter);
379  clone->nb_stmts = loop->nb_stmts;
380  OSL_malloc(clone->stmt_ids, int *, loop->nb_stmts * sizeof(int));
381 
382  for (i = 0; i < loop->nb_stmts; i++) {
383  clone->stmt_ids[i] = loop->stmt_ids[i];
384  }
385 
386  clone->directive = loop->directive;
387 
388  if(loop->private_vars != NULL)
389  OSL_strdup(clone->private_vars, loop->private_vars);
390 
391  return clone;
392 }
393 
403  osl_loop_p clone = NULL;
404  osl_loop_p head = NULL;
405 
406  if (loop == NULL)
407  return NULL;
408 
409  while (loop) {
410 
411  if (clone==NULL) {
412  head = clone = osl_loop_clone_one(loop);
413  }
414  else {
415  clone->next = osl_loop_clone_one(loop);
416  clone = clone->next;
417  }
418 
419  loop = loop->next;
420  }
421 
422  return head;
423 }
424 
437  int i, j, found;
438 
439  if (a1 == a2)
440  return 1;
441 
442  if (((a1 == NULL) && (a2 != NULL)) || ((a1 != NULL) && (a2 == NULL))) {
443  //OSL_info("loops are not the same (compare with NULL)");
444  return 0;
445  }
446 
447  // Check whether the number of names is the same.
448  if (a1->nb_stmts != a2->nb_stmts) {
449  //OSL_info("loops are not the same (nb_stmts)");
450  return 0;
451  }
452 
453  if (strcmp(a1->iter, a2->iter)) {
454  //OSL_info("loops are not the same (iter name)");
455  return 0;
456  }
457  // We accept a different order of the names, as long as the identifiers
458  // are the same.
459  for (i = 0; i < a1->nb_stmts; i++) {
460  found = 0;
461  for (j = 0; j < a2->nb_stmts; j++) {
462  if (a1->stmt_ids[i] == a2->stmt_ids[j]) {
463  found = 1;
464  break;
465  }
466  }
467  if (found != 1) {
468  //OSL_info("loop are not the same (stmt ids)");
469  return 0;
470  }
471  }
472 
473  //TODO: necessarily same ???
474  if (a1->private_vars != a2->private_vars) { // NULL check
475  if (strcmp(a1->private_vars, a2->private_vars)) {
476  //OSL_info("loops are not the same (private vars)");
477  return 0;
478  }
479  }
480 
481  //TODO: necessarily same ???
482  if (a1->directive != a2->directive) {
483  //OSL_info("loops are not the same (directive)");
484  return 0;
485  }
486 
487  return 1;
488 }
489 
502  int found = 0;
503 
504  if (a1 == a2)
505  return 1;
506 
507  if (((a1 == NULL) && (a2 != NULL)) || ((a1 != NULL) && (a2 == NULL))) {
508  OSL_info("lists of loops are not the same (compare with NULL)");
509  return 0;
510  }
511 
512  if (osl_loop_count(a1) != osl_loop_count(a2)) {
513  OSL_info("list of loops are not the same");
514  return 0;
515  }
516 
517  while (a1) {
518  found = 0;
519  osl_loop_p temp = a2;
520 
521  while (temp) {
522  if(osl_loop_equal_one(a1, temp)==1){
523  found= 1;
524  break;
525  }
526  temp = temp->next;
527  }
528 
529  if(found!=1){
530  OSL_info("list of loops are not the same");
531  return 0;
532  }
533  a1 = a1->next;
534  }
535 
536  return 1;
537 }
538 
539 
549 
550  OSL_strdup(interface->URI, OSL_URI_LOOP);
551  interface->idump = (osl_idump_f)osl_loop_idump;
552  interface->sprint = (osl_sprint_f)osl_loop_sprint;
553  interface->sread = (osl_sread_f)osl_loop_sread;
554  interface->malloc = (osl_malloc_f)osl_loop_malloc;
555  interface->free = (osl_free_f)osl_loop_free;
556  interface->clone = (osl_clone_f)osl_loop_clone;
557  interface->equal = (osl_equal_f)osl_loop_equal;
558 
559  return interface;
560 }
561 
562 
571 
572  while (*ll != NULL)
573  ll = &(*ll)->next;
574 
575  *ll = loop;
576 }
577 
578 
587  int count = 0;
588  while (ll) {
589  count++;
590  ll = ll->next;
591  }
592 
593  return count;
594 }
char * iter
\0 terminated iterator name
Definition: loop.h:95
void *(* osl_clone_f)(void *)
Definition: interface.h:80
osl_loop_p osl_loop_clone_one(osl_loop_p loop)
Definition: loop.c:370
int osl_loop_equal_one(osl_loop_p a1, osl_loop_p a2)
Definition: loop.c:436
int * stmt_ids
Array of statement identifiers.
Definition: loop.h:97
int directive
the OpenMP directive to implement
Definition: loop.h:99
osl_interface_p osl_interface_malloc()
Definition: interface.c:212
char * osl_loop_sprint(osl_loop_p loop)
Definition: loop.c:186
void osl_loop_dump(FILE *file, osl_loop_p loop)
Definition: loop.c:174
void osl_loop_idump(FILE *file, osl_loop_p loop, int level)
Definition: loop.c:91
void *(* osl_sread_f)(char **)
Definition: interface.h:77
int osl_loop_equal(osl_loop_p a1, osl_loop_p a2)
Definition: loop.c:501
osl_loop_p osl_loop_malloc()
Definition: loop.c:320
void osl_util_safe_strcat(char **dst, char *src, int *hwm)
Definition: util.c:483
struct osl_loop * next
Definition: loop.h:100
Definition: loop.h:94
int osl_loop_count(osl_loop_p ll)
Definition: loop.c:586
void(* osl_idump_f)(FILE *, void *, int)
Definition: interface.h:75
int osl_util_read_int(FILE *file, char **str)
Definition: util.c:140
char *(* osl_sprint_f)(void *)
Definition: interface.h:76
char * osl_util_read_string(FILE *file, char **str)
Definition: util.c:181
char * private_vars
\0 terminated variable names
Definition: loop.h:98
void osl_loop_free(osl_loop_p loop)
Definition: loop.c:341
void *(* osl_malloc_f)()
Definition: interface.h:78
int nb_stmts
Number of statements in the loop.
Definition: loop.h:96
int(* osl_equal_f)(void *, void *)
Definition: interface.h:81
char * osl_util_read_line(FILE *file, char **str)
Definition: util.c:226
osl_loop_p osl_loop_clone(osl_loop_p loop)
Definition: loop.c:402
osl_interface_p osl_loop_interface()
Definition: loop.c:547
osl_loop_p osl_loop_sread(char **input)
Definition: loop.c:259
void osl_loop_add(osl_loop_p loop, osl_loop_p *ll)
Definition: loop.c:570
void(* osl_free_f)(void *)
Definition: interface.h:79