OpenScop  0.9.0
dependence.c
Go to the documentation of this file.
1 
2  /*+-----------------------------------------------------------------**
3  ** OpenScop Library **
4  **-----------------------------------------------------------------**
5  ** extensions/dependence.h **
6  **-----------------------------------------------------------------**
7  ** First version: 02/07/2012 **
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 <osl/macros.h>
67 #include <osl/scop.h>
68 #include <osl/statement.h>
69 #include <osl/relation.h>
70 #include <osl/names.h>
71 #include <osl/util.h>
73 
78 /******************************************************************************
79  * Structure display function *
80  ******************************************************************************/
81 
82 
92 void osl_dependence_idump(FILE* file,
93  osl_dependence_p dependence,
94  int level) {
95  int j, first = 1;
96  osl_statement_p tmp;
97 
98  if (dependence != NULL) { /* Go to the right level. */
99  for (j=0; j<level; j++)
100  fprintf(file, "|\t");
101  fprintf(file, "+-- osl_dependence_p\n");
102  } else {
103  for (j=0; j<level; j++)
104  fprintf(file, "|\t");
105  fprintf(file, "+-- NULL dependence\n");
106  }
107 
108  while (dependence != NULL) {
109  if (!first) { /* Go to the right level. */
110  for (j=0; j<level; j++)
111  fprintf(file, "|\t");
112  fprintf(file, "| osl_dependence_p\n");
113  } else {
114  first = 0;
115  }
116 
117  /* A blank line. */
118  for (j=0; j<=level+1; j++)
119  fprintf(file, "|\t");
120  fprintf(file, "\n");
121 
122  /* Go to the right level and print the type. */
123  for (j=0; j<=level; j++)
124  fprintf(file, "|\t");
125  fprintf(file, "Type: ");
126  switch (dependence->type) {
127  case OSL_UNDEFINED : fprintf(file, "UNSET\n"); break;
128  case OSL_DEPENDENCE_RAW : fprintf(file, "RAW (flow)\n"); break;
129  case OSL_DEPENDENCE_WAR : fprintf(file, "WAR (anti)\n"); break;
130  case OSL_DEPENDENCE_WAW : fprintf(file, "WAW (output)\n"); break;
131  case OSL_DEPENDENCE_RAR : fprintf(file, "RAR (input)\n"); break;
132  case OSL_DEPENDENCE_RAW_SCALPRIV :
133  fprintf(file, "RAW_SCALPRIV (scalar priv)\n"); break;
134  default : fprintf(file, "unknown\n"); break;
135  }
136 
137  /* A blank line. */
138  for (j=0; j<=level+1; j++)
139  fprintf(file, "|\t");
140  fprintf(file, "\n");
141 
142  /* Go to the right level and print the depth. */
143  for (j=0; j<=level; j++)
144  fprintf(file, "|\t");
145  fprintf(file, "Depth: %d\n", dependence->depth);
146 
147  /* A blank line. */
148  for (j=0; j<=level+1; j++)
149  fprintf(file, "|\t");
150  fprintf(file, "\n");
151 
152  /* Ref source and target */
153  for (j=0; j<=level; j++)
154  fprintf(file, "|\t");
155  fprintf(file, "Ref source: %d, Ref target: %d\n",
156  dependence->ref_source, dependence->ref_target);
157 
158  /* A blank line. */
159  for (j=0; j<=level+1; j++)
160  fprintf(file, "|\t");
161  fprintf(file, "\n");
162 
163  /* Print the source statement. */
164  for (j=0; j<=level; j++)
165  fprintf(file, "|\t");
166  fprintf(file, "Statement label: %d\n", dependence->label_source);
167  tmp = dependence->stmt_source_ptr->next;
168  dependence->stmt_source_ptr->next = NULL;
169  osl_statement_idump(file, dependence->stmt_source_ptr, level+1);
170  dependence->stmt_source_ptr->next = tmp;
171 
172  /* Print the target statement. */
173  for (j=0; j<=level; j++)
174  fprintf(file, "|\t");
175  fprintf(file, "Target label: %d\n", dependence->label_target);
176  tmp = dependence->stmt_target_ptr->next;
177  dependence->stmt_target_ptr->next = NULL;
178  osl_statement_idump(file, dependence->stmt_target_ptr, level+1);
179  dependence->stmt_target_ptr->next = tmp;
180 
181  /* Print the dependence polyhedron. */
182  for (j=0; j<=level; j++)
183  fprintf(file, "|\t");
184  fprintf(file, "%d %d %d %d %d %d %d %d\n",
185  dependence->source_nb_output_dims_domain,
186  dependence->source_nb_output_dims_access,
187  dependence->target_nb_output_dims_domain,
188  dependence->target_nb_output_dims_access,
189  dependence->source_nb_local_dims_domain,
190  dependence->source_nb_local_dims_access,
191  dependence->target_nb_local_dims_domain,
192  dependence->target_nb_local_dims_access);
193  osl_relation_idump(file, dependence->domain, level+1);
194 
195  dependence = dependence->next;
196 
197  /* Next line. */
198  if (dependence != NULL) {
199  for (j=0; j<=level; j++)
200  fprintf(file, "|\t");
201  fprintf(file, "V\n");
202  }
203  }
204 
205  /* The last line. */
206  for (j=0; j<=level; j++)
207  fprintf(file, "|\t");
208  fprintf(file, "\n");
209 }
210 
211 
217 void osl_dependence_dump(FILE * file, osl_dependence_p dependence) {
218  osl_dependence_idump(file, dependence, 0);
219 }
220 
221 
226 void osl_dependence_print(FILE *file, osl_dependence_p dependence) {
227  char *string = osl_dependence_sprint(dependence);
228  fprintf(file, "%s\n", string);
229  free(string);
230 }
231 
232 
239 
240  osl_dependence_p tmp = dependence;
241  int nb_deps;
242  int buffer_size = 2048;
243  char* buffer;
244  char buff[2048];
245  char* type;
246  char* pbuffer;
247 
248  OSL_malloc(buffer, char*, buffer_size);
249  buffer[0] = '\0';
250 
251  for (tmp = dependence, nb_deps = 0; tmp; tmp = tmp->next, ++nb_deps)
252  ;
253  snprintf(buff, OSL_MAX_STRING, "# Number of dependences\n%d\n", nb_deps);
254  strcat(buffer, buff);
255 
256  if (nb_deps) {
257  for (tmp = dependence, nb_deps = 1; tmp; tmp = tmp->next, ++nb_deps) {
258 
259  switch (tmp->type) {
260  case OSL_UNDEFINED:
261  type = "UNSET";
262  break;
263  case OSL_DEPENDENCE_RAW:
264  type = "RAW #(flow)";
265  break;
266  case OSL_DEPENDENCE_WAR:
267  type = "WAR #(anti)";
268  break;
269  case OSL_DEPENDENCE_WAW:
270  type = "WAW #(output)";
271  break;
272  case OSL_DEPENDENCE_RAR:
273  type = "RAR #(input)";
274  break;
275  case OSL_DEPENDENCE_RAW_SCALPRIV:
276  type = "RAW_SCALPRIV #(scalar priv)";
277  break;
278  default:
279  exit(1);
280  break;
281  }
282 
283  /* Output dependence information. */
284  snprintf(buff, OSL_MAX_STRING, "# Description of dependence %d\n"
285  "# type\n%s\n"
286  "# From source statement id\n%d\n"
287  "# To target statement id\n%d\n"
288  "# Depth \n%d\n"
289  "# From source access ref\n%d\n"
290  "# To target access ref\n%d\n"
291  "# Dependence domain\n",
292  nb_deps, type,
293  tmp->label_source,
294  tmp->label_target,
295  tmp->depth,
296  tmp->ref_source,
297  tmp->ref_target);
298 
299  osl_util_safe_strcat(&buffer, buff, &buffer_size);
300 
301  /* Output dependence domain. */
302  pbuffer = osl_relation_sprint(tmp->domain);
303  osl_util_safe_strcat(&buffer, pbuffer, &buffer_size);
304  free(pbuffer);
305  }
306  }
307 
308  return buffer;
309 }
310 
311 
316 static
317 osl_dependence_p osl_dependence_read_one_dep(char **input, int precision) {
319  char *buffer;
320 
321  /* Dependence type */
322  buffer = osl_util_read_string(NULL, input);
323  if (! strcmp(buffer, "RAW"))
324  dep->type = OSL_DEPENDENCE_RAW;
325  else if (! strcmp(buffer, "RAR"))
326  dep->type = OSL_DEPENDENCE_RAR;
327  else if (! strcmp(buffer, "WAR"))
328  dep->type = OSL_DEPENDENCE_WAR;
329  else if (! strcmp(buffer, "WAW"))
330  dep->type = OSL_DEPENDENCE_WAW;
331  else if (! strcmp(buffer, "RAW_SCALPRIV"))
332  dep->type = OSL_DEPENDENCE_RAW_SCALPRIV;
333  free(buffer);
334 
335  /* # From source statement xxx */
336  dep->label_source = osl_util_read_int(NULL, input);
337 
338  /* # To target statement xxx */
339  dep->label_target = osl_util_read_int(NULL, input);
340 
341  /* # Depth */
342  dep->depth = osl_util_read_int(NULL, input);
343 
344  /* # From source access ref */
345  dep->ref_source = osl_util_read_int(NULL, input);
346 
347  /* # To target access ref */
348  dep->ref_target = osl_util_read_int(NULL, input);
349 
350  /* Read the osl_relation */
351  dep->domain = osl_relation_psread(input, precision);
352 
353  return dep;
354 }
355 
356 
362  int precision = osl_util_get_precision();
363  return osl_dependence_psread(input, precision);
364 }
365 
366 
371 osl_dependence_p osl_dependence_psread(char **input, int precision) {
372  osl_dependence_p first = NULL;
373  osl_dependence_p currdep = NULL;
374 
375  if (*input == NULL) {
376  OSL_debug("no dependence optional tag");
377  return NULL;
378  }
379 
380  int i;
381  /* Get the number of dependences. */
382  int nbdeps = osl_util_read_int(NULL, input);
383 
384  /* For each of them, read 1 and shift of the read size. */
385  for (i = 0; i < nbdeps; i++) {
386  osl_dependence_p adep = osl_dependence_read_one_dep(input, precision);
387  if (first == NULL) {
388  currdep = first = adep;
389  } else {
390  currdep->next = adep;
391  currdep = currdep->next;
392  }
393  }
394 
395  return first;
396 }
397 
398 
399 /******************************************************************************
400  * Memory deallocation function *
401  ******************************************************************************/
402 
403 
412  osl_dependence_p dependence;
413 
414  /* Memory allocation for the osl_dependence_p structure. */
415  OSL_malloc(dependence, osl_dependence_p, sizeof(osl_dependence_t));
416 
417  /* We set the various fields with default values. */
418  dependence->depth = OSL_UNDEFINED;
419  dependence->type = OSL_UNDEFINED;
420  dependence->label_source = OSL_UNDEFINED;
421  dependence->label_target = OSL_UNDEFINED;
422  dependence->ref_source = OSL_UNDEFINED;
423  dependence->ref_target = OSL_UNDEFINED;
424  dependence->domain = NULL;
425  dependence->next = NULL;
426  dependence->usr = NULL;
427  dependence->source_nb_output_dims_domain = OSL_UNDEFINED;
428  dependence->source_nb_output_dims_access = OSL_UNDEFINED;
429  dependence->target_nb_output_dims_domain = OSL_UNDEFINED;
430  dependence->target_nb_output_dims_access = OSL_UNDEFINED;
431  dependence->source_nb_local_dims_domain = OSL_UNDEFINED;
432  dependence->source_nb_local_dims_access = OSL_UNDEFINED;
433  dependence->target_nb_local_dims_domain = OSL_UNDEFINED;
434  dependence->target_nb_local_dims_access = OSL_UNDEFINED;
435  dependence->ref_source_access_ptr = NULL;
436  dependence->ref_target_access_ptr = NULL;
437  dependence->stmt_source_ptr = NULL;
438  dependence->stmt_target_ptr = NULL;
439 
440  return dependence;
441 }
442 
443 
450  osl_dependence_p next;
451  while (dependence != NULL) {
452  next = dependence->next;
453  osl_relation_free(dependence->domain);
454  free(dependence);
455  dependence = next;
456  }
457 }
458 
459 
460 /******************************************************************************
461  * Processing functions *
462  ******************************************************************************/
463 
464 
474  int first = 1, i = 0;
475  osl_dependence_p clone = NULL, node, previous = NULL;
476 
477  while ((dep != NULL) && ((n == -1) || (i < n))) {
478  node = osl_dependence_malloc();
479  node->stmt_source_ptr = dep->stmt_source_ptr;
480  node->stmt_target_ptr = dep->stmt_target_ptr;
481  node->depth = dep->depth;
482  node->type = dep->type;
483  node->label_source = dep->label_source;
484  node->label_target = dep->label_target;
485  node->ref_source = dep->ref_source;
486  node->ref_target = dep->ref_target;
487  node->domain = osl_relation_clone(dep->domain);
488  node->source_nb_output_dims_domain = dep->source_nb_output_dims_domain;
489  node->source_nb_output_dims_access = dep->source_nb_output_dims_access;
490  node->target_nb_output_dims_domain = dep->target_nb_output_dims_domain;
491  node->target_nb_output_dims_access = dep->target_nb_output_dims_access;
492  node->source_nb_local_dims_domain = dep->source_nb_local_dims_domain;
493  node->source_nb_local_dims_access = dep->source_nb_local_dims_access;
494  node->target_nb_local_dims_domain = dep->target_nb_local_dims_domain;
495  node->target_nb_local_dims_access = dep->target_nb_local_dims_access;
496  node->next = NULL;
497  node->usr = NULL;
498 
499  if (first) {
500  first = 0;
501  clone = node;
502  previous = node;
503  }
504  else {
505  previous->next = node;
506  previous = previous->next;
507  }
508 
509  i++;
510  dep = dep->next;
511  }
512 
513  return clone;
514 }
515 
516 
525  return osl_dependence_nclone(dep, -1);
526 }
527 
528 
539 
540  if (d1 == d2)
541  return 1;
542 
543  if ((d1->next != NULL && d2->next == NULL) ||
544  (d1->next == NULL && d2->next != NULL))
545  return 0;
546 
547  if (d1->next != NULL && d2->next != NULL)
548  if (!osl_dependence_equal(d1->next, d2->next))
549  return 0;
550 
551  if (!osl_relation_equal(d1->domain, d2->domain))
552  return 0;
553 
554  if (d1->label_source != d2->label_source ||
555  d1->label_target != d2->label_target ||
556  d1->ref_source != d2->ref_source ||
557  d1->ref_target != d2->ref_target ||
558  d1->depth != d2->depth ||
559  d1->type != d2->type ||
560 
563 
566 
569 
572 
575 
578 
581 
584  return 0;
585 
586  return 1;
587 }
588 
589 
600  osl_dependence_p* now,
601  osl_dependence_p dependence) {
602  if (dependence != NULL) {
603  if (*start == NULL) {
604  *start = dependence;
605  *now = *start;
606  } else {
607  (*now)->next = dependence;
608  *now = (*now)->next;
609  }
610 
611  while ((*now)->next != NULL)
612  *now = (*now)->next;
613  }
614 }
615 
616 
625  osl_dependence_p dep = deps;
626  int num = 0;
627  while (dep != NULL) {
628  num++;
629  dep = dep->next;
630  }
631  return num;
632 }
633 
634 
643 
644  OSL_strdup(interface->URI, OSL_URI_DEPENDENCE);
645  interface->idump = (osl_idump_f)osl_dependence_idump;
646  interface->sprint = (osl_sprint_f)osl_dependence_sprint;
647  interface->sread = (osl_sread_f)osl_dependence_sread;
648  interface->malloc = (osl_malloc_f)osl_dependence_malloc;
649  interface->free = (osl_free_f)osl_dependence_free;
650  interface->clone = (osl_clone_f)osl_dependence_clone;
651  interface->equal = (osl_equal_f)osl_dependence_equal;
652 
653  return interface;
654 }
osl_dependence_p osl_dependence_malloc()
Definition: dependence.c:411
void osl_relation_free(osl_relation_p relation)
Definition: relation.c:1731
int target_nb_output_dims_access
Definition: dependence.h:151
void osl_dependence_print(FILE *file, osl_dependence_p dependence)
Definition: dependence.c:226
void *(* osl_clone_f)(void *)
Definition: interface.h:80
osl_statement_p stmt_source_ptr
Definition: dependence.h:169
void osl_dependence_add(osl_dependence_p *start, osl_dependence_p *now, osl_dependence_p dependence)
Definition: dependence.c:599
void osl_dependence_free(osl_dependence_p dependence)
Definition: dependence.c:449
int source_nb_local_dims_domain
Definition: dependence.h:153
osl_dependence_p osl_dependence_nclone(osl_dependence_p dep, int n)
Definition: dependence.c:473
osl_interface_p osl_interface_malloc()
Definition: interface.c:212
osl_interface_p osl_dependence_interface()
Definition: dependence.c:641
struct osl_dependence * next
Definition: dependence.h:160
char * osl_relation_sprint(osl_relation_p relation)
Definition: relation.c:1277
int osl_dependence_equal(osl_dependence_p d1, osl_dependence_p d2)
Definition: dependence.c:538
void *(* osl_sread_f)(char **)
Definition: interface.h:77
osl_statement_p stmt_target_ptr
Definition: dependence.h:170
int target_nb_output_dims_domain
Definition: dependence.h:150
osl_dependence_p osl_dependence_psread(char **input, int precision)
Definition: dependence.c:371
void osl_util_safe_strcat(char **dst, char *src, int *hwm)
Definition: util.c:483
int osl_relation_equal(osl_relation_p r1, osl_relation_p r2)
Definition: relation.c:2435
void osl_relation_idump(FILE *file, osl_relation_p relation, int level)
Definition: relation.c:164
int target_nb_local_dims_access
Definition: dependence.h:156
int osl_util_get_precision()
Definition: util.c:518
osl_dependence_p osl_dependence_clone(osl_dependence_p dep)
Definition: dependence.c:524
void(* osl_idump_f)(FILE *, void *, int)
Definition: interface.h:75
int osl_nb_dependences(osl_dependence_p deps)
Definition: dependence.c:624
int osl_util_read_int(FILE *file, char **str)
Definition: util.c:140
int target_nb_local_dims_domain
Definition: dependence.h:155
char *(* osl_sprint_f)(void *)
Definition: interface.h:76
char * osl_util_read_string(FILE *file, char **str)
Definition: util.c:181
osl_relation_p ref_source_access_ptr
Definition: dependence.h:166
void osl_dependence_dump(FILE *file, osl_dependence_p dependence)
Definition: dependence.c:217
osl_relation_p osl_relation_clone(osl_relation_p relation)
Definition: relation.c:1863
void *(* osl_malloc_f)()
Definition: interface.h:78
int source_nb_output_dims_access
Definition: dependence.h:148
char * osl_dependence_sprint(osl_dependence_p dependence)
Definition: dependence.c:238
int(* osl_equal_f)(void *, void *)
Definition: interface.h:81
int source_nb_local_dims_access
Definition: dependence.h:154
osl_relation_p osl_relation_psread(char **input, int precision)
Definition: relation.c:1475
osl_relation_p ref_target_access_ptr
Definition: dependence.h:167
osl_relation_p domain
Definition: dependence.h:143
void osl_statement_idump(FILE *file, osl_statement_p statement, int level)
Definition: statement.c:96
int source_nb_output_dims_domain
Definition: dependence.h:147
static osl_dependence_p osl_dependence_read_one_dep(char **input, int precision)
Definition: dependence.c:317
struct osl_statement * next
Definition: statement.h:95
void(* osl_free_f)(void *)
Definition: interface.h:79
void osl_dependence_idump(FILE *file, osl_dependence_p dependence, int level)
Definition: dependence.c:92
osl_dependence_p osl_dependence_sread(char **input)
Definition: dependence.c:361