Clan  0.8.1
domain.c
Go to the documentation of this file.
1 
2  /*+------- <| --------------------------------------------------------**
3  ** A Clan **
4  **--- /.\ -----------------------------------------------------**
5  ** <| [""M# domain.c **
6  **- A | # -----------------------------------------------------**
7  ** /.\ [""M# First version: 26/09/2014 **
8  **- [""M# | # U"U#U -----------------------------------------------**
9  | # | # \ .:/
10  | # | #___| #
11  ****** | "--' .-" ******************************************************
12  * |"-"-"-"-"-#-#-## Clan : the Chunky Loop Analyzer (experimental) *
13  **** | # ## ###### *****************************************************
14  * \ .::::'/ *
15  * \ ::::'/ Copyright (C) 2008 University Paris-Sud 11 *
16  * :8a| # # ## *
17  * ::88a ### This is free software; you can redistribute it *
18  * ::::888a 8a ##::. and/or modify it under the terms of the GNU Lesser *
19  * ::::::::888a88a[]::: General Public License as published by the Free *
20  *::8:::::::::SUNDOGa8a::. Software Foundation, either version 2.1 of the *
21  *::::::::8::::888:Y8888:: License, or (at your option) any later version. *
22  *::::':::88::::888::Y88a::::::::::::... *
23  *::'::.. . ..... .. ... . *
24  * This software is distributed in the hope that it will be useful, but *
25  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
26  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
27  * for more details. *
28  * *
29  * You should have received a copy of the GNU Lesser General Public License *
30  * along with software; if not, write to the Free Software Foundation, Inc., *
31  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
32  * *
33  * Clan, the Chunky Loop Analyzer *
34  * Written by Cedric Bastoul, Cedric.Bastoul@u-psud.fr *
35  * *
36  ******************************************************************************/
37 
38 
39 #include <stdlib.h>
40 #include <stdio.h>
41 
42 #include <osl/macros.h>
43 #include <osl/relation_list.h>
44 #include <clan/macros.h>
45 #include <clan/relation.h>
46 #include <clan/relation_list.h>
47 #include <clan/domain.h>
48 #include <clan/vector.h>
49 
50 
51 /*+***************************************************************************
52  * Structure display function *
53  *****************************************************************************/
54 
55 
63 void clan_domain_idump(FILE* file, clan_domain_p domain, int level) {
64  int j, first = 1;
65 
66  // Go to the right level.
67  for (j = 0; j < level; j++)
68  fprintf(file,"|\t");
69 
70  if (domain != NULL)
71  fprintf(file, "+-- clan_domain_t\n");
72  else
73  fprintf(file, "+-- NULL clan_domain_t\n");
74 
75  while (domain != NULL) {
76  if (!first) {
77  // Go to the right level.
78  for (j = 0; j < level; j++)
79  fprintf(file, "|\t");
80  fprintf(file, "| clan_domain_t\n");
81  }
82  else
83  first = 0;
84 
85  // A blank line.
86  for (j = 0; j <= level + 1; j++)
87  fprintf(file, "|\t");
88  fprintf(file, "\n");
89 
90  // Print a set of constraint sets (a relation list).
91  osl_relation_list_idump(file, domain->constraints, level + 1);
92 
93  domain = domain->next;
94 
95  // Next line.
96  if (domain != NULL) {
97  for (j = 0; j <= level; j++)
98  fprintf(file, "|\t");
99  fprintf(file, "V\n");
100  }
101  }
102 
103  // The last line.
104  for (j = 0; j <= level; j++)
105  fprintf(file, "|\t");
106  fprintf(file, "\n");
107 }
108 
109 
117 void clan_domain_dump(FILE* file, clan_domain_p list) {
118  clan_domain_idump(file, list, 0);
119 }
120 
121 
122 /*+***************************************************************************
123  * Memory allocation/deallocation function *
124  *****************************************************************************/
125 
126 
135  clan_domain_p res;
136 
137  OSL_malloc(res, clan_domain_p, sizeof(clan_domain_t));
138  res->constraints = NULL;
139  res->next = NULL;
140 
141  return res;
142 }
143 
144 
152  clan_domain_p tmp;
153 
154  if (list == NULL)
155  return;
156 
157  while (list != NULL) {
158  osl_relation_list_free(list->constraints);
159  tmp = list->next;
160  free(list);
161  list = tmp;
162  }
163 }
164 
165 
166 /*+****************************************************************************
167  * Processing functions *
168  ******************************************************************************/
169 
170 
179  clan_domain_p clone = NULL, node, previous = NULL;
180  int first = 1;
181 
182  while (list != NULL) {
183  node = clan_domain_malloc();
184  node->constraints = osl_relation_list_clone(list->constraints);
185 
186  if (first) {
187  first = 0;
188  clone = node;
189  previous = node;
190  }
191  else {
192  previous->next = node;
193  previous = previous->next;
194  }
195 
196  list = list->next;
197  }
198 
199  return clone;
200 }
201 
202 
212  if (node != NULL) {
213  node->next = *head;
214  *head = node;
215  }
216 }
217 
218 
228  clan_domain_p top = NULL;
229 
230  if (*head != NULL) {
231  top = *head;
232  *head = (*head)->next;
233  top->next = NULL;
234  }
235 
236  return top;
237 }
238 
239 
248  clan_domain_p top = clan_domain_pop(head);
250  clan_domain_push(head, top);
251 }
252 
253 
264  clan_domain_p top = clan_domain_pop(head);
265  clan_domain_free(top);
266 }
267 
268 
276 void clan_domain_and(clan_domain_p domain, osl_relation_p new_constraints) {
277  osl_relation_list_p base_constraints = domain->constraints;
278 
279  while (base_constraints != NULL) {
280  clan_relation_and(base_constraints->elt, new_constraints);
281  base_constraints = base_constraints->next;
282  }
283 }
284 
293 void clan_domain_stride(clan_domain_p domain, int depth, int stride) {
294  osl_relation_list_p base_constraints = domain->constraints;
295  osl_relation_p stride_constraints;
296 
297  if ((stride != 1) && (stride != -1)) {
298  while (base_constraints != NULL) {
299  stride_constraints = clan_relation_stride(base_constraints->elt,
300  depth, stride);
301  osl_relation_free(base_constraints->elt);
302  domain->constraints->elt = stride_constraints;
303  base_constraints = base_constraints->next;
304  }
305  }
306 }
307 
308 
321  int depth,
322  clan_symbol_p iterator,
323  osl_relation_p initialization,
324  osl_relation_p condition,
325  int stride,
326  clan_options_p options) {
327  osl_vector_p iterator_term;
328  osl_relation_p iterator_relation;
329  osl_relation_p init_constraints;
330 
331  // Generate the set of constraints contributed by the initialization
332  // (nb: it could not be done before because we need to know the stride).
333  iterator_term = clan_vector_term(iterator, 0, NULL, options->precision);
334  osl_int_set_si(options->precision, &iterator_term->v[depth], 1);
335  iterator_relation = osl_relation_from_vector(iterator_term);
336  if (stride > 0) {
337  init_constraints = clan_relation_greater(iterator_relation,
338  initialization, 0);
339  } else {
340  init_constraints = clan_relation_greater(initialization,
341  iterator_relation, 0);
342  }
343  osl_vector_free(iterator_term);
344  osl_relation_free(iterator_relation);
345 
346  // Add the contribution of the initialization to the current domain.
347  clan_domain_and(domain, init_constraints);
348 
349  // Add the contribution of the condition to the current domain.
350  if (!options->noloopcontext)
351  clan_relation_loop_context(condition, init_constraints, depth);
352  clan_domain_and(domain, condition);
353 
354  // Add the contribution of the stride to the current domain.
355  clan_domain_stride(domain, depth, stride);
356 
357  osl_relation_free(init_constraints);
358 }
359 
360 
373  int depth,
374  clan_symbol_p iterator,
375  osl_relation_list_p initialization,
376  osl_relation_list_p condition,
377  int* stride,
378  clan_options_p options) {
379  int i;
380  int nb_indices = clan_relation_list_nb_elements(initialization);
381  int nb_constraint_sets = clan_relation_list_nb_elements(domain->constraints);
382  osl_relation_list_p base, new = NULL;
383  clan_domain_p shell = NULL;
384 
385  // Three possible cases:
386  // 1. the number of constraint sets in the domain is 1 ("first xfor"),
387  // then we duplicate the constraint sets to match the number of xfor
388  // indices, then each constraint set receives the contribution of the
389  // corresponding xfor index,
390  // 2. the number of constraints sets in the domain is equal to
391  // the number of xfor indices, then each constraint set
392  // receives the contribution of the corresponding xfor index,
393  // 3. an error is reported (this should be checked in the parser for
394  // reporting through yyerror).
395 
396  if (nb_constraint_sets == 1) {
397  for (i = 0; i < nb_indices - 1; i++) {
398  osl_relation_list_dup(&domain->constraints);
399  }
400  } else if (nb_constraint_sets != nb_indices) {
401  CLAN_error("incorrect number of indices in an xfor loop");
402  }
403 
404  // -1. Prepare a domain "shell" to process the xfor indices one by one.
405  shell = clan_domain_malloc();
406  shell->constraints = osl_relation_list_malloc();
407  base = domain->constraints;
408  // -2. For each xfor index
409  for (i = 0; i < nb_indices; i++) {
410  // -2.1 Put the corresponding base constraints in the domain shell.
411  shell->constraints->elt = osl_relation_clone(base->elt);
412  // -2.2 Apply the contribution of the loop to it.
413  clan_domain_for(shell, depth, iterator, initialization->elt,
414  condition->elt, stride[i], options);
415  // -2.3 Add the final constraint set to a new list.
416  osl_relation_list_add(&new, shell->constraints);
417  // -2.4 Prepare the variables to process the next xfor index.
418  iterator = iterator->next;
419  initialization = initialization->next;
420  condition = condition->next;
421  shell->constraints = osl_relation_list_malloc();
422  base = base->next;
423  }
424  // -3. Replace the original set of constraint set with the new one.
425  osl_relation_list_free(domain->constraints);
426  domain->constraints = new;
427 
428  clan_domain_free(shell);
429 }
osl_vector_p clan_vector_term(clan_symbol_p symbol, int coefficient, char *identifier, int precision)
Definition: vector.c:67
clan_domain_p clan_domain_clone(clan_domain_p list)
Definition: domain.c:178
osl_relation_p clan_relation_greater(osl_relation_p min, osl_relation_p max, int strict)
Definition: relation.c:332
void clan_domain_dup(clan_domain_p *head)
Definition: domain.c:247
osl_relation_p clan_relation_stride(osl_relation_p r, int depth, int stride)
Definition: relation.c:788
struct clan_symbol * next
Definition: symbol.h:60
void clan_domain_idump(FILE *file, clan_domain_p domain, int level)
Definition: domain.c:63
clan_domain_p clan_domain_pop(clan_domain_p *head)
Definition: domain.c:227
void clan_domain_stride(clan_domain_p domain, int depth, int stride)
Definition: domain.c:293
void clan_relation_and(osl_relation_p dest, osl_relation_p src)
Definition: relation.c:580
void clan_domain_push(clan_domain_p *head, clan_domain_p node)
Definition: domain.c:211
void clan_domain_free(clan_domain_p list)
Definition: domain.c:151
void clan_domain_drop(clan_domain_p *head)
Definition: domain.c:263
struct clan_domain * next
Definition: domain.h:61
void clan_domain_and(clan_domain_p domain, osl_relation_p new_constraints)
Definition: domain.c:276
int noloopcontext
Definition: options.h:67
void clan_domain_dump(FILE *file, clan_domain_p list)
Definition: domain.c:117
clan_domain_p clan_domain_malloc()
Definition: domain.c:134
void clan_relation_loop_context(osl_relation_p condition, osl_relation_p initialization, int depth)
Definition: relation.c:1162
struct osl_relation_list * constraints
Definition: domain.h:60
void clan_domain_xfor(clan_domain_p domain, int depth, clan_symbol_p iterator, osl_relation_list_p initialization, osl_relation_list_p condition, int *stride, clan_options_p options)
Definition: domain.c:372
int precision
Definition: options.h:65
void clan_domain_for(clan_domain_p domain, int depth, clan_symbol_p iterator, osl_relation_p initialization, osl_relation_p condition, int stride, clan_options_p options)
Definition: domain.c:320
int clan_relation_list_nb_elements(osl_relation_list_p list)