PIPS
claire_prettyprinter.c
Go to the documentation of this file.
1 /*
2 
3  $Id: claire_prettyprinter.c 23262 2016-11-02 07:55:48Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 // do not compile experimental phase if not required
26 #include "phases.h"
27 #ifdef BUILDER_PRINT_CLAIRE_CODE
28 
29 #ifdef HAVE_CONFIG_H
30  #include "pips_config.h"
31 #endif
32 /*
33 
34  Try to prettyprint the RI in CLAIRE.
35  Very basic at the time.
36 
37  print_claire_code > MODULE.claire_printed_file
38  < PROGRAM.entities
39  < MODULE.code
40 
41 */
42 
43 #define DEBUG_CLAIRE 1
44 
45 #include <stdio.h>
46 #include <ctype.h>
47 
48 #include "genC.h"
49 #include "linear.h"
50 
51 #include "misc.h"
52 #include "pipsdbm.h"
53 
54 #include "ri.h"
55 #include "effects.h"
56 
57 #include "ri-util.h"
58 #include "effects-util.h"
59 #include "text-util.h"
60 #include "prettyprint.h"
61 
62 #include "effects-convex.h"
63 #include "effects-generic.h"
64 #include "complexity_ri.h"
65 #include "complexity.h"
66 
67 #define COMMA ","
68 #define EMPTY ""
69 #define NL "\n"
70 #define TAB " "
71 #define SEMICOLON ";" NL
72 #define SPACE " "
73 
74 #define OPENBRACKET "["
75 #define CLOSEBRACKET "]"
76 
77 #define OPENPAREN "("
78 #define CLOSEPAREN ")"
79 
80 #define OPENBRACE "{"
81 #define CLOSEBRACE "}"
82 
83 #define SHARPDEF "#define"
84 #define COMMENT "//" SPACE
85 #define QUOTE "\""
86 
87 
88 #define CLAIRE_TASK_PREFIX "T_"
89 #define CLAIRE_MOTIF_PREFIX "M_"
90 #define CLAIRE_ARRAY_PREFIX "A_"
91 
92 #define CLAIRE_RL NL,TAB,TAB
93 
94 /* array containing extern loop indices names */
96 /* array containing intern loop indices (name : "M_") */
98 /* array containing extern upperbounds */
100 /* array containing intern upperbounds */
102 /* array containing the tasks names*/
103 static gen_array_t tasks_names;
104 
105 static const char* global_module_name;
106 
107 /**************************************************************** MISC UTILS */
108 
109 #define current_module_is_a_function() \
110  (entity_function_p(get_current_module_entity()))
111 
112 static bool variable_p(entity e)
113 {
114  storage s = entity_storage(e);
115  return type_variable_p(entity_type(e)) &&
116  (storage_ram_p(s) || storage_return_p(s));
117 }
118 
119 
120 #define RESULT_NAME "result"
121 static string claire_entity_local_name(entity var)
122 {
123  const char* name;
124 
126  var != get_current_module_entity() &&
129  name = RESULT_NAME;
130  else
131  {
132  name = entity_local_name(var);
133 
134  /* Delete all the prefixes */
135 
136  if (strstr(name,STRUCT_PREFIX) != NULL)
137  name = strstr(name,STRUCT_PREFIX) + 1;
138  if (strstr(name,UNION_PREFIX) != NULL)
139  name = strstr(name,UNION_PREFIX) + 1;
140  if (strstr(name,ENUM_PREFIX) != NULL)
141  name = strstr(name,ENUM_PREFIX) + 1;
142  if (strstr(name,TYPEDEF_PREFIX) != NULL)
143  name = strstr(name,TYPEDEF_PREFIX) + 1;
144  if (strstr(name,MEMBER_SEP_STRING) != NULL)
145  name = strstr(name,MEMBER_SEP_STRING) + 1;
146  }
147 
148  /* switch to upper cases... */
149  char * rname = strupper(strdup(name),name);
150 
151  return rname;
152 }
153 
154 
155 /************************************************************** DECLARATIONS */
156 
157 /*
158  integer a(n,m) -> int a[m][n];
159  parameter (n=4) -> #define n 4
160  */
161 
162 
163 /* Code duplicated from Newgen build.c */
164 /* forward declaration */
165 static string claire_expression(expression);
166 
167 /* Attention with Fortran: the indices are reversed. */
168 static string claire_reference_with_explicit_motif(reference r)
169 {
170  string result = strdup(EMPTY), old, svar;
171  MAP(EXPRESSION, e,
172  {
173  string s = strdup(claire_expression(e));
174 
175  old = result;
176  result = strdup(concatenate(old, OPENBRACKET, s, CLOSEBRACKET, NULL));
177  free(old);
178  free(s);
179  }, reference_indices(r));
180 
181  old = result;
182  svar = claire_entity_local_name(reference_variable(r));
183  result = strdup(concatenate(svar, old, NULL));
184  free(old);
185  free(svar);
186  return result;
187 }
188 
189 static string claire_expression(expression e)
190 {
191  string result = string_undefined;
192  syntax s = expression_syntax(e);
193 
194  switch (syntax_tag(s))
195  {
196  case is_syntax_reference:
197  result = claire_reference_with_explicit_motif(syntax_reference(s));
198  break;
199  case is_syntax_call: {
200  value ev = EvalExpression(e);
201  constant ec = value_constant(ev);
202  int eiv = 0;
203 
204  if(!value_constant_p(ev)) {
205  pips_user_error("Constant expected for CLAIRE loop bounds.\n");
206  }
207  if(!constant_int_p(ec)) {
208  pips_user_error("Integer constant expected for CLAIRE loop bounds.\n");
209  }
210  eiv = constant_int(ec);
211  result = strdup(i2a(eiv));
212 
213 
214  break;
215  }
216  default:
217  pips_internal_error("unexpected syntax tag");
218  }
219  return result;
220 }
221 
222 static gen_array_t array_names;
223 static gen_array_t array_dims;
224 
225 #define ITEM_NOT_IN_ARRAY -1
226 
227 static int gen_array_index(gen_array_t ar, string item){
228  int i;
229  for(i = 0; i < (int) gen_array_nitems(ar); i++){
230  if(gen_array_item(ar, i) != NULL){
231  if(same_string_p(item, *((string *)(gen_array_item(ar, i))))){
232  return i;
233  }
234  }
235  }
236  return ITEM_NOT_IN_ARRAY;
237 }
238 
239 static string claire_dim_string(list ldim, string name)
240 {
241  string result = "";
242  int nbdim = 0;
243  string origins = "origins = list<integer>(";
244  string dimensions = "dimSizes = list<integer>(";
245  string deuxpoints = " :: ";
246  string data_array = "DATA_ARRAY(";
247  string data_decl = "name = symbol!(";
248  string dimstring = "dim = ";
249  string datatype = "dataType = INTEGER)";
250  string name4p = name;
251  string * namep = malloc(sizeof(string));
252  int * nbdimptr = malloc(sizeof(int));
253  *namep = name4p;
254  if (ldim)
255  {
256 
257  result = strdup(concatenate(name, deuxpoints, data_array, data_decl, QUOTE, name, QUOTE, CLOSEPAREN, COMMA, NL, NULL));
258  result = strdup(concatenate(result, TAB, dimstring, NULL));
259  MAP(DIMENSION, dim, {
260  expression elow = dimension_lower(dim);
261  expression eup = dimension_upper(dim);
262 
263  intptr_t low;
264  intptr_t up;
265  nbdim++;
266  if (expression_integer_value(elow, &low)){
267  if(nbdim != 1)
268  origins = strdup(concatenate(origins, COMMA ,int2a(low), NULL));
269  else
270  origins = strdup(concatenate(origins, int2a(low), NULL));
271  }
272  else pips_user_error("Array origins must be integer\n");
273 
274  if (expression_integer_value(eup, &up)){
275  if(nbdim != 1)
276  dimensions = strdup(concatenate(dimensions, COMMA ,int2a(up-low+1), NULL));
277  else
278  dimensions = strdup(concatenate(dimensions, int2a(up-low+1), NULL));
279  }
280  else pips_user_error("Array dimensions must be integer\n");
281  }, ldim);
282  *nbdimptr = nbdim;
283  gen_array_append(array_dims, nbdimptr);
285  result = strdup(concatenate(result, int2a(nbdim), COMMA, NL, NULL));
286  result = strdup(concatenate(result, TAB, origins, CLOSEPAREN, COMMA, NL, NULL));
287  result = strdup(concatenate(result, TAB, dimensions, CLOSEPAREN, COMMA, NL, NULL));
288  result = strdup(concatenate(result, TAB, datatype, NL, NL, NULL));
289  }
290  return result;
291 }
292 
293 static string this_entity_clairedeclaration(entity var)
294 {
295  string result = strdup("");
296  string name = strdup(concatenate("A_", entity_local_name(var), NULL));
297  type t = entity_type(var);
298  pips_debug(2,"Entity name : %s\n",entity_name(var));
299  /* Many possible combinations */
300 
301  if (strstr(name,TYPEDEF_PREFIX) != NULL)
302  pips_user_error("Structs not supported\n");
303 
304  switch (type_tag(t)) {
305  case is_type_variable:
306  {
307  variable v = type_variable(t);
308  string sd;
309  sd = strdup(claire_dim_string(variable_dimensions(v), name));
310 
311  result = strdup(concatenate(result, sd, NULL));
312  break;
313  }
314  case is_type_struct:
315  {
316  pips_user_error("Struct not allowed\n");
317  break;
318  }
319  case is_type_union:
320  {
321  pips_user_error("Union not allowed\n");
322  break;
323  }
324  case is_type_enum:
325  {
326  pips_user_error("Enum not allowed\n");
327  break;
328  }
329  default:
330  pips_user_error("Something not allowed here\n");
331  }
332 
333  return result;
334 }
335 
336 static string
337 claire_declarations_with_explicit_motif(entity module,
338  bool (*consider_this_entity)(entity),
339  string separator,
340  bool lastsep)
341 {
342  string result = strdup("");
343  code c;
344  bool first = true;
345 
346  pips_assert("it is a code", value_code_p(entity_initial(module)));
347 
349  MAP(ENTITY, var,
350  {
351  debug(2, "\n Prettyprinter declaration for variable :",claire_entity_local_name(var));
352  if (consider_this_entity(var))
353  {
354  string old = strdup(result);
355  string svar = strdup(this_entity_clairedeclaration(var));
356  result = strdup(concatenate(old, !first && !lastsep? separator: "",
357  svar, lastsep? separator: "", NULL));
358  free(old);
359  free(svar);
360  first = false;
361  }
362  },code_declarations(c));
363  return result;
364 }
365 
366 static string claire_array_in_task(reference r, bool first, int task_number);
367 
368 static string claire_call_from_assignation(call c, int task_number, bool * input_provided){
369  /* All arguments of this call are in Rmode (inputs of the task) */
370  /* This function is called recursively */
372  syntax syn;
373  string result = "";
374 
375  MAP(EXPRESSION, expr, {
376  syn = expression_syntax(expr);
377  switch(syntax_tag(syn)){
378  case is_syntax_call:{
379  result = strdup(concatenate(result, claire_call_from_assignation(syntax_call(syn), task_number, input_provided), NULL));
380  break;
381  }
382  case is_syntax_reference:{
384  string varname = strdup(concatenate("A_", claire_entity_local_name(reference_variable(ref)), NULL));
386  result = strdup(concatenate(result, claire_array_in_task(ref, false, task_number), NULL));
387  *input_provided = true;
388  }
389 
390 
391  break;
392  }
393  default:{
394  pips_user_error("only call and references allowed here\n");
395  }
396  }
397  }, arguments);
398  return result;
399 }
400 
401 static void claire_call_from_indice(call c, string * offset_array, string paving_array[], string fitting_array[]){
402  entity called = call_function(c);
403  string funname = claire_entity_local_name(called);
405  syntax args[2];
406  int i = 0;
407  int iterator_nr;
408  if(gen_length(arguments)==2){
409  if(same_string_p(funname, "+") || same_string_p(funname, "-") || same_string_p(funname, "*")){
410  MAP(EXPRESSION, arg, {
411  args[i] = expression_syntax(arg);
412  i++;
413  }, arguments);
414 
415 
416  if(same_string_p(funname, "+")){
417  if(syntax_tag(args[0]) == is_syntax_call){
418  claire_call_from_indice(syntax_call(args[0]), offset_array, paving_array, fitting_array);
419  }
420  if(syntax_tag(args[1]) == is_syntax_call){
421  claire_call_from_indice(syntax_call(args[1]), offset_array, paving_array, fitting_array);
422  }
423  if(syntax_tag(args[0]) == is_syntax_reference){
424  reference ref = syntax_reference(args[0]);
425  if((iterator_nr = gen_array_index(extern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
426  paving_array[iterator_nr] = strdup("1");
427  }
428  else if((iterator_nr = gen_array_index(intern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
429  fitting_array[iterator_nr] = strdup("1");
430  }
431  }
432  if(syntax_tag(args[1]) == is_syntax_reference){
433  reference ref = syntax_reference(args[1]);
434  if((iterator_nr = gen_array_index(extern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
435  paving_array[iterator_nr] = strdup("1");
436  }
437  else if((iterator_nr = gen_array_index(intern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
438  fitting_array[iterator_nr] = strdup("1");
439  }
440  }
441  }
442  else if(same_string_p(funname, "-")){
443  if(syntax_tag(args[1]) == is_syntax_call && gen_length(call_arguments(syntax_call(args[1])))==0){
444  if(syntax_tag(args[0]) == is_syntax_reference){
445  reference ref = syntax_reference(args[0]);
446  if((iterator_nr = gen_array_index(extern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
447  paving_array[iterator_nr] = strdup("1");
448  }
449  else if((iterator_nr = gen_array_index(intern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
450  fitting_array[iterator_nr] = strdup("1");
451  }
452  }
453  if(syntax_tag(args[0]) == is_syntax_call){
454  claire_call_from_indice(syntax_call(args[0]), offset_array, paving_array, fitting_array);
455  }
456  claire_call_from_indice(syntax_call(args[1]), offset_array, paving_array, fitting_array);
457  }
458  else {
459  pips_user_error("APOTRES doesn't allow negative coefficients in paving and fitting matrices\n");
460  }
461  }
462  else if(same_string_p(funname, "*")){
463  if(syntax_tag(args[0]) != is_syntax_call || syntax_tag(args[1]) != is_syntax_reference || gen_length(call_arguments(syntax_call(args[0])))!=0 ){
464  pips_user_error("Only scalar * reference are allowed here. Please develop expressions.\n");
465  }
466  else {
467  int intern_nr = gen_array_index(intern_indices_array, claire_entity_local_name(reference_variable(syntax_reference(args[1]))));
468  int extern_nr = gen_array_index(extern_indices_array, claire_entity_local_name(reference_variable(syntax_reference(args[1]))));
469  string mult = strdup(claire_entity_local_name(call_function(syntax_call(args[0]))));
470  if(extern_nr != ITEM_NOT_IN_ARRAY){
471  paving_array[extern_nr] = mult;
472  }
473  else if(intern_nr != ITEM_NOT_IN_ARRAY){
474  fitting_array[intern_nr] = strdup(mult);
475  }
476  }
477  }
478  }
479  else{
480  pips_user_error("only linear expression of indices allowed\n");
481  }
482  }
483  else if(gen_length(arguments) == 0){
484  *offset_array = funname;
485  }
486  else{
487  pips_user_error("only +, -, * and constants allowed\n");
488  }
489 }
490 
491 #define CLAIRE_ARRAY_PREFIX "A_"
492 
493 static string claire_array_in_task(reference r, bool first, int task_number){
494  /* CLAIRE name of the referenced array */
495  string varname = strdup(concatenate(CLAIRE_ARRAY_PREFIX,
496  claire_entity_local_name(reference_variable(r)),
497  NULL));
498  /* iterator for dimensions of array */
499  int indice_nr = 0;
501  string result = "";
502  /* number of external loops*/
503  int extern_nb = gen_array_nitems(extern_indices_array);
504 
505  /* number of dimensions of referenced array */
506  int index_of_array = gen_length(indices); /*((int *) (gen_array_item(array_dims, gen_array_index(array_names, varname))));*/
507 
508  /* number of internal loops*/
509  int intern_nb = gen_array_nitems(intern_indices_array);
510 
511  /* list of offsets for CLAIRE code */
512  string offset_array[index_of_array];
513  /* paving matrix for CLAIRE code
514  1st coeff: array dimension (row index)
515  2nd coeff: iteration dimension (column index) */
516  string paving_array[index_of_array][extern_nb];
517 
518  /* fitting matrix for CLAIRE code
519  1st coeff: array dimension
520  2nd coeff: iteration dimension*/
521  string fitting_array[index_of_array][intern_nb];
522  int i;
523  int j;
524  int depth = 0;
525 
526  bool null_fitting_p = true;
527  string internal_index_declarations = strdup("");
528  string fitting_declaration = strdup("");
529  string fitting_declaration2 = strdup("");
530 
531  /* initialization of the arrays */
532  for (i=0; i<index_of_array; i++)
533  offset_array[i] = "0";
534 
535  for (i=0; i<index_of_array ; i++)
536  for (j=0; j<extern_nb; j++)
537  paving_array[i][j] = "0";
538 
539  for (i=0; i<index_of_array ; i++)
540  for (j=0; j<intern_nb; j++)
541  fitting_array[i][j] = "0";
542 
543  /* CLAIRE reference header */
544  result = strdup(concatenate(result, "DATA(name = symbol!(\"", "T_", int2a(task_number),
545  "\" /+ \"", varname, "\"),", NL, TAB, TAB, NULL));
546 
547  result = strdup(concatenate(result, "darray = ", varname, "," NL, TAB, TAB, "accessMode = ", (first?"Wmode,":"Rmode,"),
548  NL, TAB, TAB, "offset = list<VARTYPE>(", NULL));
549 
550  /* Fill in paving, fitting and offset matrices from index expressions. */
551  MAP(EXPRESSION, ind, {
552  syntax sind = expression_syntax(ind);
553  int iterator_nr;
554  switch(syntax_tag(sind)){
555  case is_syntax_reference:{
557  if((iterator_nr = gen_array_index(extern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
558  paving_array[indice_nr][iterator_nr] = strdup("1");
559  }
560  else if((iterator_nr = gen_array_index(intern_indices_array, claire_entity_local_name(reference_variable(ref)))) != ITEM_NOT_IN_ARRAY){
561  fitting_array[indice_nr][iterator_nr] = strdup("1");
562  }
563 
564  break;
565  }
566  case is_syntax_call:{
567  call c = syntax_call(sind);
568  claire_call_from_indice(c, &(offset_array[indice_nr]), paving_array[indice_nr], fitting_array[indice_nr]);
569  break;
570  }
571  default:{
572  pips_user_error("Only call and reference allowed in indices.\n");
573  break;
574  }
575  }
576  indice_nr++;
577  }, indices);
578 
579 
580  /* generate offset list in CLAIRE code */
581  for(i=0; i<index_of_array - 1; i++){
582  result=strdup(concatenate(result, "vartype!(", offset_array[i],"), ", NULL));
583  }
584  result = strdup(concatenate(result, "vartype!(", offset_array[i], "))," NL, NULL));
585 
586  /* fitting header */
587  result = strdup(concatenate(result, TAB, TAB, "fitting = list<list[VARTYPE]>(", NULL));
588 
589  /* CLAIRE column-major storage of fitting matrix */
590  for(i=0;i<intern_nb; i++){
591  bool is_null_p = true;
592  for(j = 0; j<index_of_array; j++){
593  is_null_p = is_null_p && (same_string_p(fitting_array[j][i], "0"));
594  }
595  if(!is_null_p){
596  null_fitting_p = false;
597  fitting_declaration = strdup(concatenate(fitting_declaration, "list(", NULL));
598  for(j = 0; j<index_of_array-1; j++){
599  fitting_declaration = strdup(concatenate(fitting_declaration, "vartype!(", fitting_array[j][i], "), ", NULL));
600  }
601  fitting_declaration = strdup(concatenate(fitting_declaration,
602  "vartype!(",
603  fitting_array[j][i],
604  ")), ",
605  NULL));
606  }
607  }
608 
609  if(!null_fitting_p){
610  fitting_declaration2 =
611  strdup(concatenate(gen_strndup0(fitting_declaration,
612  strlen(fitting_declaration) - 2),
613  "),", NL, TAB, TAB, TAB, NULL));
614  result = strdup(concatenate(result, fitting_declaration2, NULL));
615  }
616 
617  if(null_fitting_p){
618  result = strdup(concatenate(result, "list()),", NL, TAB, TAB, NULL));
619  }
620 
621  null_fitting_p = true;
622  /* Generation of paving CLAIRE code*/
623  result = strdup(concatenate(result, TAB, TAB, "paving = list<list[VARTYPE]>(", NULL));
624 
625  for(i=0;i<extern_nb-1; i++){
626  result = strdup(concatenate(result, "list(", NULL));
627  for(j = 0; j<index_of_array-1; j++){
628  result = strdup(concatenate(result, "vartype!(", paving_array[j][i], "), ", NULL));
629  }
630  result = strdup(concatenate(result, "vartype!(", paving_array[j][i], ")),", NL, TAB, TAB, TAB, NULL));
631  }
632  result = strdup(concatenate(result, "list(", NULL));
633  for(j = 0; j<index_of_array-1; j++){
634  result = strdup(concatenate(result, "vartype!(", paving_array[j][i], "), ", NULL));
635  }
636  result = strdup(concatenate(result, "vartype!(", paving_array[j][i], "))),", NL, TAB, TAB, NULL));
637 
638 #define MONMAX(a, b) ((a<b)?b:a)
639 
640  /* Definition of the inner loop nest */
641  /* FI->IH: if some columns are removed, the effective depth is unkown and must be computed here */
642  /* result = strdup(concatenate(result, "inLoopNest = LOOPNEST(deep = ", int2a(MONMAX(gen_array_nitems(intern_indices_array), 1)), ",", NL, TAB, TAB, TAB, NULL)); */
643 
644  for (j = 0; j<intern_nb; j++){
645  bool is_null_p = true;
646  for(i = 0; i < index_of_array; i++){
647  is_null_p = is_null_p && (same_string_p(fitting_array[i][j], "0"));
648  }
649  if(!is_null_p){
650  depth++;
651  }
652  }
653  if(depth==0) depth = 1; /* see comment just below about null fitting matrices. */
654  result = strdup(concatenate(result, "inLoopNest = LOOPNEST(deep = ", i2a(depth), ",", NL, TAB, TAB, TAB, NULL));
655  result = strdup(concatenate(result, "upperBound = list<VARTYPE>(", NULL));
656 
657  /* 3 cases :
658  - the fitting matrix is null : must generate a (0,0) loop with dummy index
659  - some fitting matrix column is null : do not generate anything
660  - some fitting matrix column is not null : generate the corresponding loop bound and index name
661  */
662 
663  for (j = 0; j<intern_nb; j++){
664  bool is_null_p = true;
665  for(i = 0; i < index_of_array; i++){
666  is_null_p = is_null_p && (same_string_p(fitting_array[i][j], "0"));
667  }
668  if(!is_null_p){
669  null_fitting_p = false;
670  result = strdup(concatenate(result,
671  "vartype!(",
672  *((string *)(gen_array_item(intern_upperbounds_array, j))),
673  "), ",
674  NULL));
675  internal_index_declarations =
676  strdup(concatenate(internal_index_declarations,
677  QUOTE,
678  *((string *)(gen_array_item(intern_indices_array, j))),
679  QUOTE,
680  ", ",
681  NULL));
682  }
683  }
684  if(!null_fitting_p)
685  {
686  result = strdup(concatenate(gen_strndup0(result, strlen(result) - 2),
687  "),", NULL));
688  internal_index_declarations =
689  strdup(concatenate(gen_strndup0(internal_index_declarations,
690  strlen(internal_index_declarations) -2),
691  ")", NULL));
692  }
693 
694 
695 
696  if(null_fitting_p){
697  result = strdup(concatenate(result, "vartype!(1)),", NL, TAB, TAB, TAB, "names = list<string>(\"M_I\")", NULL));
698  }
699  else{
700  result = strdup(concatenate(result, NL, TAB, "names = list<string>(", internal_index_declarations, NULL));
701  }
702 
703  /* Complete CLAIRE reference */
704  result = strdup(concatenate(result, "))", (first?")":","), NL, NULL));
705  return result;
706 
707 }
708 
709 static string claire_call_from_loopnest(call c, int task_number){
710  entity called = call_function(c);
712 
713  syntax s;
714  string result = "";
715  string first_result = "";
716  bool first = true;
717  bool input_provided = false, output_provided = false;
718  string name = strdup(claire_entity_local_name(called));
719 
720  if(!same_string_p(name, "="))
721  pips_user_error("Only assignation allowed here.\n");
722 
724  {
725  s = expression_syntax(e);
726 
727  switch(syntax_tag(s))
728  {
729  case is_syntax_call:
730  {
731  if(first)
733  "Call not allowed in left-hand side argument of assignation.");
734  result = strdup(concatenate(result,
735  claire_call_from_assignation(syntax_call(s), task_number,
736  &input_provided), NULL));
737  break;
738  }
739  case is_syntax_reference:
740  {
742  string varname = strdup(concatenate(
743  "A_", claire_entity_local_name(reference_variable(r)), NULL));
745  {
746  if(first)
747  {
748  first_result = claire_array_in_task(r, first, task_number);
749  output_provided = true;
750  }
751  else
752  {
753  result = strdup(concatenate(result,
754  claire_array_in_task(r, first, task_number), NULL));
755  input_provided = true;
756  }
757  }
758  break;
759  }
760  default:
761  pips_internal_error("unhandled case");
762  }
763  first = false;
764  }
765 
766  if(!input_provided){
767  result = strdup(concatenate("data = list<DATA>(dummyDATA, ", result, first_result, NULL));
768  }
769  else{
770  result = strdup(concatenate("data = list<DATA>(", result, first_result, NULL));
771  }
772  if(!output_provided){
773  result = strdup(concatenate(result, " dummyDATA)", NULL));
774  }
775  result = strdup(concatenate(result, TAB, ")", NL, NULL));
776  return result;
777 }
778 
779 
780 static call sequence_call(sequence seq)
781 {
782  call mc = call_undefined; /* meaningful call */
783  int nc = 0; /* number of calls */
784 
785  MAP(STATEMENT, s, {
786  if(continue_statement_p(s))
787  ;
788  else if(statement_call_p(s)) {
790  nc++;
791  }
792  else {
793  nc = 0;
794  break;
795  }
796  }, sequence_statements(seq));
797 
798  if(nc!=1)
799  mc = call_undefined;
800 
801  return mc;
802 }
803 
804 static loop sequence_loop(sequence seq)
805 {
806  loop ml = loop_undefined; /* meaningful loop */
807  int nl = 0; /* number of loops */
808 
809  MAP(STATEMENT, s, {
810  if(continue_statement_p(s))
811  ;
812  else if(statement_loop_p(s)) {
814  nl++;
815  }
816  else {
817  nl = 0;
818  break;
819  }
820  }, sequence_statements(seq));
821 
822  if(nl!=1)
823  ml = loop_undefined;
824 
825  return ml;
826 }
827 
828 static call claire_loop_from_loop(loop l, string * result, int task_number){
829 
830  string * up = malloc(sizeof(string));
831  string * claire_name = malloc(sizeof(string));
832  statement s = loop_body(l);
834  int u, low;
836  syntax incr_s = expression_syntax(incr_e);
837 
838  if(!syntax_call_p(incr_s) ||
839  strcmp( entity_local_name(call_function(syntax_call(incr_s))), "1") != 0 ) {
840  pips_user_error("Loop increments must be constant \"1\".\n");
841  }
842 
843  u = atoi(claire_expression(range_upper(loop_range(l))));
844  low = atoi(claire_expression(range_lower(loop_range(l))));
845  /* printf("%i %i\n", u, low); */
846  *up = strdup(int2a(u - low+1));
847  //*up = claire_expression(range_upper(loop_range(l)) - range_lower(loop_range(l)) + 1);
848  *claire_name = claire_entity_local_name(loop_index(l));
849  if( (*claire_name)[0] == 'M'){
852  }
853  else{
856  }
857 
858  switch(instruction_tag(i))
859  {
860  case is_instruction_loop:{
861  loop l = instruction_loop(i);
862  return claire_loop_from_loop(l, result, task_number);
863  }
864  case is_instruction_call: {
865  call c = instruction_call(i);
866  return c;
867  }
869  {
870  // The sequence should contain only one meaningful call
871  // or one meaningful loop.
874  if (!call_undefined_p(c))
875  return c;
876  if (!loop_undefined_p(l))
877  return claire_loop_from_loop(l, result, task_number);
878  pips_user_error("Only loops and calls allowed in a loop.");
879  break;
880  }
881  default:
882  pips_user_error("Only loops and calls allowed in a loop.");
883  }
884  return call_undefined;
885 }
886 
887 
888 /* We enter a loop nest. The first loop must be an extern loop. */
889 static string claire_loop_from_sequence(loop l, int task_number){
890  statement s = loop_body(l);
891  call c;
892  int i;
893  string * taskname = (string *)(malloc(sizeof(string)));
895  syntax incr_s = expression_syntax(incr_e);
896 
897 
898  /* Initialize result string with the declaration of the task */
899  string result;
900 
902  string * name = malloc(sizeof(string));
903  string * up = malloc(sizeof(string));
904  int u, low;
905  if(!syntax_call_p(incr_s) ||
906  strcmp( entity_local_name(call_function(syntax_call(incr_s))), "1") != 0 ) {
907  pips_user_error("Loop increments must be constant \"1\".\n");
908  }
909 
910 
911  *taskname = strdup(concatenate("T_", int2a(task_number), NULL));
912  result = strdup(concatenate(*taskname,
913  " :: TASK(unitSpentTime = vartype!(1),"
914  NL, TAB, "exLoopNest = LOOPNEST(deep = ", NULL));
915  gen_array_append(tasks_names, taskname);
916  /* (re-)initialize task-scoped arrays*/
921 
922 
923  *name = claire_entity_local_name(loop_index(l));
924  u = atoi(claire_expression(range_upper(loop_range(l))));
925  low = atoi(claire_expression(range_lower(loop_range(l))));
926  *up = strdup(int2a(u - low+1));
927  //*up = claire_expression(range_upper(loop_range(l)) - range_lower(loop_range(l)) + 1);
928 
929  if((*name)[0] == 'M'){
930  pips_user_error("At least one extern loop is needed.\n");
931  }
932  else{
935  }
936 
937  switch(instruction_tag(ins))
938  {
939  case is_instruction_loop:
940  {
941  loop l = instruction_loop(ins);
942  c = claire_loop_from_loop(l, &result, task_number);
943  break;
944  }
945  case is_instruction_call:
946  {
947  c = instruction_call(ins);
948  break;
949  }
951  // The sequence should contain only one meaningful call
953  break;
955  c = claire_loop_from_loop(l, &result, task_number);
956  break;
957  }
958  pips_user_error("Only loops and one significant call allowed in a loop.");
959  break;
960  default:
961  pips_user_error("Only loops and one significant call allowed in a loop.");
962  }
963 
964  /* External loop nest depth */
965  result = strdup(concatenate(result, int2a(gen_array_nitems(extern_upperbounds_array)), ",", NL, TAB, TAB, NULL));
966 
967  /* add external upperbounds */
968  result = strdup(concatenate(result, "upperBound = list<VARTYPE>(", NULL));
969 
970  for(i=0; i<(int) gen_array_nitems(extern_upperbounds_array) - 1; i++){
971  result = strdup(concatenate(result, "vartype!(", *((string *)(gen_array_item(extern_upperbounds_array, i))), "), ", NULL));
972  }
973  result = strdup(concatenate(result, "vartype!(",*((string *)(gen_array_item(extern_upperbounds_array, i))), ")),",NL, TAB, TAB, NULL));
974 
975  /* add external indices names*/
976  result = strdup(concatenate(result, "names = list<string>(", NULL));
977  for(i=0; i<(int) gen_array_nitems(extern_indices_array) - 1; i++){
978  result = strdup(concatenate(result, QUOTE, *((string *)(gen_array_item(extern_indices_array, i))), QUOTE ", ", NULL));
979  }
980  result = strdup(concatenate(result, QUOTE, *((string *)(gen_array_item(extern_indices_array, i))), QUOTE, ")),", NL, TAB, NULL));
981 
982  result = strdup(concatenate(result, claire_call_from_loopnest(c, task_number), NULL));
983 
988 
989  result = strdup(concatenate(result, NL, NULL));
990  return result;
991 }
992 
993 /* We are here at the highest level of statements. The statements are either
994  loopnests or a RETURN instruction. Any other possibility pips_user_errors
995  the prettyprinter.*/
996 static string claire_statement_from_sequence(statement s, int task_number){
997  string result = "";
999 
1000  switch(instruction_tag(i)){
1001  case is_instruction_loop:{
1002  loop l = instruction_loop(i);
1003  result = claire_loop_from_sequence(l, task_number);
1004  break;
1005  }
1006  case is_instruction_call:{
1007  /* RETURN should only be allowed as the last statement in the sequence */
1009  pips_user_error("Only RETURN and CONTINUE allowed here.\n");
1010  break;
1011  }
1012  default:{
1013  pips_user_error("Only loops and calls allowed here.\n");
1014  }
1015  }
1016 
1017  return result;
1018 }
1019 
1020 /* Concatentates each task to the final result.
1021  The validity of the task is not checked in this function but
1022  it is into claire_statementement_from_sequence and subsequent
1023  functions.*/
1024 static string claire_sequence_from_task(sequence seq){
1025  string result = "";
1026  int task_number = 0;
1027  MAP(STATEMENT, s,
1028  {
1029  string oldresult = strdup(result);
1030  string current = strdup(claire_statement_from_sequence(s, task_number));
1031 
1032  if(strlen(current)==0) {
1033  free(current);
1034  result = oldresult;
1035  }
1036  else {
1037  result = strdup(concatenate(oldresult, current, NULL));
1038  free(current);
1039  free(oldresult);
1040  task_number++;
1041  }
1042  }, sequence_statements(seq));
1043  return result;
1044 }
1045 
1046 /* Manages tasks. The code is very defensive and hangs if sth not
1047  predicted happens. Here basically we begin the code in itself
1048  and thus $stat is obligatory a sequence. */
1049 static string claire_tasks_with_motif(statement stat){
1050  int j;
1051  instruction i;
1052  string result = "tasks\n";
1053  if(statement_undefined_p(stat))
1054  {
1055  pips_internal_error("statement error");
1056  }
1057  i = statement_instruction(stat);
1059  switch(instruction_tag(i)){
1061  sequence seq = instruction_sequence(i);
1062  result = claire_sequence_from_task(seq);
1063  break;
1064  }
1065  default:{
1066  pips_user_error("Only a sequence can be here");
1067  }
1068  }
1069  result = strdup(concatenate(result, NL, NL, "PRES:APPLICATION := APPLICATION(name = symbol!(", QUOTE, global_module_name, QUOTE, "), ", NL, TAB,NULL));
1070  result = strdup(concatenate(result, "tasks = list<TASK>(", NULL));
1071  for(j = 0; j<(int) gen_array_nitems(tasks_names) - 1; j++){
1072  result = strdup(concatenate(result, *((string *)(gen_array_item(tasks_names, j))), ", ", NULL));
1073  }
1074  result = strdup(concatenate(result, *((string *)(gen_array_item(tasks_names, j))), "))", NULL));
1075 
1076  return result;
1077 }
1078 
1079 
1080 /* Creates string for claire pretty printer.
1081  This string divides in declarations (array decl.) and
1082  tasks which are loopnest with an instruction at the core.
1083 */
1084 static string claire_code_string(entity module, statement stat)
1085 {
1086  string decls="", tasks="", result="";
1087 
1088  ifdebug(2)
1089  {
1090  printf("Module statement: \n");
1091  print_statement(stat);
1092  printf("and declarations: \n");
1094  }
1095 
1096  decls = claire_declarations_with_explicit_motif(module, variable_p, "", true);
1097  tasks = claire_tasks_with_motif(stat);
1098 
1099  result = strdup(concatenate(decls, NL, tasks, NL, NULL));
1100  ifdebug(2)
1101  {
1102  printf("%s", result);
1103  }
1104  return result;
1105 }
1106 
1107 
1108 /******************************************************** PIPSMAKE INTERFACE */
1109 
1110 #define CLAIREPRETTY ".cl"
1111 
1112 /* Initiates claire pretty print modules
1113  */
1115 {
1116  FILE * out;
1117  string ppt, claire, dir, filename;
1118  entity module;
1119  statement stat;
1122  claire = db_build_file_resource_name(DBR_CLAIRE_PRINTED_FILE, module_name, CLAIREPRETTY);
1123 
1127  filename = strdup(concatenate(dir, "/", claire, NULL));
1128  stat = (statement) db_get_memory_resource(DBR_CODE, module_name, true);
1129 
1130  if(statement_undefined_p(stat))
1131  {
1132  pips_internal_error("No statement for module %s", module_name);
1133  }
1136 
1137  debug_on("CLAIREPRETTYPRINTER_DEBUG_LEVEL");
1138  pips_debug(1, "Begin Claire prettyprinter for %s\n", entity_name(module));
1139  ppt = claire_code_string(module, stat);
1140  pips_debug(1, "end\n");
1141  debug_off();
1142 
1143  /* save to file */
1144  out = safe_fopen(filename, "w");
1145  fprintf(out, "// Claire pretty print for module %s. \n%s", module_name, ppt);
1146  safe_fclose(out, filename);
1147 
1148  free(ppt);
1149  free(dir);
1150  free(filename);
1151 
1152  DB_PUT_FILE_RESOURCE(DBR_CLAIRE_PRINTED_FILE, module_name, claire);
1153 
1156 
1157  return true;
1158 }
1159 
1160 
1161 /* ======================================================= */
1162 
1163 
1164 
1165 typedef struct
1166 {
1167  stack loops_for_call;
1168  stack loop_indices;
1169  stack current_stat;
1170  gen_array_t nested_loops;
1171  gen_array_t nested_loop_indices;
1172  gen_array_t nested_call;
1173 }
1175  * nest_context_p;
1176 
1177 
1178 static void
1179 claire_declarations(entity module, string_buffer result)
1180 {
1181  bool comma = false;
1182  list dim;
1183  int nb_dim =0;
1184  string up_string ;
1185  MAP ( ENTITY, var,
1186  {
1187  if (variable_p(var) && ( variable_entity_dimension(var) >0))
1188  {
1189  string_buffer result_up = string_buffer_make(true);
1190  nb_dim = variable_entity_dimension(var);
1191  string_buffer_append(result,
1192  concatenate(CLAIRE_ARRAY_PREFIX,entity_user_name(var),
1193  " :: DATA_ARRAY(name = symbol!(", QUOTE,
1194  CLAIRE_ARRAY_PREFIX,entity_user_name(var), QUOTE,"),"
1195  , CLAIRE_RL, NULL));
1196  string_buffer_append(result,
1197  concatenate("dim = ",
1198  int2a(nb_dim), ",", CLAIRE_RL,NULL));
1199 
1200  string_buffer_append(result, "origins = list<integer>(");
1201  comma = false;
1202  for (dim = variable_dimensions(type_variable(entity_type(var))); !ENDP(dim); dim = CDR(dim)) {
1203 
1204  intptr_t low;
1205  intptr_t up;
1206  expression elow = dimension_lower(DIMENSION(CAR(dim)));
1207  expression eup = dimension_upper(DIMENSION(CAR(dim)));
1208  if (expression_integer_value(elow, &low) && expression_integer_value(eup, &up)){
1209  string_buffer_append(result,
1210  concatenate((comma)? ",":"", int2a(low),NULL));
1211  string_buffer_append(result_up,
1212  concatenate((comma)? ",":"", int2a(up-low+1),NULL));
1213  }
1214  else pips_user_error("Array dimensions must be integer\n");
1215  comma = true;
1216  }
1217 
1218  string_buffer_append(result, concatenate("),", CLAIRE_RL,NULL));
1219 
1220  string_buffer_append(result, "dimSizes = list<integer>(");
1221  up_string=string_buffer_to_string(result_up);
1222  /* string_buffer_free(&result_up,false);*/ // MEMORY LEAK???
1223  string_buffer_append(result,up_string);
1224  free(up_string);
1225 
1226  string_buffer_append(result,
1227  concatenate("),", CLAIRE_RL,NULL));
1228  string_buffer_append(result,
1229  concatenate("dataType = INTEGER)",
1230  NL,NL,NULL));
1231 
1232  }
1233  },
1235 
1236 
1237 }
1238 
1239 
1240 static void
1242 {
1243  stack_push(s , nest->current_stat);
1244 }
1245 
1246 static void
1248 {
1249  stack_pop(nest->current_stat);
1250 }
1251 
1252 static void
1253 push_loop(loop l, nest_context_p nest)
1254 {
1255  // on sauve le statement associe a la boucle courante
1257  stack_push(sl , nest->loops_for_call);
1258  stack_push(loop_index(l) , nest->loop_indices);
1259 }
1260 
1261 static void
1263 {
1264  stack_pop(nest->loops_for_call);
1265  stack_pop(nest->loop_indices);
1266 }
1267 
1268 static bool call_selection(call c, _UNUSED_ nest_context_p nest)
1269 {
1270 
1271  /* CA il faut implemeter un choix judicieux ... distribution ou encapsulation*/
1272  /* pour le moment distribution systematique de tout call */
1273  /* il faut recuperer les appels de fonction value_code_p(entity_initial(f)*/
1274  entity f = call_function(c);
1276  {
1277  return true;
1278  }
1279  else return false;
1280 
1281  /* statement s = (statement) stack_head(nest->current_stat);
1282  return ((!return_statement_p(s) && !continue_statement_p(s)));*/
1283 }
1284 
1286 {
1287  stack sl = stack_copy(nest->loops_for_call);
1288  stack si = stack_copy(nest->loop_indices);
1289  /* on sauve le statement associe au call */
1290  statement statc = (statement) stack_head(nest->current_stat) ;
1291  gen_array_append(nest->nested_loop_indices,si);
1292  gen_array_append(nest->nested_loops,sl);
1293  gen_array_append(nest->nested_call,statc);
1294 }
1295 
1296 static bool push_test(_UNUSED_ test t, _UNUSED_ nest_context_p nest)
1297 {
1298  /* encapsulation de l'ensemble des instructions appartenant au test*/
1299  /* on ne fait rien pour le moment */
1300  return false;
1301 }
1302 
1303 
1304 static void pop_test(_UNUSED_ test t, _UNUSED_ nest_context_p nest)
1305 {
1306  /* encapsulation de l'ensemble des instructions appartenant au test*/
1307 }
1308 
1309 
1310 static void
1312 {
1317  NULL);
1318 }
1319 
1320 static void __attribute__ ((unused)) print_call_selection(nest_context_p nest)
1321 {
1322  int j;
1323  int numberOfTasks=gen_array_nitems(nest->nested_call);
1324  for (j = 0; j<numberOfTasks; j++)
1325  {
1326  //statement s = gen_array_item(nest->nested_call,j);
1327  //stack st = gen_array_item(nest->nested_loops,j);
1328  /* print_statement(s);
1329  stack_map( st, print_statement);*/
1330  }
1331 }
1332 
1333 
1335 {
1336  expression new_e;
1337  if (expression_constant_p(e)) {
1338  new_e = int_to_expression(1+ expression_to_int(e));
1339  }
1340  else {
1342  new_e = make_call_expression(add_ent,
1344  }
1345  return new_e;
1346 }
1347 
1348 static void claire_loop(stack st, string_buffer result)
1349 {
1350  bool comma_needed = false;
1351  string_buffer buffer_lower = string_buffer_make(true);
1352  string_buffer buffer_upper = string_buffer_make(true);
1353  string_buffer buffer_names = string_buffer_make(true);
1354  string lower_bounds = "";
1355  string upper_bounds = "";
1356  string name_bounds = "";
1357 
1358  string_buffer_append(result, "exLoopNest = LOOPNEST(deep = ");
1359  string_buffer_append(result, concatenate(int2a(stack_size(st)),",",NULL));
1360 
1362  {
1366  expression new_eu= expression_plusplus(eu);
1367 
1368  string_buffer_append(buffer_lower,
1369  concatenate(comma_needed? ",": "",
1370  "vartype!(",
1372  ")",NULL));
1373  string_buffer_append(buffer_upper,
1374  concatenate(comma_needed? ",": "",
1375  "vartype!(",
1377  ")",NULL));
1378  string_buffer_append(buffer_names,
1379  concatenate(comma_needed? ",": "",
1381  QUOTE,NULL));
1382  comma_needed = true;
1383  },
1384  st, 0);
1385 
1386  /* Lower bounds generation*/
1387  string_buffer_append(result,
1388  concatenate(CLAIRE_RL,TAB, "lowerBound = list<VARTYPE>(", NULL));
1389  lower_bounds =string_buffer_to_string(buffer_lower);
1390  string_buffer_append(result,lower_bounds);
1391  free(lower_bounds), lower_bounds = NULL;
1392  string_buffer_append(result,"),");
1393 
1394  /* Upper bounds generation */
1395  string_buffer_append(result,
1396  concatenate(CLAIRE_RL,TAB, "upperBound = list<VARTYPE>(", NULL));
1397 
1398  upper_bounds =string_buffer_to_string(buffer_upper);
1399  string_buffer_append(result,upper_bounds);
1400  free(upper_bounds), upper_bounds = NULL;
1401  string_buffer_append(result, "),");
1402 
1403  /* Loop Indices generation */
1404  string_buffer_append(result,
1405  concatenate(CLAIRE_RL,TAB, "names = list<string>(", NULL));
1406  name_bounds =string_buffer_to_string(buffer_names);
1407  string_buffer_append(result,name_bounds);
1408  free(name_bounds), name_bounds = NULL;
1409 
1410  string_buffer_append(result, ")");
1411 
1412  string_buffer_append(result, concatenate("),",CLAIRE_RL,NULL));
1413 }
1414 
1415 
1416 
1417 static void claire_reference(int taskNumber, reference r, bool wmode,
1418  string_buffer result)
1419 {
1420 
1421  const char* varname = entity_user_name(reference_variable(r));
1423  (result,
1424  concatenate("name = symbol!(\"",
1425  CLAIRE_TASK_PREFIX,int2a(taskNumber),
1426  "\" /+ \"", CLAIRE_ARRAY_PREFIX, varname, "\"),",
1427  CLAIRE_RL, TAB,
1428  "darray = ", CLAIRE_ARRAY_PREFIX, varname, ",",
1429  CLAIRE_RL,TAB,
1430  "accessMode = ",
1431  (wmode?"Wmode,":"Rmode,"), CLAIRE_RL,TAB,
1432  NULL));
1433 }
1434 
1435 static void find_motif(
1436  Psysteme ps, Pvecteur nested_indices,
1437  int dim, _UNUSED_ int nb_dim, Pcontrainte *bound_inf,
1438  Pcontrainte *bound_sup, Pcontrainte *iterator, int *motif_up_bound)
1439 {
1440  Variable phi;
1441  Value v;
1442  Pvecteur pi;
1443  Pcontrainte c, next, cl, cu, cl_dup, cu_dup,lind, lind_dup,
1444  list_cl=NULL ,
1445  list_cu=NULL,
1446  list_ind=NULL;
1447  int lower =1;
1448  int upper =2;
1449  int ind =3;
1450  Pcontrainte bounds[4][4];
1451  int nb_bounds =0;
1452  int nb_lower = 0;
1453  int nb_upper = 0;
1454  int nb_indices=0;
1455  int i,j;
1456  Pbase vars_to_eliminate = BASE_NULLE;
1457 
1458  for (i=1; i<=3;i++)
1459  for (j=1; j<=3;j++)
1460  bounds[i][j]=CONTRAINTE_UNDEFINED;
1461 
1462  phi = (Variable) make_phi_entity(dim);
1463 
1464  /* elimination des variables autres de les phi et les indices de boucles englobants
1465 copie de la base + mise a zero des indices englobants + projection selon les elem de ce vecteur*/
1466 
1467  vars_to_eliminate = vect_copy(ps->base);
1468  /* printf("Base des variables :\n");
1469  vect_print(vars_to_eliminate, entity_local_name);
1470  */
1471  vect_erase_var(&vars_to_eliminate, phi);
1472  for (pi = nested_indices; !VECTEUR_NUL_P(pi); pi = pi->succ)
1473  vect_erase_var(&vars_to_eliminate, var_of(pi));
1474 
1475  /* printf("Elimination des variables :\n");
1476  vect_print(vars_to_eliminate, entity_local_name);
1477  */
1478 
1479  sc_projection_along_variables_ofl_ctrl(&ps,vars_to_eliminate , NO_OFL_CTRL);
1480 
1481  for(c = sc_inegalites(ps), next=(c==NULL ? NULL : c->succ);
1482  c!=NULL;
1483  c=next, next=(c==NULL ? NULL : c->succ))
1484  {
1485  Pvecteur indices_in_vecteur = VECTEUR_NUL;
1486  /* printf("Tri de la contrainte :\n");
1487  vect_print(c->vecteur, entity_local_name);
1488  */
1489  v = vect_coeff(phi, c->vecteur);
1490  for (pi = nested_indices; !VECTEUR_NUL_P(pi); pi = pi->succ)
1491  {
1492  int coeff_index = vect_coeff(var_of(pi),c->vecteur);
1493  if (coeff_index)
1494  vect_add_elem(&indices_in_vecteur,var_of(pi), coeff_index);
1495  }
1496 
1497 
1498  nb_indices=vect_size(indices_in_vecteur);
1499  nb_indices = (nb_indices >2) ? 2 : nb_indices;
1500 
1501  if (value_pos_p(v)) {
1502  c->succ = bounds[upper][nb_indices+1];
1503  bounds[upper][nb_indices+1] = c;
1504  /* printf(" bornes inf avec indices de boucles englobants :\n");
1505  vect_print(bounds[upper][nb_indices+1]->vecteur, entity_local_name); */
1506  nb_upper ++;
1507  }
1508  else if (value_neg_p(v)) {
1509  c->succ = bounds[lower][nb_indices+1];
1510  bounds[lower][nb_indices+1] = c;
1511  /* printf(" bornes inf avec indices de boucles englobants :\n");
1512  vect_print(bounds[lower][nb_indices+1]->vecteur, entity_local_name);*/
1513  lind = contrainte_make(indices_in_vecteur);
1514  lind->succ = bounds[ind][nb_indices+1];
1515  bounds[ind][nb_indices+1] = lind;
1516  /* printf(" indices contenus dans la contrainte :\n");
1517  vect_print(bounds[ind][nb_indices+1]->vecteur, entity_local_name); */
1518  nb_lower ++;
1519  }
1520  }
1521  /* printf("Nb borne inf = %d, Nb borne sup = %d ;\n",nb_lower,nb_upper); */
1522 
1523 
1524  if (!CONTRAINTE_UNDEFINED_P(bounds[lower][2])) {
1525  /* case with 1 loop index in the loop bound constraints */
1526  for(cl = bounds[lower][2], lind= bounds[ind][2]; cl !=NULL; cl=cl->succ,lind=lind->succ) {
1527  for(cu = bounds[upper][2]; cu !=NULL; cu =cu->succ) {
1528  /* printf("Tests de la negation des contraintes :\n");
1529  vect_print(cl->vecteur, entity_local_name);
1530  vect_print(cu->vecteur, entity_local_name); */
1531  if (vect_opposite_except(cl->vecteur,cu->vecteur,TCST)){
1532  cl_dup = contrainte_dup(cl);
1533  cl_dup->succ = list_cl, list_cl=cl_dup;
1534  cu_dup = contrainte_dup(cu);
1535  cu_dup->succ = list_cu, list_cu=cu_dup;
1536  lind_dup = contrainte_dup(lind);
1537  lind_dup->succ = list_ind, list_ind = lind_dup;
1538  nb_bounds ++;
1539  }
1540  }
1541  }
1542  *bound_inf= list_cl;
1543  *bound_sup = list_cu;
1544  *iterator = list_ind;
1545  *motif_up_bound =- vect_coeff(TCST,list_cl->vecteur) - vect_coeff(TCST,list_cu->vecteur) +1;
1546  }
1547  else if (!CONTRAINTE_UNDEFINED_P(bounds[lower][1]) && !CONTRAINTE_UNDEFINED_P(bounds[upper][1])) {
1548  /* case where loop bounds are numeric */
1549  *bound_inf= bounds[lower][1];
1550  *bound_sup = bounds[upper][1];
1551  *iterator = bounds[ind][1];
1552  *motif_up_bound = - vect_coeff(TCST,bounds[lower][1]->vecteur)
1553  - vect_coeff(TCST,bounds[upper][1]->vecteur)+1;
1554  } else {
1555  /* Only bounds with several loop indices */
1556  /* printf("PB - Only bounds with several loop indices\n"); */
1557  *bound_inf= CONTRAINTE_UNDEFINED;
1558  *bound_sup = CONTRAINTE_UNDEFINED;
1559  *iterator = CONTRAINTE_UNDEFINED;
1560  *motif_up_bound = 1;
1561 
1562  }
1563 
1564 }
1565 
1566 
1567 static void claire_tiling(int taskNumber, reference ref, region reg, stack indices, string_buffer result)
1568 {
1569  Psysteme ps_reg = sc_dup(region_system(reg));
1570 
1571  entity var = reference_variable(ref);
1573  int i, j ;
1574  string_buffer buffer_lower = string_buffer_make(true);
1575  string_buffer buffer_upper = string_buffer_make(true);
1576  string_buffer buffer_names = string_buffer_make(true);
1577  string_buffer buffer_offset = string_buffer_make(true);
1578  string_buffer buffer_fitting = string_buffer_make(true);
1579  string_buffer buffer_paving = string_buffer_make(true);
1580 
1581  string string_lower = "";
1582  string string_upper = "";
1583  string string_names = "";
1584  string string_offset = "";
1585  string string_paving = "";
1586  string string_fitting = "";
1587  bool comma = false;
1588 
1589  Pvecteur iterat, pi= VECTEUR_NUL;
1590  Pcontrainte bound_inf = CONTRAINTE_UNDEFINED;
1591  Pcontrainte bound_up = CONTRAINTE_UNDEFINED;
1592  Pcontrainte iterator = CONTRAINTE_UNDEFINED;
1593  int motif_up_bound =0;
1594  int dim_indices= stack_size(indices);
1595  int pav_matrix[10][10], fit_matrix[10][10];
1596 
1597  for (i=1; i<=9;i++)
1598  for (j=1;j<=9;j++)
1599  pav_matrix[i][j]=0, fit_matrix[i][j]=0;
1600 
1601  /* if (debug) printf("matrix pavage dimension:[%d][%d]\n",dim,dim_indices); */
1602 
1603  STACK_MAP_X(index,entity,
1604  {
1605  vect_add_elem (&pi,(Variable) index ,VALUE_ONE);
1606  }, indices,1);
1607 
1608  /* if (debug)
1609  {
1610  printf("liste des indices de boucles englobants :\n");
1611  vect_print(pi, entity_local_name);
1612  }*/
1613 
1614  for(i=1; i<=dim ; i++)
1615  {
1616  Psysteme ps = sc_dup(ps_reg);
1618 
1619  find_motif(ps, pi, i, dim, &bound_inf, &bound_up, &iterator, &motif_up_bound);
1620 
1621 
1622  /* extraction offset = terme / partie constante de lower*/
1623  string_buffer_append(buffer_offset,
1624  concatenate((comma)?",":"",
1625  "vartype!(",
1626  (CONTRAINTE_UNDEFINED_P(bound_inf))? "0" :
1627  int2a(vect_coeff(TCST,bound_inf->vecteur)),
1628  ")",NULL));
1629 
1630  /* paving = coef de l'indice de boucle */
1631  if (!CONTRAINTE_UNDEFINED_P(iterator)) {
1632  for (iterat = pi, j=1; !VECTEUR_NUL_P(iterat); iterat = iterat->succ, j++)
1633  pav_matrix[i][j]= vect_coeff(var_of(iterat),iterator->vecteur);
1634  }
1635 
1636  /* fitting = 1 */
1637  if (!CONTRAINTE_UNDEFINED_P(bound_inf))
1638  fit_matrix[i][i]= (motif_up_bound >1) ? 1:0;
1639 
1640 
1641  /* motif = boucle prof = dim */
1642 
1643  /* lower bound = 1 et upper bound = upper - lower */
1644  string_buffer_append(buffer_lower,
1645  concatenate(comma? ",": "",
1646  "vartype!(0)",NULL));
1647  string_buffer_append(buffer_upper,
1648  concatenate(comma? ",": "",
1649  "vartype!(",int2a(motif_up_bound),")",NULL));
1650  /* motif name = M_ numero = dim */
1651 
1652  string_buffer_append(buffer_names,
1653  concatenate(comma? ",": "",
1654  QUOTE,
1655  CLAIRE_MOTIF_PREFIX, int2a(taskNumber),"_",
1656  entity_user_name(var), "_",int2a(i),
1657  QUOTE,NULL));
1658  comma = true;
1659  }
1660  for (j=1; j<=dim_indices ; j++){
1661  if (j>1) string_buffer_append(buffer_paving,strdup("),list("));
1662  for(i=1; i<=dim ; i++)
1663  string_buffer_append(buffer_paving,
1664  concatenate((i>1)?",":"",
1665  "vartype!(",
1666  int2a( pav_matrix[i][j]),
1667  ")",NULL));
1668  }
1669  for(i=1; i<=dim ; i++) {
1670  if (i>1)
1671  string_buffer_append(buffer_fitting, "),list(");
1672  for(j=1; j<=dim ; j++)
1673  string_buffer_append(buffer_fitting,
1674  concatenate((j>1)?",":"",
1675  "vartype!(",
1676  int2a( fit_matrix[i][j]),
1677  ")",NULL));
1678  }
1679 
1680  string_buffer_append(result, "offset = list<VARTYPE>(");
1681  string_offset =string_buffer_to_string(buffer_offset);
1682  string_buffer_append(result,string_offset);
1683  free(string_offset), string_offset = NULL;
1684 
1685  string_buffer_append(result,concatenate("),",CLAIRE_RL,TAB,NULL));
1686  string_buffer_append(result,"fitting = list<list[VARTYPE]>(list(");
1687  string_fitting =string_buffer_to_string(buffer_fitting);
1688  string_buffer_append(result,string_fitting);
1689  free(string_fitting), string_fitting = NULL;
1690 
1691  string_buffer_append(result, concatenate(")),",CLAIRE_RL,TAB,NULL));
1692  string_buffer_append(result, "paving = list<list[VARTYPE]>(list(");
1693  string_paving =string_buffer_to_string(buffer_paving);
1694  string_buffer_append(result,string_paving);
1695  free(string_paving), string_paving = NULL;
1696 
1697  string_buffer_append(result, concatenate(")),",CLAIRE_RL,TAB,NULL));
1698  string_buffer_append(result, "inLoopNest = LOOPNEST(deep = ");
1699  string_buffer_append(result, int2a(dim));
1700  string_buffer_append(result, concatenate(",",CLAIRE_RL,NULL));
1701 
1702  /* Motif Lower bounds generation*/
1703  string_buffer_append(result,
1704  concatenate(TAB,TAB,"lowerBound = list<VARTYPE>(", NULL));
1705  string_lower =string_buffer_to_string(buffer_lower);
1706  string_buffer_append(result,string_lower);
1707  free(string_lower), string_lower = NULL;
1708  string_buffer_append(result, "),");
1709 
1710  /* Motif Upper bounds generation */
1711  string_buffer_append(result,
1712  concatenate(CLAIRE_RL,TAB,TAB, "upperBound = list<VARTYPE>(", NULL));
1713 
1714  string_upper =string_buffer_to_string(buffer_upper);
1715  string_buffer_append(result,string_upper);
1716  free(string_upper), string_upper = NULL;
1717  string_buffer_append(result, "),");
1718 
1719  /* Motif Loop Indices generation */
1720  string_buffer_append(result,
1721  concatenate(CLAIRE_RL,TAB,TAB, "names = list<string>(", NULL));
1722  string_names =string_buffer_to_string(buffer_names);
1723  string_buffer_append(result, string_names);
1724  free(string_names), string_names = NULL;
1725 
1726  string_buffer_append(result, ")");
1727  string_buffer_append(result, ")");
1728 }
1729 static void claire_references(int taskNumber, list l_regions, stack indices, string_buffer result)
1730 {
1731  list lr;
1732  bool atleast_one_read_ref = false;
1733  bool atleast_one_written_ref = false;
1734  bool comma = false;
1735 /* Read array references first */
1736  for ( lr = l_regions; !ENDP(lr); lr = CDR(lr))
1737  {
1738  region re = REGION(CAR(lr));
1740  if (array_reference_p(ref) && region_read_p(re)) {
1741  atleast_one_read_ref = true;
1742  if (comma) string_buffer_append(result,concatenate(",",CLAIRE_RL,NULL));
1743  string_buffer_append(result,concatenate(TAB, "DATA(",NULL));
1744  claire_reference(taskNumber, ref, region_write_p(re), result);
1745  /* fprintf(stderr, "\n la region ");
1746  print_regions(lr);*/
1747 
1748  claire_tiling(taskNumber, ref,re, indices, result);
1749  string_buffer_append(result,concatenate(TAB, ")", NULL));
1750  comma = true;
1751  }
1752  }
1753  if (!atleast_one_read_ref)
1754  string_buffer_append(result,concatenate(TAB, "dummyDATA, ",
1755  CLAIRE_RL,NULL));
1756 
1757  for ( lr = l_regions; !ENDP(lr); lr = CDR(lr))
1758  {
1759  region re = REGION(CAR(lr));
1761  if (array_reference_p(ref) && region_write_p(re)) {
1762  atleast_one_written_ref = true;
1763  if (comma) string_buffer_append(result, concatenate(",",CLAIRE_RL,NULL));
1764  string_buffer_append(result, concatenate(TAB, "DATA(",NULL));
1765  claire_reference(taskNumber, ref, region_write_p(re), result);
1766  /* fprintf(stderr, "\n la region ");
1767  print_regions(lr); */
1768  claire_tiling(taskNumber, ref,re, indices, result);
1769  string_buffer_append(result, ")");
1770  comma = true;
1771  }
1772  }
1773  if (!atleast_one_written_ref)
1774  string_buffer_append(result,concatenate(TAB,", dummyDATA ",NULL));
1775 }
1776 
1777 static void claire_data(int taskNumber,statement s, stack indices, string_buffer result )
1778 {
1780  string_buffer_append(result, concatenate("data = list<DATA>(",
1781  CLAIRE_RL,NULL));
1782  /*
1783  ifdebug(2) {
1784  fprintf(stderr, "\n list of regions ");
1785  print_regions(l_regions);
1786  fprintf(stderr, "\n for the statement");
1787  print_statement(s);
1788  }
1789  */
1790  claire_references(taskNumber, l_regions, indices, result);
1791 
1792  /*
1793  claire_tiling();
1794  claire_motif();
1795  */
1796  string_buffer_append(result, concatenate(")",CLAIRE_RL,NULL));
1797 }
1798 
1799 static string task_complexity(statement s)
1800 {
1801  complexity stat_comp = load_statement_complexity(s);
1802  string r;
1803  if(stat_comp != (complexity) HASH_UNDEFINED_VALUE && !complexity_zero_p(stat_comp)) {
1804  cons *pc = CHAIN_SWORD(NIL, complexity_sprint(stat_comp, false,
1805  true));
1806  r = words_to_string(pc);
1807  }
1808  else r = int2a(1);
1809  return (r);
1810 }
1811 static void claire_task( int taskNumber, nest_context_p nest, string_buffer result)
1812 {
1813  statement s = gen_array_item(nest->nested_call,taskNumber);
1814  stack st = gen_array_item(nest->nested_loops,taskNumber);
1815  stack sindices = gen_array_item(nest->nested_loop_indices,taskNumber);
1816 
1817  string_buffer_append(result, CLAIRE_TASK_PREFIX);
1818  string_buffer_append(result, int2a(taskNumber));
1819  string_buffer_append(result, " :: TASK(unitSpentTime = vartype!(");
1821  string_buffer_append(result, concatenate("),",CLAIRE_RL,NULL));
1822 
1823  claire_loop(st, result);
1824  claire_data (taskNumber, s,sindices, result);
1825  string_buffer_append(result, concatenate(")",NL,NL,NULL));
1826 
1827 }
1828 
1829 static void claire_tasks(statement stat, string_buffer result){
1830 
1831  const char* module_name = get_current_module_name();
1832  nest_context_t nest;
1833  int taskNumber =0;
1837  nest.nested_loops= gen_array_make(0);
1839  nest.nested_call= gen_array_make(0);
1840 
1841  if(statement_undefined_p(stat)) {
1842  pips_internal_error("statement error");
1843  }
1844 
1845  search_nested_loops_and_calls(stat,&nest);
1846  /* ifdebug(2) print_call_selection(&nest); */
1847 
1848  for (taskNumber = 0; taskNumber<(int) gen_array_nitems(nest.nested_call); taskNumber++)
1849 
1850  claire_task(taskNumber, &nest,result);
1851 
1852  string_buffer_append(result,
1853  concatenate(NL, NL,
1854  "PRES:APPLICATION := APPLICATION(name = symbol!(",
1855  QUOTE, module_name, QUOTE, "), ",
1856  NL, TAB,NULL));
1857  string_buffer_append(result, "tasks = list<TASK>(");
1858 
1859  for(taskNumber = 0; taskNumber<(int)gen_array_nitems(nest.nested_call)-1; taskNumber++)
1860  string_buffer_append(result, concatenate(CLAIRE_TASK_PREFIX,
1861  int2a(taskNumber), ", ", NULL));
1862  string_buffer_append(result, concatenate(CLAIRE_TASK_PREFIX,
1863  int2a(taskNumber) , "))", NL, NULL));
1864 
1868  stack_free(&(nest.loops_for_call));
1869  stack_free(&(nest.loop_indices));
1870  stack_free(&(nest.current_stat));
1871 
1872 }
1873 
1874 
1875 /* Creates string for claire pretty printer.
1876  This string divides in declarations (array decl.) and
1877  tasks which are loopnests with an instruction at the core.
1878 */
1879 static string claire_code(entity module, statement stat)
1880 {
1881  string_buffer result=string_buffer_make(true);
1882  string result2;
1883 
1884  claire_declarations(module,result);
1885  claire_tasks(stat,result);
1886 
1887  result2=string_buffer_to_string(result);
1888  /* string_buffer_free(&result,true); */ // MEMORY LEAK ???
1889  /* ifdebug(2)
1890  {
1891  printf("%s", result2);
1892  } */
1893  return result2;
1894 }
1895 
1896 static bool valid_specification_p(
1898 {
1899  return true;
1900 }
1901 
1902 /******************************************************** PIPSMAKE INTERFACE */
1903 
1904 #define CLAIREPRETTY ".cl"
1905 
1906 /* Initiates claire pretty print modules
1907  */
1908 bool print_claire_code(const char* module_name)
1909 {
1910  FILE * out;
1911  string ppt;
1912 
1914  string claire = db_build_file_resource_name(DBR_CLAIRE_PRINTED_FILE,
1915  module_name, CLAIREPRETTY);
1916  string dir = db_get_current_workspace_directory();
1917  string filename = strdup(concatenate(dir, "/", claire, NULL));
1918 
1919  statement stat=(statement) db_get_memory_resource(DBR_CODE,
1920  module_name, true);
1921 
1922  init_cost_table();
1923  /* Get the READ and WRITE regions of the module */
1925  db_get_memory_resource(DBR_REGIONS, module_name, true));
1926 
1928  db_get_memory_resource(DBR_COMPLEXITIES, module_name, true));
1929 
1930  if(statement_undefined_p(stat))
1931  {
1932  pips_internal_error("No statement for module %s", module_name);
1933  }
1936 
1937  debug_on("CLAIREPRETTYPRINTER_DEBUG_LEVEL");
1938  pips_debug(1, "Spec validation before Claire prettyprinter for %s\n",
1939  entity_name(module));
1940  if (valid_specification_p(module,stat)){
1941  pips_debug(1, "Spec is valid\n");
1942  pips_debug(1, "Begin Claire prettyprinter for %s\n", entity_name(module));
1943 
1944  ppt = claire_code(module, stat);
1945  pips_debug(1, "end\n");
1946  debug_off();
1947 
1948  /* save to file */
1949  out = safe_fopen(filename, "w");
1950  fprintf(out, "// Claire pretty print for module %s. \n%s",
1951  module_name, ppt);
1952  safe_fclose(out, filename);
1953  free(ppt);
1954  }
1955 
1956  free(dir);
1957  free(filename);
1958 
1959  DB_PUT_FILE_RESOURCE(DBR_CLAIRE_PRINTED_FILE, module_name, claire);
1960 
1963 
1964  return true;
1965 }
1966 
1967 #endif // BUILDER_PRINT_CLAIRE_CODE
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static FILE * out
Definition: alias_check.c:128
#define value_pos_p(val)
void const char const char const int
int Value
#define VALUE_ONE
#define value_neg_p(val)
size_t gen_array_nitems(const gen_array_t a)
Definition: array.c:131
gen_array_t gen_array_make(size_t size)
declarations...
Definition: array.c:40
void * gen_array_item(const gen_array_t a, size_t i)
Definition: array.c:143
void gen_array_append(gen_array_t a, void *what)
Definition: array.c:105
void gen_array_free(gen_array_t a)
Definition: array.c:70
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
bool complexity_zero_p(complexity comp)
zero complexity check.
Definition: comp_math.c:244
char * complexity_sprint(complexity comp, bool print_stats_p, bool print_local_names_p)
Definition: comp_util.c:175
void init_cost_table()
Completes the intrinsic cost table with the costs read from the files specified in the "COMPLEXITY_CO...
Definition: comp_util.c:519
complexity load_statement_complexity(statement)
void set_complexity_map(statement_mapping)
#define CONTRAINTE_UNDEFINED_P(c)
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
Pcontrainte contrainte_dup(Pcontrainte c_in)
Pcontrainte contrainte_dup(Pcontrainte c_in): allocation d'une contrainte c_out prenant la valeur de ...
Definition: alloc.c:132
#define region_write_p(reg)
#define region_system(reg)
#define region_read_p(reg)
useful region macros
#define REGION
#define region
simulation of the type region
entity make_phi_entity(int)
list regions_dup(list)
void set_rw_effects(statement_effects)
list load_statement_local_regions(statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
static bool variable_p(entity e)
lready exist in cprettyprint but in mode static.
Definition: prettyprint.c:207
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
void * malloc(YYSIZE_T)
void free(void *)
#define COMMA
Definition: genspec.h:85
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_FILE_RESOURCE
Put a file resource into the current workspace database.
Definition: pipsdbm-local.h:85
bool statement_call_p(statement)
Definition: statement.c:364
bool statement_loop_p(statement)
Definition: statement.c:349
bool return_statement_p(statement)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
bool continue_statement_p(statement)
Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: statement.c:203
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
static list indices
Definition: icm.c:204
bool vect_opposite_except(Pvecteur v1, Pvecteur v2, Variable var)
bool vect_opposite_except(Pvecteur v1, Pvecteur v2, Variable var): test a egalite des projections sel...
Definition: reductions.c:399
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define CLOSEPAREN
string db_build_file_resource_name(const char *rname, const char *oname, const char *suffix)
returns an allocated file name for a file resource.
Definition: lowlevel.c:169
#define debug_on(env)
Definition: misc-local.h:157
#define _UNUSED_
Definition: misc-local.h:232
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
#define pips_user_error
Definition: misc-local.h:147
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
struct nest_context_t * nest_context_p
bool print_claire_code(const char *)
bool print_claire_code_with_explicit_motif(const char *)
claire_prettyprinter.c
#define TYPEDEF_PREFIX
Definition: naming-local.h:62
#define UNION_PREFIX
Definition: naming-local.h:58
#define ENUM_PREFIX
Definition: naming-local.h:60
#define MEMBER_SEP_STRING
Definition: naming-local.h:53
#define STRUCT_PREFIX
Definition: naming-local.h:56
string gen_strndup0(string, size_t)
Like strdup() but copy at most n characters.
Definition: string.c:83
char * i2a(int)
I2A (Integer TO Ascii) yields a string for a given Integer.
Definition: string.c:121
string strupper(string, const char *)
Definition: string.c:213
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define same_string_p(s1, s2)
#define STACK_MAP_X(_item, _itemtype, _code, _stack, _downwards)
not needed
Definition: newgen_stack.h:104
stack stack_copy(const stack)
duplicate a stack with its contents.
Definition: stack.c:267
void * stack_head(const stack)
returns the item on top of stack s
Definition: stack.c:420
int stack_size(const stack)
observers
void stack_push(void *, stack)
stack use
Definition: stack.c:373
void stack_free(stack *)
type, bucket_size, policy
Definition: stack.c:292
stack stack_make(int, int, int)
allocation
Definition: stack.c:246
void * stack_pop(stack)
POPs one item from stack s.
Definition: stack.c:399
void string_buffer_append(string_buffer, const string)
append string s (if non empty) to string buffer sb, the duplication is done if needed according to th...
string string_buffer_to_string(const string_buffer)
return malloc'ed string from string buffer sb
string_buffer string_buffer_make(bool dup)
allocate a new string buffer
Definition: string_buffer.c:58
#define string_undefined
Definition: newgen_types.h:40
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
list Words_Expression(expression obj)
of string
Definition: misc.c:2616
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define ENTITY_ASSIGN_P(e)
#define PLUS_OPERATOR_NAME
#define entity_declarations(e)
MISC: newgen shorthands.
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool entity_subroutine_p(entity e)
Definition: entity.c:737
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
void print_entities(list l)
Definition: entity.c:167
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
expression make_call_expression(entity e, list l)
Build an expression that call an function entity with an argument list.
Definition: expression.c:321
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
bool array_reference_p(reference r)
predicates on references
Definition: expression.c:1861
int variable_entity_dimension(entity)
variable_entity_dimension(entity v): returns the dimension of variable v; scalar have dimension 0.
Definition: variable.c:1293
#define loop_body(x)
Definition: ri.h:1644
#define test_domain
newgen_entity_domain_defined
Definition: ri.h:418
#define value_code_p(x)
Definition: ri.h:3065
#define value_constant(x)
Definition: ri.h:3073
#define loop_undefined
Definition: ri.h:1612
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define range_upper(x)
Definition: ri.h:2290
#define type_tag(x)
Definition: ri.h:2940
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define constant_int(x)
Definition: ri.h:850
#define syntax_call_p(x)
Definition: ri.h:2734
#define instruction_loop(x)
Definition: ri.h:1520
#define dimension_lower(x)
Definition: ri.h:980
#define call_undefined_p(x)
Definition: ri.h:686
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define code_declarations(x)
Definition: ri.h:784
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define range_increment(x)
Definition: ri.h:2292
#define storage_ram_p(x)
Definition: ri.h:2519
#define value_constant_p(x)
Definition: ri.h:3071
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define constant_int_p(x)
Definition: ri.h:848
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define loop_undefined_p(x)
Definition: ri.h:1613
#define entity_name(x)
Definition: ri.h:2790
#define sequence_statements(x)
Definition: ri.h:2360
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define value_code(x)
Definition: ri.h:3067
#define instruction_sequence(x)
Definition: ri.h:1514
#define syntax_call(x)
Definition: ri.h:2736
#define range_lower(x)
Definition: ri.h:2288
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define loop_range(x)
Definition: ri.h:1642
#define call_arguments(x)
Definition: ri.h:711
#define statement_undefined_p(x)
Definition: ri.h:2420
@ is_type_enum
Definition: ri.h:2907
@ is_type_variable
Definition: ri.h:2900
@ is_type_union
Definition: ri.h:2906
@ is_type_struct
Definition: ri.h:2905
#define entity_type(x)
Definition: ri.h:2792
#define call_undefined
Definition: ri.h:685
#define expression_syntax(x)
Definition: ri.h:1247
#define storage_return_p(x)
Definition: ri.h:2516
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define loop_index(x)
Definition: ri.h:1640
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
int printf()
void sc_transform_eg_in_ineg(Psysteme sc)
Package sc.
#define ifdebug(n)
Definition: sg.c:47
#define intptr_t
Definition: stdint.in.h:294
static size_t current
Definition: string.c:115
Pvecteur vecteur
struct Scontrainte * succ
Pbase base
Definition: sc-local.h:75
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
struct Svecteur * succ
Definition: vecteur-local.h:92
the stack head
Definition: stack.c:62
internally defined structure.
Definition: string_buffer.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Warning! Do not modify this file that is automatically generated!
Definition: modeling-local.h:4
gen_array_t nested_loop_indices
gen_array_t nested_call
stack loops_for_call
Definition: modeling-local.h:5
gen_array_t nested_loops
Definition: modeling-local.h:9
#define CHAIN_SWORD(l, s)
string words_to_string(cons *lw)
Definition: print.c:211
char * int2a(int)
util.c
Definition: util.c:42
static int depth
la sequence de nids
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define NO_OFL_CTRL
#define VECTEUR_NUL_P(v)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define var_of(varval)
#define BASE_NULLE
MACROS SUR LES BASES.
Pbase vect_copy(Pvecteur b)
direct duplication.
Definition: alloc.c:240
void vect_erase_var(Pvecteur *ppv, Variable v)
void vect_erase_var(Pvecteur * ppv, Variable v): projection du vecteur *ppv selon la direction v (i....
Definition: unaires.c:106
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228
#define NL
Definition: xml_output.c:48
#define ITEM_NOT_IN_ARRAY
#define CLOSEBRACKET
static loop sequence_loop(sequence seq)
static void push_current_statement(statement s, nest_context_p nest)
#define EMPTY
static int gen_array_index(gen_array_t ar, string item)
static gen_array_t extern_indices_array
array containing extern loop indices names
static gen_array_t array_names
static void store_call_context(call c __attribute__((unused)), nest_context_p nest)
static gen_array_t intern_indices_array
array containing intern loop indices (name : "M_")
static void pop_current_statement(statement s __attribute__((unused)), nest_context_p nest)
#define OPENBRACKET
static bool valid_specification_p(entity module __attribute__((unused)), statement stat __attribute__((unused)))
static void search_nested_loops_and_calls(statement stmp, nest_context_p nest)
static void find_motif(Psysteme ps, Pvecteur nested_indices, int dim, int nb_dim __attribute__((unused)), Pcontrainte *bound_inf, Pcontrainte *bound_sup, Pcontrainte *iterator, int *motif_up_bound, int *lowerbound, int *upperbound)
static void pop_loop(_UNUSED_ loop l, nest_context_p nest)
static void pop_test(test t __attribute__((unused)), nest_context_p nest __attribute__((unused)))
#define QUOTE
#define current_module_is_a_function()
static const char * global_module_name
static bool push_test(test t __attribute__((unused)), nest_context_p nest __attribute__((unused)))
static string task_complexity(statement s)
#define RESULT_NAME
static gen_array_t array_dims
static call sequence_call(sequence seq)
static gen_array_t extern_upperbounds_array
array containing extern upperbounds
static bool call_selection(call c, nest_context_p nest __attribute__((unused)))
#define TAB
static gen_array_t intern_upperbounds_array
array containing intern upperbounds
static gen_array_t tasks_names
array containing the tasks names
static void push_loop(loop l, nest_context_p nest)
static expression expression_plusplus(expression e)