PIPS
tiling.c
Go to the documentation of this file.
1 /*
2 
3  $Id: tiling.c 23495 2018-10-24 09:19:47Z 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 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* package tiling
28  *
29  * 1. Why?
30  * - memory hierarchy (registers, caches L1/L2/L3, memory, virtual memory, out-of-core,...)
31  * - granularity (amortization of fix costs: synchronization, communication, control,...)
32  * 2. Legality
33  * - TO BE IMPLEMENTED
34  * 3. Selection
35  * - directions (e.g. communication minimization): Darte/Robert, Hoegsted
36  * - ratios (e.g. critical path minimization)
37  * - volume (fix cost amortization) under memory constraints
38  * - mapping on finite hardware (Robert/...)
39  * restriction to orthogonal tilings: ratios, volume, mapping (Andonov/Rajopadhye)
40  * 4. Code Generation (Xue?)
41  * - control and memory addressing overheads
42  * 5. Hierarchical Tiling (Ferrante/Carter,...)
43  * 6. Data vs Control Tiling
44  * 7. Extensions
45  * - perfectly nested loops (IMPLEMENTED)
46  * - non perfectly nested loops (e.g. matrix multiply)
47  * - general nested loops (e.g. ADI)
48  * - sequence of loop nests (signal processing, Thomson-CSF)
49  * - ...
50  * See: http://www.irisa.fr/api/Rajopadhye/tiling
51  */
52 
53 #include <stdlib.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <strings.h>
57 
58 #include "genC.h"
59 #include "linear.h"
60 #include "ri.h"
61 #include "effects.h"
62 #include "misc.h"
63 #include "text.h"
64 #include "pipsdbm.h"
65 #include "boolean.h"
66 #include "vecteur.h"
67 #include "contrainte.h"
68 #include "sc.h"
69 #include "matrice.h"
70 #include "matrix.h"
71 #include "sparse_sc.h"
72 #include "ri-util.h"
73 #include "effects-util.h"
74 #include "conversion.h"
75 #include "dg.h"
78 #include "graph.h"
79 #include "ricedg.h"
80 
81 #include "graph.h"
82 #include "transformations.h"
83 #include "properties.h"
84 #include "tiling.h"
85 #include "movements.h"
86 
87 #include "hyperplane.h"
88 
89 /* Create a new entity for tile index. Because of the module name, it is easier to postfix
90  * by "_t" than to prefix by "t_".
91  */
92 static entity
94 {
95  return make_new_index_entity(old_index, "_t");
96 }
97 static entity
99 {
100  return make_new_index_entity(old_index, "_l");
101 }
102 
103 bool
104 static_partitioning_matrix(matrice P, int n, const char* serialized_matrix)
105 {
106  pips_assert("interactive_partitioning_matrix", n>=1);
107  bool status = false;
108  if( serialized_matrix && !string_undefined_p(serialized_matrix) && !empty_string_p(serialized_matrix))
109  {
110  int row,col;
111  string ctxt0 = string_undefined, ctxt1 = string_undefined;
112  string saved_ptr,buffer,elem = NULL;
113  saved_ptr= buffer = strdup(serialized_matrix);
114  string line = strtok_r(buffer,",",&ctxt0);
115  DENOMINATOR(P) = VALUE_ONE;
116  for(row=1;row<=n;row++){
117  elem = strtok_r(line," ",&ctxt1);
118 
119  for(col=1;col<=n;col++)
120  {
121  if(!elem) elem = col==row ? "1" : "0";
122  ACCESS(P, n, row, col)=atoi(elem);
123  elem = strtok_r(NULL," ",&ctxt1);
124  }
125  line = strtok_r(NULL,",",&ctxt0);
126  }
127  status= ( line == NULL ) && (elem == NULL );
128  free(saved_ptr);
129  }
130  return status;
131 }
132 
133 /* Query the user for a partitioning matrix P
134  */
135 
136 bool
138 {
139  int n_read;
140  string resp = string_undefined;
141  string cn = string_undefined;
142  bool return_status = false;
143  int row;
144  int col;
145 
146  DENOMINATOR(P) = VALUE_ONE;
147  /* Query the user for P's components */
148  pips_assert("interactive_partitioning_matrix", n>=1);
149  debug(8, "interactive_partitioning_matrix", "Reading P\n");
150 
151  for(row=1; row<=n; row++) {
152  resp = user_request("Partitioning matrix (%dx%d)?\n"
153  "(give all its integer coordinates on one line of %d per row): ",
154  n, n, n);
155  if (resp[0] == '\0') {
156  user_log("Tiling loop transformation has been cancelled.\n");
157  return_status = false;
158  }
159  else {
160  cn = strtok(resp, " \t");
161 
162  return_status = true;
163  for( col = 1; col<=n; col++) {
164  if(cn==NULL) {
165  user_log("Too few coordinates. "
166  "Tiling loop transformation has been cancelled.\n");
167  return_status = false;
168  break;
169  }
170  n_read = sscanf(cn," " VALUE_FMT, &ACCESS(P, n, row, col));
171  if(n_read!=1) {
172  user_log("Too few coordinates. "
173  "Hyperplane loop transformation has been cancelled.\n");
174  return_status = false;
175  break;
176  }
177  cn = strtok(NULL, " \t");
178  }
179  }
180 
181  if(cn!=NULL) {
182  user_log("Too many coordinates. "
183  "Tiling loop transformation has been cancelled.\n");
184  return_status = false;
185  }
186  }
187 
188  ifdebug(8) {
189  if(return_status) {
190  pips_debug(8, "Partitioning matrix:\n");
191  matrice_fprint(stderr, P, n, n);
192  (void) fprintf(stderr,"\n");
193  pips_debug(8, "End\n");
194  }
195  else {
196  pips_debug(8, "Ends with failure\n");
197  }
198  }
199 
200  return return_status;
201 }
202 
203 
204 /* Generate the tile membership constraints between a tile coordinates and
205  an iteration coordinate
206  */
207 
208 static Psysteme
210  Pbase tile_basis,
211  matrice HT,
212  Pvecteur tiling_offset)
213 {
214  Psysteme mc = sc_new();
215  int dim = base_dimension(initial_basis);
216  int row;
217  int col;
218  Value k = DENOMINATOR(HT);
219  Value up = k - VALUE_ONE;
220  Pbase civ = BASE_UNDEFINED;
221  Pbase ctv = BASE_UNDEFINED;
222 
223  ifdebug(8) {
224  debug(8, "tile_membership_constraints", "Begin with Matrix HT:\n");
225  matrice_fprint(stderr, HT, dim, dim);
226  }
227 
228  pips_assert("The two bases have the same dimension", dim == base_dimension(tile_basis));
229 
230  for(row = 1; row <= dim; row++) {
231  Pvecteur upper = VECTEUR_NUL;
232  Pvecteur lower = VECTEUR_NUL;
235 
236  for(col = 1, civ = initial_basis, ctv = tile_basis;
237  col <= dim;
238  col++, civ = vecteur_succ(civ), ctv = vecteur_succ(ctv)) {
239  if(ACCESS(HT, dim, row, col)!=VALUE_ZERO) {
240  Value coeff = ACCESS(HT, dim, row, col);
241  Value offset = vect_coeff(vecteur_var(civ), tiling_offset);
242 
243  vect_add_elem(&upper, vecteur_var(civ), coeff);
244  vect_add_elem(&upper, TCST, value_uminus(offset*coeff));
245  }
246  if(col==row) {
247  vect_add_elem(&upper, vecteur_var(ctv), value_uminus(k));
248  }
249  }
250  lower = vect_dup(upper);
251  vect_chg_sgn(lower);
252  vect_add_elem(&upper, TCST, value_uminus(up));
253  cupper = contrainte_make(upper);
254  clower = contrainte_make(lower);
255  sc_add_inegalite(mc, cupper);
256  sc_add_inegalite(mc, clower);
257  }
258 
259  sc_creer_base(mc);
260 
261  ifdebug(8) {
262  pips_debug(8, "End with constraint system mc:\n");
264  }
265 
266  return mc;
267 }
268 
269 /* Generate the tile membership constraints between a tile coordinates and
270  an iteration coordinate
271 */
272 
273 Psysteme
275  Pbase tile_basis,
276  matrice HT,
277  Pvecteur tiling_offset)
278 {
279  Psysteme mc = sc_new();
280  int dim = base_dimension(initial_basis);
281  int row;
282  int col,col2;
283  Value k = DENOMINATOR(HT);
284  Value up = k - VALUE_ONE;
285  Pbase civ = BASE_UNDEFINED;
286  Pbase ctv = BASE_UNDEFINED;
287  matrice G_tile;
288  Value *h_tile; // hyperplane direction
289  ifdebug(8) {
290  debug(8, "tile_membership_constraints", "Begin with Matrix HT:\n");
291  matrice_fprint(stderr,HT, dim, dim);
292  }
293  int n = dim;
294  pips_assert("The two bases have the same dimension", dim == base_dimension(tile_basis));
295 
296  ifdebug(8) {
297  pips_debug(8,"hyperplane matrix HT:");
298  matrice_fprint(stderr, HT, n, n);
299  (void) fprintf(stderr,"\n");
300  }
301 
302  /* computation of the hyperplane tile direction in the tile basis: = sum(hi)= 1H */
303  h_tile = (Value*)(malloc(n*sizeof(Value)));
304  G_tile = matrice_new(n,n);
305 
306  string tile_direction = (string) get_string_property("TILE_DIRECTION");
307  if(!empty_string_p(tile_direction) && strcmp(tile_direction,"TP") == 0) {
308  for(col=0; col<n; col++) {
309  h_tile[col]=VALUE_ONE;
310  }
311 
312  ifdebug(8) {
313  (void) fprintf(stdout,"The hyperplane direction h_tile is :");
314  for(col=0; col<n; col++)
315  (void) printf("%d ;",(int)h_tile[col]);
316  (void) printf("\n");
317  }
318  /* computation of the tile scanning base G.
319  */
320  scanning_base_hyperplane(h_tile, n, G_tile);
321  ifdebug(8) {
322  (void) fprintf(stderr,"The tile scanning base G_tile is :");
323  matrice_fprint(stderr, G_tile, n, n);
324  }
325  }
326  else matrice_identite(G_tile,n,0);
327 
328  /* Build the constraints
329  0 <= det(HT).[HT. (i -i0)]<det(HT).1 with
330  i0=P.G_tile.i_tile
331  <==> 0 <= det(HT).[HT. (i -P.G_tile.i_tile)]<det(HT).1
332  <==> 0 <= det(HT).[HT.i -G_tile.i_tile]<= det(HT)-1
333  */
334  for(row = 1; row <= dim; row++) {
335  Pvecteur upper = VECTEUR_NUL;
336  Pvecteur lower = VECTEUR_NUL;
339 
340  for(col = 1, civ = initial_basis; col <= dim; col++, civ = vecteur_succ(civ)) {
341  if(ACCESS(HT, dim, row, col)!=VALUE_ZERO) {
342  Value coeff = ACCESS(HT, dim, row, col);
343  Value offset = vect_coeff(vecteur_var(civ), tiling_offset);
344 
345  vect_add_elem(&upper, vecteur_var(civ), coeff);
346  vect_add_elem(&upper, TCST, value_uminus(offset*coeff));
347  }
348  }
349  for(col2 = 1, ctv = tile_basis; col2 <= dim; col2++,ctv = vecteur_succ(ctv)) {
350 
351  /* Find the origin of the iteration domain. Use 0 as default coordinate */
352  if(ACCESS(G_tile, dim, row, col2)!=VALUE_ZERO) {
353  Value coeff2 = ACCESS(G_tile, dim,row, col2);
354  vect_add_elem(&upper, vecteur_var(ctv), value_uminus(k) *coeff2);
355  }
356  }
357 
358  lower = vect_dup(upper);
359  vect_chg_sgn(lower);
360  vect_add_elem(&upper, TCST, value_uminus(up));
361  cupper = contrainte_make(upper);
362  clower = contrainte_make(lower);
363  sc_add_inegalite(mc, cupper);
364  sc_add_inegalite(mc, clower);
365  }
366  sc_creer_base(mc);
367 
368  ifdebug(8) {
369  pips_debug(8, "End with constraint system mc:\n");
371  }
372 
373  return mc;
374 }
375 
376 static void compute_local_change_of_basis( Value *h_tile, matrice P, matrice G, int option, int dim, int selected_Pdim)
377 {
378  int row;
379  int col;
380  if (option ==1) {
381  /* computation of the hyperplane tile direction in the tile basis: = sum(hi)= 1H */
382  for(row=0; row<dim; row++) {
383  h_tile[row]=VALUE_ZERO;
384  for(col=0; col<dim; col++) {
385  h_tile[row]+=ACCESS(P, dim, row+1, col+1);
386  }
387  }
388  }
389  else if (option==2)
390  { /* The local tile direction is colinear to the (selected_Pdim) partitioning vecteur */
391  for(col=0; col<dim; col++)
392  h_tile[col]=ACCESS(P, dim, col+1, selected_Pdim);
393  }
394  ifdebug(8) {
395  (void) fprintf(stdout,"The first scanning direction h_tile in %s mode is :",(option==1)?"LP":"LS");
396  for(col=0; col<dim; col++)
397  (void) printf("%d ;",(int)h_tile[col]);
398  (void) printf("\n");
399  }
400 
401  /* computation of the local tile scanning base G according to h_tile
402  */
403  scanning_base_hyperplane(h_tile, dim, G);
404 }
405 
406 Psysteme
407 local_tile_constraints(Pbase initial_basis,Pbase local_tile_basis, Psysteme sc, matrice P, Pvecteur *pvch, statement st)
408 {
409  Psysteme mc = sc_dup(sc),mc2;
410  int dim = base_dimension(initial_basis);
411  int row;
412  int col;
413  Pbase civ = BASE_UNDEFINED;
414  Pbase ctv = BASE_UNDEFINED;
415  Value *h_tile; // hyperplane direction
416  int n = dim;
417  matrice V = matrice_new(n,n);
418  matrice G_tile = matrice_new(n,n);
419  bool legal=false;
420 
421  pips_assert("The two bases have the same dimension", dim == base_dimension(local_tile_basis));
422 
423  string local_tile_direction = (string) get_string_property("LOCAL_TILE_DIRECTION");
424  if (!empty_string_p(local_tile_direction) && strcmp(local_tile_direction,"LI") != 0) {
425  h_tile = (Value*)(malloc(n*sizeof(Value)));
426  if(strcmp(local_tile_direction,"LP") == 0) {
427  /* computation of the hyperplane tile direction in the tile basis: = sum(hi)= 1H */
428  compute_local_change_of_basis(h_tile, P, G_tile, 1 , n, 1);
429  matrice_general_inversion(G_tile,V,n);
430  legal = check_tiling_legality(st,V,n);
431  if (!legal)
432  matrice_identite(G_tile,n,0);
433  }
434  else // search a valid direction colinear to one of the partitioning vectors
435  if(strcmp(local_tile_direction,"LS") == 0) {
436  int pdim;
437  legal=false;
438  for (pdim=1; !legal && pdim<=n; pdim++) {
439  /* The local tile direction is legal and colinear to the partitioning vecteur (pdim) */
440  compute_local_change_of_basis(h_tile, P, G_tile, 2, n, pdim);
441  ifdebug(8) {
442  fprintf(stderr,"Check the legality of the chosen LOCAL basis");
443  (void) fprintf(stderr,"Temporary local tile scanning base G_tile obtained with %d-th Pvecteur :",pdim);
444  matrice_fprint(stderr, G_tile, n, n);
445  }
446  matrice_general_inversion(G_tile,V,n);
447  legal = check_tiling_legality(st,V,n);
448  }
449  if (pdim>n && !legal)
450  matrice_identite(G_tile,n,0);
451  }
452  }
453  else // the local tile direction is the original basis
454  matrice_identite(G_tile,n,0);
455 
456  ifdebug(8) {
457  (void) fprintf(stderr,"The local tile scanning base G_tile - i = G_tile.i_prime is :");
458  matrice_fprint(stderr, G_tile, n, n);
459  }
460  /* Build the constraints
461  0 <= det(HT).[HT. (i -i0)]<det(HT).1 with
462  i0=P.G_tile.i_tile
463  <==> 0 <= det(HT).[HT. (i -P.G_tile.i_tile)]<det(HT).1
464  <==> 0 <= det(HT).[HT.i -G_tile.i_tile]<= det(HT)-1
465  */
466  for(ctv = local_tile_basis; !VECTEUR_NUL_P(ctv) ; ctv = vecteur_succ(ctv)) {
468  sc_dimension(mc)++;
469  }
470  for(row = 1, civ = initial_basis; row <= dim; row++, civ = vecteur_succ(civ)) {
473 
474  for(col = 1, ctv = local_tile_basis; col <= dim ; col++, ctv = vecteur_succ(ctv)) {
475  if(ACCESS(G_tile, dim, row, col)!=VALUE_ZERO) {
476  Value coeff = ACCESS(G_tile, dim, row, col);
477  vect_add_elem(&veq, vecteur_var(ctv), -1*coeff);
478  }
479  }
480  ceq = contrainte_make(veq);
481  sc_add_egalite(mc, ceq);
482  }
483 
484  ifdebug(8) {
485  pips_debug(8, "End with constraint system mc:\n");
487  fprintf(stderr, "sc dimension = %d \n",mc->dimension);
488  }
489  mc2=sc_dup(mc);
490  sc_projection_along_variables_ofl_ctrl(&mc2,initial_basis , OFL_CTRL);
491  ifdebug(8) {
492  pips_debug(8, "End with constraint system mc after change of basis:\n");
494  }
495  scanning_base_to_vect(G_tile, n, local_tile_basis, pvch);
496  return mc2;
497 }
498 
499 
500 Pvecteur
502 {
504  list cs = list_undefined;
505 
506  for (cs = lls; cs != NIL; cs = CDR(cs)){
508  entity ind = loop_index(l);
509  range r = loop_range(l);
510  expression lower = range_lower(r);
511  intptr_t val;
512 
513  if(expression_integer_value(lower, &val)) {
514  vect_chg_coeff(&origin, (Variable) ind, (Value) val);
515  }
516  }
517 
518  return origin;
519 }
520 
521 /* Generate tiled code for a loop nest, PPoPP'91, p. 46, Figure 15.
522  *
523  * The row-echelon algorithm is called from new_loop_bound().
524  */
525 
527 {
528  Psysteme sci; /* iteration domain */
529  Psysteme sc_tile_scan;
530  Psysteme sc_tile;
531  Psysteme mc = SC_UNDEFINED; /* Tile membership constraints */
532  Psysteme sc_B_prime = SC_UNDEFINED;
533  Psysteme sc_B_second = SC_UNDEFINED;
534  Pbase initial_basis = NULL;
535  Pbase tile_basis = NULL;
536  Pbase reverse_tile_basis = NULL;
537  /* Pbase local_basis = NULL; */
538  Pbase new_basis = NULL;
539  matrice P; /* Partitioning matrix */
540  matrice HT; /* Transposed matrix of the inverse of P */
541  matrice G; /* Change of basis in the tile space to use vector 1 as hyperplane direction */
542  int n; /* number of indices, i.e. loop nest depth */
543  Value *h;
544  statement s_lhyp;
545  Pvecteur *pvg;
546  Pbase pb;
547  expression lower, upper;
548  int col;
549  Pvecteur to = VECTEUR_NUL; /* Tiling offset: 0 by default */
550 
551  debug_on("TILING_DEBUG_LEVEL");
552 
553  pips_debug(8, "Begin with iteration domain:\n");
554 
555  /* make the constraint system for the iteration space and find a good
556  origin for the tiling */
557 
558  const char* smatrix = get_string_property("LOOP_TILING_MATRIX");
559 
560  if (get_bool_property("PARTIAL_LOOP_TILING")) {
561  int ndim=0;
562  if (smatrix && !string_undefined_p(smatrix) && !empty_string_p(smatrix))
563  for (int k=1; k <=(int)strlen(smatrix); k++)
564  if (smatrix[k]==',') ndim++;
565  if (ndim!=0 && ndim<(int)gen_length(lls)-1) {
566  for (int k =1; k< (int)gen_length(lls)-ndim && lls != NIL; k++)
567  lls=CDR(lls);
568  }
569  }
570 
571  sci = loop_iteration_domaine_to_sc(lls, &initial_basis);
572  n = base_dimension(initial_basis);
573  to = loop_nest_to_offset(lls);
574  ifdebug(8) {
576  pips_debug(8,"And with origin:\n");
578  }
579 
580  /* computation of the partitioning matrix P and its inverse HT */
581 
582  P = matrice_new(n, n);
583  HT = matrice_new(n, n);
584  if(
585  !static_partitioning_matrix(P,n,smatrix) &&
587  ) {
588  pips_user_error("A proper partitioning matrix was not provided\n");
589  }
590 
591  ifdebug(8) {
592  pips_debug(8,"Partitioning matrix P:");
593  matrice_fprint(stderr, P, n, n);
594  (void) fprintf(stderr,"\n");
595  }
596 
597  matrice_general_inversion(P, HT, n);
598 
599  ifdebug(8) {
600  pips_debug(8,"Inverse partitioning matrix HT:");
601  matrice_fprint(stderr, HT, n, n);
602  (void) fprintf(stderr,"\n");
603  }
604 
605  /* Compute B': each iteration i in the iteration space is linked to its tile s */
606 
607  derive_new_basis(initial_basis, &tile_basis, make_tile_index_entity);
608  mc = tile_membership_constraints(initial_basis, tile_basis, HT, to);
609  mc = sc_normalize(mc);
610  ifdebug(8) {
611  (void) fprintf(stderr,"Tile membership constraints:\n");
613  }
614  /* mc and SC_B_prime are aliased after this call */
615  sc_B_prime = sc_append(mc, sci);
616  ifdebug(8) {
617  (void) fprintf(stderr,"sc_B_prime after call to sc_append (is the basis ok?):\n");
618  sc_fprint(stderr, sc_B_prime, (get_variable_name_t)entity_local_name);
619  }
620 
621 
622  mc = SC_UNDEFINED;
623  /* Save a copy to compute B" later */
624  sc_B_second = sc_dup(sc_B_prime);
625 
626  /* Get constraints on tile coordinates */
627 
628  sc_projection_along_variables_ofl_ctrl(&sc_B_prime, initial_basis, OFL_CTRL);
629  ifdebug(8) {
630  (void) fprintf(stderr,"Tile domain:\n");
631  sc_fprint(stderr, sc_B_prime, (get_variable_name_t)entity_local_name);
632  }
633 
634  /* Build the constraint system to scan the set of tiles */
635  sc_tile_scan = new_loop_bound(sc_B_prime, tile_basis);
636  ifdebug(8) {
637  (void) fprintf(stderr,"Tile domain in echelon format:\n");
638  sc_fprint(stderr, sc_tile_scan, (get_variable_name_t)entity_local_name);
639  }
640 
641  /* CA: Build the new basis (tile_basis+initial_basis)*/
642  /* base It, Jt, I, J pour notre exemple */
643  new_basis = vect_add(vect_dup(initial_basis),vect_dup(tile_basis));
644  ifdebug(8) {
645  (void) fprintf(stderr,"new_basis\n");
647  }
648 
649  /* Build the constraint system sc_tile to scan one tile (BS IN
650  PPoPP'91 paper) */
651  ifdebug(8) {
652  (void) fprintf(stderr,"sc_B_second:\n");
653  sc_fprint(stderr, sc_B_second, (get_variable_name_t)entity_local_name);
654  }
655  sc_tile = new_loop_bound(sc_B_second, new_basis);
656  ifdebug(8) {
657  (void) fprintf(stderr,"Iteration domain for one tile:\n");
659  }
660 
661  /* computation of the hyperplane tile direction: let's use the
662  default 1 vector */
663  h = (Value*)(malloc(n*sizeof(Value)));
664  for(col=0; col<n; col++) {
665  h[col] = VALUE_ONE;
666  }
667  /* computation of the tile scanning base G: right now, let's
668  * assume it's Id. This is OK to tile parallel loops... or to
669  * scan tiles sequentially on a monoprocessor.
670  */
671  G = matrice_new(n,n);
673  ifdebug(8) {
674  (void) fprintf(stderr,"The tile scanning base G is before ID:");
675  matrice_fprint(stderr, G, n, n);
676  }
677  matrice_identite(G, n, 0);
678  ifdebug(8) {
679  (void) fprintf(stderr,"The tile scanning base G is:");
680  matrice_fprint(stderr, G, n, n);
681  }
682 
683  /* generation of code for scanning one tile */
684 
685  /* Compute the local coordinate changes: there should be none for the time being
686  * because we keep the initial basis to scan iterations within one tile, i.e
687  * G must be the identity matrix
688  */
689  pvg = (Pvecteur *)malloc((unsigned)n*sizeof(Svecteur));
690  scanning_base_to_vect(G, n, initial_basis, pvg);
691  ifdebug(8) {
692  (void) fprintf(stderr,"The local coordinate change vector is:");
693  for (int i=1; i<=n; i++)
695  }
696  /* generation of code to scan one tile, and update of loop body using pvg */
697 
698  s_lhyp = code_generation(lls, pvg, initial_basis,
699  new_basis, sc_tile, false);
700 
701  /* generation of code for scanning all tiles */
702 
703  reverse_tile_basis = base_reversal(tile_basis);
704  for (pb = reverse_tile_basis; pb!=NULL; pb=pb->succ) {
705  loop tl = loop_undefined;
706 
707  make_bound_expression(pb->var, tile_basis, sc_tile_scan, &lower, &upper);
708  tl = make_loop((entity) vecteur_var(pb),
710  int_to_expression(1)),
711  s_lhyp,
714  NIL);
716  }
717 
718  pips_debug(8,"End\n");
719 
720  debug_off();
721 
722  return(s_lhyp);
723 }
724 
725 bool loop_tiling(const char* module_name)
726 {
727  bool return_status = false;
728 
730 
731  return return_status;
732 }
733 
734 
735 
736 static bool statement_in_loopnest_p = false;
739 {
742 }
743 
744 /*
745  Check that H.v >0
746  v is a dependence vecteur or a dependence vertex expressed in base b
747  Matrice H is the tiling scanning base, expressed in base b.
748  */
749 static void legal_point_p(Pvecteur v, Ptsg gs, matrice H,int dim, bool *legal)
750 {
751  Pbase b=gs->base;
752  Pvecteur coord;
753  int row, col, accu;
754  if(vect_in_basis_p(v, b)) {
755  for (row=1; row<=dim; row++) {
756  accu = 0;
757  for(coord = b, col=1; !VECTEUR_NUL_P(coord) && col<=dim; coord = coord->succ,col++) {
758  Variable var = vecteur_var(coord);
759  if(VARIABLE_DEFINED_P(var)) {
760  accu += vect_coeff(var, v)*ACCESS(H, dim, row, col);
761  }
762  }
763  if (accu <0) {
764  ifdebug(8) {
765  pips_debug(8,"Tile scanning matrix H:");
766  fprintf(stdout,"NON LEGAL TILING: H(%d,*)*SG =%d <0\n", row,accu);
767  sg_fprint_as_dense(stdout, gs, gs->base );
768  }
769  *legal=(*legal) && false;
770  }
771  else {
772  ifdebug(8) {
773  pips_debug(8,"Tile scanning matrix H:");
774  fprintf(stdout,"LEGAL TILING: H(%d,*)*SG =%d >=0\n", row,accu);
775  sg_fprint_as_dense(stdout, gs, gs->base );
776  }
777  }
778  }
779  }
780 }
781 
782 static void check_positive_dependence(Ptsg gs, matrice H,int dim, bool *legal)
783 {
784  if( sg_nbre_rayons(gs) > 0) {
785  for (Pray_dte e = sg_rayons(gs); e != NULL; e = e->succ) {
786  legal_point_p(e->vecteur, gs, H,dim, legal);
787  }
788  }
789  if( legal && sg_nbre_droites(gs) > 0) {
790  for (Pray_dte e = sg_droites(gs); e != NULL; e = e->succ) {
791  Pvecteur v=vect_copy(e->vecteur);
792  legal_point_p(e->vecteur, gs, H,dim, legal);
793  vect_chg_sgn(v);
794  legal_point_p(e->vecteur, gs, H,dim, legal);
795  vect_rm(v);
796  }
797  }
798  if( legal && sg_nbre_sommets(gs) > 0) {
799  for (Psommet e = sg_sommets(gs); e != NULL; e = e->succ) {
800  legal_point_p(e->vecteur, gs, H,dim, legal);
801  }
802  }
803 }
804 /*
805  Test whether H.D >0.
806  Returns TRUE if ok, FALSE otherwise
807  D is dependence cone (vertex, rays, lines) in base b
808  among all the dependence conflicts belonging to loopnest
809  Matrice H is a squared matrix of dimension dim.
810  It is the tiling scanning base, expressed in base b.
811  */
812 bool check_tiling_legality(statement loopnest_st, matrice H,int dim)
813 {
814  const char * module_name = get_current_module_name();
815  graph dg = (graph) db_get_memory_resource(DBR_DG, module_name, true);
816  int bl;
817  matrice HC;
818  // statement mod_stat = get_current_module_statement();
819  bool legal=true;
822  // Verify s is a statement in the loop nest
826 
829 
830  vertex v2 = successor_vertex(su);
831  statement s2 = vertex_to_statement( v2 );
832  // Verify s2 is a statement in the loop nest
836 
837  if(statement_in_loopnest_p) { // s and s2 are in the loop nest
839 
840  if ( conflict_cone(c) != cone_undefined ) {
841  //test H.D >0 for sommets, rays, and lines
843  if( !SG_UNDEFINED_P(gs)) {
844  Pbase b=gs->base;
845  bl=vect_size(b);
846 
847  if (bl==dim)
848  check_positive_dependence(gs, H,dim, &legal);
849  else {
850  if (bl > dim) {
851  HC=matrice_new(bl,bl);
852  int row,col;
853  ifdebug(8) {
854  fprintf(stdout," Different SIZES for base %d and matrice %d, Partial tiling case ?\n",bl,dim);
855  }
856  // Complete matrix Ht for the first non tiled dimension of the loop nest
857  // for 1<=i<=bl-dim, if di!=0 hji>=loop increment
858  // only loop with increment 1 are tiled ==> hji =1
859  matrice_identite(HC,bl,0);
860  DENOMINATOR(HC)=DENOMINATOR(H);
861  for (row=1; row<=bl; row++) {
862  if (row>=bl-dim+1) {
863  for(col=1; col<bl-dim+1;col++) {
864  ACCESS(HC, bl, row, col)=DENOMINATOR(H) ;
865  }
866  for(col=bl-dim+1; col<=bl;col++) {
867  ACCESS(HC, bl, row, col)= ACCESS(H, dim, row-bl+dim, col-bl+dim);
868  }
869  }
870  else {
871  ACCESS(HC, bl, row, row)=DENOMINATOR(H);
872  }
873  }
874  check_positive_dependence(gs, HC,bl, &legal);
875  matrice_free(HC);
876  }
877  else
878  pips_user_warning(" Different SIZES for dependence cone basis %d and partitioning matrice %d\n",bl,dim);
879  }
880  }
881  }
882  }
883  }
884  }
885  }
886  }
887  return(legal);
888 }
889 
891  Psysteme sc,
892  Pbase index_base)
893 {
894  Pvecteur lvar_proj;
895  Psysteme sc1 = sc_dup(sc);
896  int nb=vect_size(index_base);
897  // Automatic variables read in a CATCH block need to be declared volatile as
898  // specified by the documentation
899  volatile Psysteme sc2,sc3;
900  sc3=sc_init_with_sc(sc);
901 
902  if (!VECTEUR_NUL_P(index_base))
903  {
904  volatile Pvecteur pv1;
905  lvar_proj = vect_copy(base_reversal(index_base));
906  sc2 = sc_copy(sc);
907  for (pv1 = lvar_proj;!VECTEUR_NUL_P(pv1) && nb>1; pv1=pv1->succ, nb--) {
908 
910  sc_elim_var(sc2, vecteur_var(pv1));
911  }
912  TRY {// force the overflow forwarding in order to apply sc_elim_var in case of overflow
913  sc_projection_along_variable_ofl_ctrl
914  (&sc2,vecteur_var(pv1), FWD_OFL_CTRL);
916  }
917  sc2 = sc_normalize(sc2);
918  if (SC_EMPTY_P(sc2)) {
919  sc2 = sc_empty(base_copy(sc->base));
920  break;
921  }
922  else {
924  }
925  // Concatenation of the intermediate system sc2 resulting
926  // from the projection of pv1 and the previous concatenated system sc3
927  sc3 = sc_append(sc3,sc2);
928  if (SC_EMPTY_P(sc3)) {
929  sc3 = sc_empty(base_copy(sc->base));
930  break;
931  }
932  }
933  }
934  sc1 = sc_append(sc1,sc3);
935  sc1 = sc_normalize(sc1);
936  if (SC_EMPTY_P(sc1))
937  sc1 = sc_empty(base_copy(sc->base));
938  return sc1;
939 }
940 
941 
943 {
944  Psysteme sci; /* iteration domain */
945  Psysteme sc_tile;
946  Psysteme sc_local_tile;
947  Psysteme mc = SC_UNDEFINED; /* Tile membership constraints */
948  Psysteme sc_B_prime = SC_UNDEFINED;
949  Psysteme sc_B_prime_2 = SC_UNDEFINED;
950  Pbase initial_basis = NULL;
951  Pbase tile_basis = NULL;
952  Pbase local_tile_basis = NULL;
953  Pbase reverse_tile_basis = NULL;
954  Pbase new_basis = NULL;
955  matrice P; /* Partitioning matrix */
956  matrice HT; /* Transposed matrix of the inverse of P */
957  int n,i; /* number of indices, i.e. loop nest depth */
958  statement s_lhyp;
959  Pvecteur *pvch;
960  Pbase pb;
961  expression lower, upper;
962  Pvecteur to = VECTEUR_NUL; /* Tiling offset: 0 by default */
964  list lls2; // first loop in the loop nest;
965 #define maxscinfosize 100
966  int sc_info[maxscinfosize][4];
967  Psysteme sc_proj2,sc_tmp;
968  int space;
969  Psysteme *list_of_systems;
972 
973  debug_on("TILING_DEBUG_LEVEL");
974  pips_debug(8, "Begin with iteration domain:\n");
975  const char* smatrix = get_string_property("LOOP_TILING_MATRIX");
976 
977  if (get_bool_property("PARTIAL_LOOP_TILING")) {
978  int ndim=0;
979  if (smatrix && !string_undefined_p(smatrix) && !empty_string_p(smatrix))
980  for (int k=1; k <=(int)strlen(smatrix); k++)
981  if (smatrix[k]==',') ndim++;
982  if (ndim!=0 && ndim<(int)gen_length(lls)-1) {
983  for (int k =1; k< (int)gen_length(lls)-ndim && lls != NIL; k++)
984  lls=CDR(lls);
985  }
986  }
987  // keep the original statement in case of NOT legal tiling
988  for (lls2=lls;(int)gen_length(lls2)>1 && lls2 != NIL; lls2=CDR(lls2));
989  stmf=STATEMENT(CAR(lls2));
990 
991  sci = loop_iteration_domaine_to_sc(lls, &initial_basis);
992  n = base_dimension(initial_basis);
993  to = loop_nest_to_offset(lls);
994  ifdebug(8) {
996  pips_debug(8,"And with origin:\n");
998  }
999 
1000  /* computation of the partitioning matrix P and its inverse HT */
1001  P = matrice_new(n, n);
1002  HT = matrice_new(n, n);
1003  if(
1004  !static_partitioning_matrix(P,n,smatrix) &&
1006  ) {
1007  pips_user_error("A proper partitioning matrix was not provided\n");
1008  }
1009 
1010  ifdebug(8) {
1011  pips_debug(8,"Partitioning matrix P:");
1012  matrice_fprint(stderr, P, n, n);
1013  (void) fprintf(stderr,"\n");
1014  }
1015  matrice_general_inversion(P, HT, n);
1016  ifdebug(8) {
1017  pips_debug(8,"Inverse partitioning matrix HT = P^-1:");
1018  matrice_fprint(stderr, HT, n, n);
1019  (void) fprintf(stderr,"\n");
1020  }
1021  /* make the constraint system for the iteration space and find a good
1022  origin for the tiling if the transformation is legal*/
1023  if (!get_bool_property("CHECK_TRANSFORMATION_LEGALITY") || check_tiling_legality(STATEMENT(CAR(lls2)),HT,n)) {
1024 
1025  derive_new_basis(initial_basis, &tile_basis, make_tile_index_entity);
1026  derive_new_basis(initial_basis, &local_tile_basis, make_local_tile_index_entity);
1027  /* Compute B': each iteration i in the iteration space is linked to its tile s */
1028 
1029  mc = tile_hyperplane_constraints(initial_basis, tile_basis, HT, to);
1030  mc = sc_normalize(mc);
1031  ifdebug(8) {
1032  (void) fprintf(stderr,"Tile membership constraints:\n");
1034  }
1035  /* mc and SC_B_prime are aliased after this call */
1036  sc_B_prime = sc_append(mc, sci);
1037  ifdebug(8) {
1038  (void) fprintf(stderr,"sc_B_prime after call to sc_append :\n");
1039  sc_fprint(stderr, sc_B_prime, (get_variable_name_t)entity_user_name);
1040  }
1041 
1042  /* computation of the base scanning local tile elements and its constraints*/
1043  pvch = (Pvecteur *)malloc((unsigned)n*sizeof(Svecteur));
1044  sc_B_prime_2= local_tile_constraints(initial_basis,local_tile_basis,sc_B_prime, P, pvch, STATEMENT(CAR(lls2)));
1045 
1046  ifdebug(8) {
1047  (void) fprintf(stderr,"sc_B_prime2 after change of local basis:\n");
1048  sc_fprint(stderr, sc_B_prime_2, (get_variable_name_t)entity_user_name);
1049  }
1050 
1051  /* Build the new basis (tile_basis+local_tile_basis)*/
1052  new_basis = vect_add(vect_dup(local_tile_basis),vect_dup(tile_basis));
1053  ifdebug(8) {
1054  (void) fprintf(stderr,"new_basis\n");
1055  vect_fprint(stderr, new_basis, (get_variable_name_t)entity_user_name);
1056  }
1057  {
1058  sc_tmp= sc_dup(sc_B_prime_2);
1059  space = (vect_size(new_basis)+1) * sizeof(Ssysteme);
1060  list_of_systems = (Psysteme *) malloc((unsigned) space);
1061 
1062  sc_proj2 = sc_dup(sc_B_prime_2);
1063  // Add redundant constraints on intermediate loop indices to improve the generated code
1064  sc_proj2 = sc_projection_concat_proj_on_variables(sc_proj2,new_basis);
1065  sc_integer_projection_information(sc_proj2,new_basis, sc_info,sc_proj2->dimension,sc_proj2->dimension);
1066  sc_proj2=build_integer_sc_nredund(sc_proj2,new_basis,sc_info,1,sc_proj2->dimension,sc_proj2->dimension);
1067 
1068  // Distribute constraints according to loop nest indices of new_basis
1069  for (i=1;i<=sc_proj2->dimension;i++)
1070  list_of_systems[i] = sc_init_with_sc(sc_proj2);
1071  constraint_distribution(sc_proj2,list_of_systems,new_basis,sc_info);
1072 
1073  // Remove redundant constraints according to the cumulated constraints from outer to inner loop bounds
1074  sc_tmp=sc_dup(list_of_systems[1]);
1075  for (i = 2; sc_tmp != NULL && i <=vect_size(new_basis);i++) {
1076  list_of_systems[i] = elim_redund_sc_with_sc(list_of_systems[i],
1077  sc_tmp,
1078  new_basis,
1079  vect_size(new_basis));
1080  ifdebug(8) {
1081  fprintf(stdout," Constraints on the %d-th var. :\n",i);
1082  sc_fprint(stdout,list_of_systems[i],(get_variable_name_t)entity_user_name);
1083  }
1084  sc_tmp=sc_intersection(sc_tmp,sc_tmp,list_of_systems[i]);
1085  }
1086  sc_rm(sc_tmp);
1087 
1088  // Build system sc_tile to scan one tile
1089  sc_tile =sc_dup(list_of_systems[1]);
1090  for (i=2; i<=vect_size(tile_basis);i++)
1091  sc_tile =sc_intersection(sc_tile,sc_tile,list_of_systems[i]);
1092  ifdebug(8) {
1093  (void) fprintf(stderr,"Tile domain in echelon format:\n");
1094  sc_fprint(stderr, sc_tile, (get_variable_name_t)entity_user_name);
1095  }
1096  // Constraint system sc_tile to scan one tile
1097  sc_local_tile =sc_dup(list_of_systems[i]);
1098  i++;
1099  for (; i<=vect_size(tile_basis)+vect_size(local_tile_basis);i++)
1100  sc_local_tile =sc_intersection(sc_local_tile,sc_local_tile,list_of_systems[i]);
1101  ifdebug(8) {
1102  (void) fprintf(stderr,"Iteration domain for one tile:\n");
1103  sc_fprint(stderr, sc_local_tile, (get_variable_name_t)entity_user_name);
1104  }
1105  }
1106 
1107  /* generation of code for scanning one tile */
1108  ifdebug(8) {
1109  (void) fprintf(stderr,"The local coordonate change vector is:");
1110  for (int i=1; i<=n; i++)
1112  }
1113  /* generation of code to scan one tile and update of loop body using pvch */
1114  s_lhyp = code_generation(lls, pvch, initial_basis,
1115  local_tile_basis, sc_local_tile, false);
1116 
1117  /* generation of code for scanning all tiles */
1118  reverse_tile_basis = base_reversal(tile_basis);
1119  for (pb = reverse_tile_basis; pb!=NULL; pb=pb->succ) {
1120  loop tl = loop_undefined;
1121 
1122  make_bound_expression(pb->var, tile_basis, sc_tile, &lower, &upper);
1123  tl = make_loop((entity) vecteur_var(pb),
1125  int_to_expression(1)),
1126  s_lhyp,
1129  NIL);
1131  }
1132  stmf =s_lhyp;
1133  }
1134  else pips_user_warning("PIPS legality test for Tiling transformation NOT VERIFIED, Verify data dependencies or simplify array access functions\n");
1135 
1136  pips_debug(8,"End\n");
1137 
1138  debug_off();
1140  return(stmf);
1141 }
1142 
1144 {
1145  bool return_status = false;
1147  return return_status;
1148 }
static void statement_in_loopnest(statement s)
Definition: tiling.c:738
static statement test_statement_of_reference
Definition: tiling.c:737
Psysteme local_tile_constraints(Pbase initial_basis, Pbase local_tile_basis, Psysteme sc, matrice P, Pvecteur *pvch, statement st)
Definition: tiling.c:407
statement parallel_tiling(list lls, _UNUSED_ bool(*u)(statement))
Definition: tiling.c:942
Pvecteur loop_nest_to_offset(list lls)
Definition: tiling.c:501
bool parallel_loop_tiling(const char *module_name)
Definition: tiling.c:1143
bool loop_tiling(const char *module_name)
Definition: tiling.c:725
Psysteme sc_projection_concat_proj_on_variables(Psysteme sc, Pbase index_base)
Definition: tiling.c:890
static entity make_local_tile_index_entity(entity old_index)
Definition: tiling.c:98
#define maxscinfosize
dg_vertex_label vertex_label
Definition: tiling.c:77
static Psysteme tile_membership_constraints(Pbase initial_basis, Pbase tile_basis, matrice HT, Pvecteur tiling_offset)
Generate the tile membership constraints between a tile coordinates and an iteration coordinate.
Definition: tiling.c:209
bool static_partitioning_matrix(matrice P, int n, const char *serialized_matrix)
tiling.c
Definition: tiling.c:104
statement tiling_transformation(list lls, _UNUSED_ bool(*u)(statement))
Generate tiled code for a loop nest, PPoPP'91, p.
Definition: tiling.c:526
bool check_tiling_legality(statement loopnest_st, matrice H, int dim)
Definition: tiling.c:812
static void legal_point_p(Pvecteur v, Ptsg gs, matrice H, int dim, bool *legal)
Definition: tiling.c:749
dg_arc_label arc_label
package tiling
Definition: tiling.c:76
Psysteme tile_hyperplane_constraints(Pbase initial_basis, Pbase tile_basis, matrice HT, Pvecteur tiling_offset)
Generate the tile membership constraints between a tile coordinates and an iteration coordinate.
Definition: tiling.c:274
static entity make_tile_index_entity(entity old_index)
Create a new entity for tile index.
Definition: tiling.c:93
static bool statement_in_loopnest_p
Definition: tiling.c:736
static void check_positive_dependence(Ptsg gs, matrice H, int dim, bool *legal)
Definition: tiling.c:782
bool interactive_partitioning_matrix(matrice P, int n)
Query the user for a partitioning matrix P.
Definition: tiling.c:137
static void compute_local_change_of_basis(Value *h_tile, matrice P, matrice G, int option, int dim, int selected_Pdim)
Definition: tiling.c:376
void user_log(const char *format,...)
Definition: message.c:234
execution make_execution(enum execution_utype tag, void *val)
Definition: ri.c:838
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
range make_range(expression a1, expression a2, expression a3)
Definition: ri.c:2041
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
#define VALUE_ZERO
#define value_uminus(val)
unary operators on values
void const char const char const int
#define VALUE_FMT
int Value
#define VALUE_ONE
Pbase base_add_variable(Pbase b, Variable var)
Pbase base_add_variable(Pbase b, Variable v): add variable v as a new dimension to basis b at the end...
Definition: base.c:88
bool vect_in_basis_p(Pvecteur v, Pbase b)
Pvecteur vect_in_basis_p(Pvecteur v, Pbase b): check that all coordinates in v are in b,...
Definition: base.c:342
Pbase base_reversal(Pbase b_in)
Pbase base_reversal(Pbase b_in): produces a basis b_out, having the same basis vectors as b_in,...
Definition: base.c:221
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
void derive_new_basis(Pbase base_oldindex, Pbase *base_newindex, entity(*new_entity)(entity))
package conversion
void scanning_base_to_vect(matrice G, int n, Pbase base, pvg)
void scanning_base_to_vect(matrice G,int n,Pbase base,Pvecteur pvg[n]) compute G*base and put the res...
statement code_generation(list lls, Pvecteur pvg[], Pbase base_oldindex, Pbase base_newindex, Psysteme sc_newbase, bool preserve_entry_label_p)
package hyperplane
void constraint_distribution(Psysteme sc, Psysteme *bound_systems, Pbase index_base, int sc_info[][4])
Distribution of the constraints of the system sc into several systems.
#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
Psysteme loop_iteration_domaine_to_sc(list, Pbase *)
loop_iteration_domaine_to_sc.c
struct _newgen_struct_status_ * status
Definition: database.h:31
#define cone_generating_system(x)
Definition: dg.h:130
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define cone_undefined
Definition: dg.h:104
#define conflict_cone(x)
Definition: dg.h:169
static Value offset
Definition: translation.c:283
bool empty_string_p(const char *s)
Definition: entity_names.c:239
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
char * get_string_property(const char *)
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void * malloc(YYSIZE_T)
void free(void *)
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
#define vertex_successors(x)
Definition: graph.h:154
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#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 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 list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
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
void scanning_base_hyperplane(Value[], int, matrice)
scanning_base.c
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
bool interactive_loop_transformation(const char *module_name, statement(*loop_transformation)(list, bool(*)(statement)))
float_t space[SIZE][SIZE]
Definition: jacobi.c:7
void vect_fprint(FILE *f, Pvecteur v, get_variable_name_t variable_name)
void vect_fprint(FILE * f, Pvecteur v, char * (*variable_name)()): impression d'un vecteur creux v su...
Definition: io.c:124
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define DENOMINATOR(matrix)
int DENOMINATEUR(matrix): acces au denominateur global d'une matrice matrix La combinaison *(&()) est...
Definition: matrice-local.h:93
#define matrice_free(m)
Definition: matrice-local.h:78
#define ACCESS(matrix, column, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrice-local.h:86
#define matrice_new(n, m)
Allocation et desallocation d'une matrice.
Definition: matrice-local.h:77
Value * matrice
package matrice
Definition: matrice-local.h:71
void matrice_general_inversion(matrice a, matrice inv_a, int n)
void matrice_general_inversion(matrice a; matrice inv_a; int n) calcul de l'inversion du matrice gene...
Definition: inversion.c:222
void matrice_identite(matrice, int, int)
void matrice_identite(matrice ID, int n, int level) Construction d'une sous-matrice identite dans ID(...
Definition: sous-matrice.c:322
void matrice_fprint(FILE *, matrice, int, int)
matrice_io.c
Definition: matrice_io.c:62
#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_user_warning
Definition: misc-local.h:146
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#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
string user_request(const char *,...)
Psysteme elim_redund_sc_with_sc(Psysteme sc1, Psysteme sc2, Pbase index_base, int dim)
Build the system of inequations of sc1 no-redundant with system sc2.
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#define string_undefined_p(s)
Definition: newgen_types.h:41
#define UU
Definition: newgen_types.h:98
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
void make_bound_expression(Variable index, Pbase base, Psysteme sc, expression *lower, expression *upper)
void make_bound_expression(variable index, Pbase base, Psysteme sc, expression *lower,...
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
entity entity_empty_label(void)
Definition: entity.c:1105
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
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
entity make_new_index_entity(entity, string)
Definition: variable.c:1851
#define loop_undefined
Definition: ri.h:1612
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
@ is_instruction_loop
Definition: ri.h:1471
#define range_lower(x)
Definition: ri.h:2288
#define statement_instruction(x)
Definition: ri.h:2458
#define loop_range(x)
Definition: ri.h:1642
@ is_execution_sequential
Definition: ri.h:1189
#define statement_number(x)
Definition: ri.h:2452
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
Psysteme sc_init_with_sc(Psysteme sc)
This function returns a new empty system which has been initialized with the same dimension and base ...
Definition: sc_alloc.c:303
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Psysteme sc_copy(Psysteme ps)
Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation et copie complete des champs sans...
Definition: sc_alloc.c:230
void build_sc_nredund_1pass(Psysteme volatile *ps)
Computation of a new system sc from the system ps, where each constraint of the system ps is added to...
Psysteme build_integer_sc_nredund(volatile Psysteme ps, Pbase index_base, int tab_info[][4], int loop_level, int dim_h __attribute__((unused)), int n __attribute__((unused)))
Computation of a new system sc from the system ps, where each constraint of the system ps is added to...
void sc_integer_projection_information(Psysteme sc, Pbase index_base, int sc_info[][4], int dim_h, int n)
This function gives information about the variables and the constraints of the system.
Psysteme sc_append(Psysteme s1, Psysteme s2)
Psysteme sc_append(Psysteme s1, Psysteme s2): calcul de l'intersection des polyedres definis par s1 e...
Psysteme sc_intersection(Psysteme s1, Psysteme s2, Psysteme s3)
Psysteme sc_intersection(Psysteme s1, Psysteme s2, Psysteme s3): calcul d'un systeme de contraintes s...
void sc_fprint(FILE *fp, Psysteme ps, get_variable_name_t nom_var)
void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()): cette fonction imprime dans le fichier po...
Definition: sc_io.c:220
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
int printf()
Psysteme new_loop_bound(Psysteme scn, Pbase base_index)
Psysteme new_loop_bound(Psysteme scn, Pbase base_index) computation of the new iteration space (given...
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
#define G(j, a, b)
maybe most of them should be functions?
Psysteme sc_elim_var(Psysteme sc, Variable v)
package sur les systemes de contraintes sc
Definition: sc_unaires.c:49
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
static int line
FLEX_SCANNER.
Definition: scanner.c:852
#define sg_sommets(sg)
vieilles definitions des fonctions d'impression void sg_fprint(); #define print_sg(sg) sg_fprint(stdo...
Definition: sg-local.h:85
#define sg_rayons(sg)
acces au premier rayon de la liste des rayons d'un systeme generateur defini par un pointeur: sg_rayo...
Definition: sg-local.h:89
struct type_sg * Ptsg
Representation d'un systeme generateur par trois ensembles de sommets de rayons et de droites.
#define sg_nbre_sommets(sg)
nombre de sommets: int sg_nbre_sommets(Ptsg)
Definition: sg-local.h:96
#define SG_UNDEFINED_P(sg)
Definition: sg-local.h:74
#define sg_nbre_droites(sg)
nombre de droites: int sg_nbre_droites(Ptsg)
Definition: sg-local.h:102
#define sg_nbre_rayons(sg)
nombre de rayons: int sg_nbre_rayons(Ptsg)
Definition: sg-local.h:99
#define sg_droites(sg)
acces a la premiere droite de la liste des droites d'un systeme generateur defini par un pointeur: sg...
Definition: sg-local.h:93
#define ifdebug(n)
Definition: sg.c:47
void sg_fprint_as_dense(FILE *f, Ptsg sg, Pbase b)
void sg_fprint_as_dense(FILE * f, Ptsg sg): impression d'un systeme generateur
Definition: sg.c:298
static statement origin
Definition: simdizer.c:411
#define intptr_t
Definition: stdint.in.h:294
static string buffer
Definition: string.c:113
Pbase base
Definition: sc-local.h:75
int dimension
Definition: sc-local.h:74
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
structure de donnees Sommet
Definition: sommet-local.h:64
Representation d'un systeme generateur par trois ensembles de sommets de rayons et de droites.
Definition: sg-local.h:66
Pbase base
Definition: sg-local.h:70
#define VARIABLE_DEFINED_P(v)
Definition: vecteur-local.h:66
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
#define vecteur_succ(v)
#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 FWD_OFL_CTRL
#define BASE_UNDEFINED
#define base_dimension(b)
#define OFL_CTRL
I do thing that overflows are managed in a very poor manner.
struct Svecteur Svecteur
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Pbase vect_copy(Pvecteur b)
direct duplication.
Definition: alloc.c:240
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
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
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val)
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val): mise de la coordonnee var du vecteur *pp...
Definition: unaires.c:143