PIPS
utils.c
Go to the documentation of this file.
1 /*
2 
3  $Id: utils.c 23065 2016-03-02 09:05:50Z 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 
28 /* Name : utils.c
29  * Package : paf-util
30  * Author : Alexis Platonoff
31  * Date : july 1993
32  *
33  * Historic :
34  * - 16 jul 93, change in paf_ri, AP
35  * - 23 sep 93, remove some functions from paf_ri to placement, AP
36  * - 29 sep 93, remove prefixes when they are not needed (adg, plc, ...), AP
37  * - 9 nov 93, add merge_sort() and meld(), AP
38  * - 9 dec 93, add rational_op_exp(), AP
39  * - 21 fev 94, add prototype_var_subst(), AP
40  * - 21 fev 94, add vecteur_mult(), AP
41  * - 25 fev 94, add prototype_factorize(), modify vecteur_to_polynome(), AP
42  * - 11 mar 94, modify polynome_to_sc(), AP
43  * - 7 apr 94, add pu_constraints_with_sym_cst_to_matrices() and
44  * pu_matrices_to_constraints_with_sym_cst(), AP
45  * - 29 jun 94, add simplify_minmax(), AP
46  * - 9 nov 94, modify name : merge_sort() --> general_merge_sort()
47  * because it already exists in C3, AP
48  * - 14 nov 94, add find_implicit_equation(), taken from prgm_mapping, AP
49  * - 20 dec 94, add functions for the static control map, AP
50  * - 19 jan 95, move make_rational_vect() in this file from scheduling and
51  * reindexing packages, AP
52  * - 25 sep 95, moved stco_common_loops_of_statements() in this file from
53  * static_controlise/utils.c, AP
54  *
55  * Documents:
56  *
57  * Comments : This file contains useful functions used for the computation of
58  * paf_ri.
59  */
60 
61 /* Ansi includes */
62 #include <stdio.h>
63 #include <string.h>
64 /* #include <varargs.h> */ /* (not ANSI but SUN:-) */
65 
66 /* Newgen includes */
67 #include "genC.h"
68 
69 /* C3 includes */
70 #include "boolean.h"
71 #include "arithmetique.h"
72 #include "vecteur.h"
73 #include "contrainte.h"
74 #include "ray_dte.h"
75 #include "sommet.h"
76 #include "sg.h"
77 #include "sc.h"
78 #include "polyedre.h"
79 #include "matrix.h"
80 
81 /* Pips includes */
82 #include "linear.h"
83 #include "ri.h"
84 #include "ri-util.h"
85 #include "prettyprint.h"
86 #include "constants.h"
87 #include "paf_ri.h"
90 #include "graph.h"
91 #include "dg.h"
92 #include "text.h"
93 #include "text-util.h"
94 #include "misc.h"
95 #include "paf-util.h"
96 #include "static_controlize.h"
97 
98 // Forward declaration to survive races in the compilation process
100 
101 /* Macro functions */
102 #define STRING_FOUR_OPERATION_P(s) ( \
103  (strcmp(s,PLUS_OPERATOR_NAME) == 0) || \
104  (strcmp(s,MINUS_OPERATOR_NAME) == 0) || \
105  (strcmp(s,MULTIPLY_OPERATOR_NAME) == 0) || \
106  (strcmp(s,DIVIDE_OPERATOR_NAME) == 0) )
107 #define ENTITY_FOUR_OPERATION_P(s) (ENTITY_PLUS_P(s) || ENTITY_MINUS_P(s) || ENTITY_MULTIPLY_P(s) || ENTITY_DIVIDE_P(s))
108 
109 /* Global variables */
110 
111 /* Internal variables */
112 
113 /* Local defines: FI, they are needed earlier in the file because
114  newgen is now fully typed statically */
115 /*
116 typedef dfg_arc_label arc_label;
117 typedef dfg_vertex_label vertex_label;
118 */
119 
120 /* begin MATRIX functions */
121 
122 /*=========================================================================*/
123 /*
124  * void matrix_scalar_multiply(A, nb)
125  *
126  * multiplies all elements of matrix A by the number nb.
127  *
128  */
129 /* never called
130 void matrix_scalar_multiply(A, nb)
131 Pmatrix A;
132 int nb;
133 {
134  int i, j, m, n, d, p;
135 
136  m = MATRIX_NB_LINES(A);
137  n = MATRIX_NB_COLUMNS(A);
138  d = MATRIX_DENOMINATOR(A);
139  p = pgcd(d, nb);
140 
141  MATRIX_DENOMINATOR(A) = d/p;
142  for (i = 1; i <= m; i++)
143  for (j = 1; j <= n; j++)
144  MATRIX_ELEM(A,i,j) = (nb/p) * MATRIX_ELEM(A,i,j);
145 }
146 */
147 
148 /*=====================================================================*/
149 /*
150  * void matrix_add(Pmatrix a, Pmatrix b, Pmatrix c)
151  *
152  * add rational matrix c to rational matrix b and store result
153  * in matrix a
154  *
155  * a is a (nxm) matrix, b a (nxm) and c a (nxm)
156  *
157  * a = b + c ;
158  *
159  * Algorithm used is directly from definition, and space has to be
160  * provided for output matrix a by caller. Matrix a is not necessarily
161  * normalized: its denominator may divide all its elements
162  * (see matrix_normalize()).
163  *
164  * Precondition: n > 0; m > 0;
165  * Note: aliasing between a and b or c is supported
166  */
167 /* never called
168 void pu_matrix_add(a,b,c)
169 Pmatrix a;
170 Pmatrix b, c;
171 {
172  int d1, d2, i, j, n, m;
173 
174  n = MATRIX_NB_LINES(a);
175  m = MATRIX_NB_COLUMNS(a);
176  pips_assert("matrix_add", (n > 0) && (m > 0));
177 
178  d1 = MATRIX_DENOMINATOR(b);
179  d2 = MATRIX_DENOMINATOR(c);
180  if (d1 == d2) {
181  for (i = 1; i <= n; i++)
182  for (j = 1; j <= m; j++)
183  MATRIX_ELEM(a,i,j)=MATRIX_ELEM(b,i,j)+MATRIX_ELEM(c,i,j);
184  MATRIX_DENOMINATOR(a) = d1;
185  }
186  else {
187  int lcm = ppcm(d1,d2);
188  d1 = lcm/d1;
189  d2 = lcm/d2;
190  for (i = 1; i <= n; i++)
191  for (j = 1; j <= m; j++)
192  MATRIX_ELEM(a,i,j)=MATRIX_ELEM(b,i,j)*d1+MATRIX_ELEM(c,i,j)*d2;
193  MATRIX_DENOMINATOR(a) = lcm;
194  }
195 }
196 */
197 
198 /* ======================================================================= */
199 /*
200  * void constraints_with_sym_cst_to_matrices(Pcontrainte pc, Pbase ib, cb,
201  * Pmatrix A B)
202  *
203  * constructs the matrices "A" and "B" corresponding to the linear
204  * constraints "pc", so: A.ib + B1.cb + B2 = 0 <=> pc(ib, cb) = 0
205  *
206  * B = ( B1 | B2 ), B2 of dimension (n,1).
207  *
208  * The basis "ib" gives the variables of the linear system.
209  * The basis "cb" gives the symbolic constants of the linear system.
210  *
211  * WARNING: "cb" should not contain TCST.
212  *
213  * The matrices "A" and "B" are supposed to have been already allocated in
214  * memory, respectively of dimension (n, m1) and (n, m2):
215  *
216  * n must be the exact number of constraints in "pc".
217  * m1 must be the exact number of variables in "ib".
218  * m2 must be the exact number of variables in "cb" PLUS ONE (TCST).
219  */
220 /* never called
221 void pu_constraints_with_sym_cst_to_matrices(pc,ib,cb,A,B)
222 Pcontrainte pc;
223 Pbase ib,cb;
224 Pmatrix A, B;
225 {
226  int i,j;
227  Pcontrainte eq;
228  Pvecteur pv;
229  int n, m1, m2;
230 
231  for (eq = pc, n = 0; !CONTRAINTE_UNDEFINED_P(eq); eq=eq->succ) { n++; }
232  m1 = vect_size(ib);
233  m2 = vect_size(cb) + 1;
234 
235  pips_assert("constraints_with_sym_cst_to_matrices",
236  (MATRIX_NB_LINES(A) == n) && (MATRIX_NB_COLUMNS(A) == m1) &&
237  (MATRIX_NB_LINES(B) == n) && (MATRIX_NB_COLUMNS(B) == m2));
238 
239  matrix_nulle(B);
240  matrix_nulle(A);
241 
242  for (eq = pc,i=1; !CONTRAINTE_UNDEFINED_P(eq); eq=eq->succ,i++) {
243  for(pv = ib, j=1; pv != NULL; pv = pv->succ, j++){
244  MATRIX_ELEM(A,i,j) = vect_coeff(vecteur_var(pv),eq->vecteur);
245  }
246  for(pv = cb, j=1; pv != NULL; pv = pv->succ, j++){
247  MATRIX_ELEM(B,i,j) = vect_coeff(vecteur_var(pv),eq->vecteur);
248  }
249  MATRIX_ELEM(B,i,m2) = vect_coeff(TCST,eq->vecteur);
250  }
251 }
252 */
253 
254 /* ======================================================================= */
255 /*
256  * void matrices_to_constraints_with_sym_cst(Pcontrainte *pc, Pbase ib, cb,
257  * Pmatrix A, B)
258  *
259  * constructs the constraints "pc" corresponding to the matrices "A" and "B"
260  * so: pc(ib, cb) = 0 <=> A.ib + B1.cb + B2 = 0
261  *
262  * B = ( B1 | B2 ), B2 of dimension (n,1).
263  *
264  * The basis "ib" gives the variables of the linear system.
265  * The basis "cb" gives the symbolic constants of the linear system.
266  *
267  * Matrices "A" and "B" are supposed to have been already allocated in
268  * memory, respectively of dimension (n, m1) and (n, m2).
269  *
270  * n must be the exact number of constraints in "pc".
271  * m1 must be the exact number of variables in "ib".
272  * m2 must be the exact number of variables in "cb" PLUS ONE (TCST).
273  *
274  * "A" and "B" may be rationnal. In such case, we compute the least common
275  * multiple of their denominators and multiply the system by it:
276  *
277  * Note: the formal parameter pc is a "Pcontrainte *". Instead, the resulting
278  * Pcontrainte could have been returned as the result of this function.
279  */
280 /* never called
281 void pu_matrices_to_constraints_with_sym_cst(pc,ib,cb,A,B)
282 Pcontrainte *pc;
283 Pbase ib,cb;
284 Pmatrix A, B;
285 {
286  Pcontrainte newpc = NULL;
287  int i, j, coeff, dena, denb, n, m1, m2, lcm;
288 
289  n = MATRIX_NB_LINES(A);
290  m1 = MATRIX_NB_COLUMNS(A);
291  m2 = MATRIX_NB_COLUMNS(B);
292 
293  pips_assert("constraints_with_sym_cst_to_matrices",
294  (MATRIX_NB_LINES(B) == n) &&
295  (vect_size(ib) == m1) && ((vect_size(cb) + 1) == m2));
296 
297  dena = MATRIX_DENOMINATOR(A);
298  denb = MATRIX_DENOMINATOR(B);
299  lcm = ppcm(dena, denb);
300 
301  for (i=n;i>=1; i--) {
302  bool found = false;
303  Pcontrainte cp = contrainte_new();
304  Pvecteur vect, pv = NULL;
305 
306  if ((coeff = MATRIX_ELEM(B,i,m2)) != 0) {
307  pv = vect_new(TCST, (lcm/denb) * coeff);
308  found = true;
309  }
310  for (j=1, vect=ib;j<=m1;vect=vect->succ,j++) {
311  if ((coeff = MATRIX_ELEM(A,i,j)) != 0)
312  if (found)
313  vect_chg_coeff(&pv, vecteur_var(vect),(lcm/dena) * coeff);
314  else {
315  pv = vect_new(vecteur_var(vect), (lcm/dena) * coeff);
316  found = true;
317  }
318  }
319  for (j=1, vect=cb;j<=m2-1;vect=vect->succ,j++) {
320  if ((coeff = MATRIX_ELEM(B,i,j)) != 0)
321  if (found)
322  vect_chg_coeff(&pv, vecteur_var(vect),(lcm/denb) * coeff);
323  else {
324  pv = vect_new(vecteur_var(vect), (lcm/denb) * coeff);
325  found = true;
326  }
327  }
328  cp->vecteur = pv;
329  cp->succ = newpc;
330  newpc = cp;
331  }
332  *pc = newpc;
333 }
334 */
335 
336 /*============================================================================*/
337 /* void pu_matrices_to_contraintes(Pcontrainte *pc, Pbase b, matrice A B,
338  * int n m):
339  * constructs the constraints "pc" corresponding to the matrices "A" and "B"
340  * so: pc(b) <=> Ab + B
341  *
342  * B represents the constant term.
343  *
344  * The base "b" gives the variables of the linear system.
345  * The matrices "A" and "B" are respectively of dimension (n, m) and (n, 1).
346  *
347  * "n" will be the exact number of constraints contained in "pc".
348  * "m" must be the exact number of variables contained in "b".
349  */
350 void pu_matrices_to_contraintes(pc, b, A, B, n, m)
351 Pcontrainte *pc;
352 Pbase b;
353 matrice A, B;
354 int n, m;
355 {
356  Pvecteur vect,pv=NULL;
357  Pcontrainte cp, newpc= NULL;
358  int i,j;
359  Value cst,coeff,dena,denb;
360  bool trouve ;
361 
362  dena = DENOMINATOR(A);
363  denb = DENOMINATOR(B);
364 
365  for (i=n;i>=1; i--) {
366  trouve = false;
367  cp = contrainte_new();
368 
369  /* build the constant terme if it is null */
370  if (value_notzero_p(cst = ACCESS(B,n,i,1))) {
371  pv = vect_new(TCST, value_mult(dena,cst));
372  trouve = true;
373  }
374 
375  for (vect = b,j=1;j<=m;vect=vect->succ,j++) {
376  if (value_notzero_p(coeff = ACCESS(A,n,i,j))) {
377  if (trouve)
378  vect_chg_coeff(&pv, vecteur_var(vect),
379  value_mult(denb,coeff));
380  else {
381  /* build a new vecteur if there is a null constant term */
382  pv = vect_new(vecteur_var(vect), value_mult(denb,coeff));
383  trouve = true;
384  }
385  }
386  }
387  cp->vecteur = pv;
388  cp->succ = newpc;
389  newpc = cp;
390  }
391  *pc = newpc;
392 }
393 
394 /*============================================================================*/
395 /* void pu_contraintes_to_matrices(Pcontrainte pc, Pbase b, matrice A B,
396  * int n m):
397  * constructs the matrices "A" and "B" corresponding to the linear
398  * constraints "pc", so: Ab + B <=> pc(b).
399  *
400  * The base "b" gives the variables of the linear system.
401  *
402  * The matrices "A" and "B" are supposed to have been already allocated in
403  * memory, respectively of dimension (n, m) and (n, 1).
404  *
405  * "n" must be the exact number of constraints contained in "pc".
406  * "m" must be the exact number of variables contained in "b".
407  */
408 void pu_contraintes_to_matrices(pc, b, A, B, n, m)
409 Pcontrainte pc;
410 Pbase b;
411 matrice A, B;
412 int n;
413 int m;
414 {
415  int i,j;
416  Pvecteur pv;
417  Pcontrainte eq;
418  matrice_nulle(B,n,1);
419  matrice_nulle(A,n,m);
420 
421  for(eq = pc,i=1; !CONTRAINTE_UNDEFINED_P(eq); eq=eq->succ,i++) {
422  for(pv = b, j=1; pv != NULL; pv = pv->succ, j++){
423  ACCESS(A,n,i,j) = vect_coeff(vecteur_var(pv),eq->vecteur);
424  }
425  ACCESS(B,n,i,1) = vect_coeff(0,eq->vecteur);
426  }
427 }
428 
429 
430 /* Creation de la matrice A correspondant au systeme lineaire et de la matrice
431  * correspondant a la partie constante B
432  * Le systeme peut contenir des constantes symboliques. Dans ce cas, la base
433  * index_base ne doit contenir que les variables etant des indices de boucles
434  * et la base const_base les constantes symboliques. La matrice B
435  * represente toutes les contraintes sur les constantes.
436  *
437  * Les parametres de la fonction :
438  *
439  * Psysteme ps : systeme lineaire
440  *!int A[] : matrice
441  *!int B[] : matrice
442  * int n : nombre de lignes de la matrice
443  * int m : nombre de colonnes de la matrice
444  */
445 
446 void contraintes_with_sym_cst_to_matrices(pc,index_base,const_base,A,B,n,m1,m2)
447 Pcontrainte pc;
448 Pbase index_base,const_base;
449 matrice A;
450 matrice B;
451 int n,m1,m2;
452 {
453 
454  int i,j;
455  Pcontrainte eq;
456  Pvecteur pv;
457 
458  matrice_nulle(B,n,m2);
459  matrice_nulle(A,n,m1);
460 
461  for (eq = pc,i=1; !CONTRAINTE_UNDEFINED_P(eq); eq=eq->succ,i++) {
462  for(pv = index_base, j=1; pv != NULL; pv = pv->succ, j++){
463  ACCESS(A,n,i,j) = vect_coeff(vecteur_var(pv),eq->vecteur);
464  }
465  for(pv = const_base, j=1; pv != NULL; pv = pv->succ, j++){
466  ACCESS(B,n,i,j) = vect_coeff(vecteur_var(pv),eq->vecteur);
467  }
468  ACCESS(B,n,i,m2) = vect_coeff(TCST,eq->vecteur);
469  }
470 
471 }
472 
473 
474 /*
475  * Creation d'un systeme lineaire a partir de deux matrices. La matrice B
476  * correspond aux termes constants de chacune des inequations appartenant
477  * au systeme. La matrice A correspond a la partie lineaire des expressions
478  * des inequations le composant.
479  *
480  * Le systeme peut contenir des constantes symboliques. Dans ce cas, la
481  * matrice B represente toutes les contraintes sur les constantes.
482  * La base index_base ne contiendra que les variables etant des indices de
483  * boucles et la base const_base les constantes symboliques.
484  *
485  * L'ensemble des variables du nouveau systeme est initialise avec une base
486  * d'indices que l'on donne en argument. Cette base peut etre vide (NULL).
487  *
488  * Des nouvelles variables sont creees si necessaire si il n'y a pas assez
489  * de variables dans la base fournie.
490  *
491  * La matrice A correspond a la partie non constante du systeme lineaire.
492  * La matrice B correspond a la partie constante.
493  * Le syteme lineaire s'ecrit A.x <= B.
494  *
495  * Les parametres de la fonction :
496  *
497  *!Psysteme ps : systeme lineaire
498  * int A[] : matrice de dimension (n,m)
499  * int B[] : matrice de dimension (n,m2)
500  * int n : nombre de lignes de la matrice
501  * int m : nombre de colonnes de la matrice A
502  */
503 void matrices_to_contraintes_with_sym_cst(pc,index_base,const_base,A,B,n,m1,m2)
504 Pcontrainte *pc;
505 Pbase index_base,const_base;
506 matrice A,B;
507 int n,m1,m2;
508 {
509  Pvecteur vect,pv=NULL;
510  Pcontrainte cp,newpc= NULL;
511  int i,j;
512  Value cst,coeff,dena,denb;
513  bool trouve ;
514 
515  dena = DENOMINATOR(A);
516  denb = DENOMINATOR(B);
517 
518  for (i=n;i>=1; i--) {
519  trouve = false;
520  cp = contrainte_new();
521 
522  /* build the constant terme if it exists */
523  if (value_notzero_p(cst = ACCESS(B,n,i,m2))) {
524  pv = vect_new(TCST, value_mult(dena,cst));
525  trouve = true;
526  }
527 
528  for (vect = base_union(index_base, const_base),j=1;
529  j<=m1;vect=vect->succ,j++) {
530  if (value_notzero_p(coeff = ACCESS(A,n,i,j))) {
531  if (trouve) {
532  vect_chg_coeff(&pv, vecteur_var(vect),
533  value_mult(denb, coeff));
534  }
535  else {
536  /* build a new vecteur if there is not constant term */
537  pv = vect_new(vecteur_var(vect), value_mult(denb, coeff));
538  trouve = true;
539  }
540  }
541  }
542 
543  for (j=1;j<=m2-1;vect=vect->succ,j++) {
544  if (value_notzero_p(coeff = ACCESS(B,n,i,j))) {
545  if (trouve) {
546  vect_chg_coeff(&pv, vecteur_var(vect),
547  value_mult(denb, coeff));
548  }
549  else {
550  /* build a new vecteur if there is not constant term */
551  pv = vect_new(vecteur_var(vect),
552  value_mult(denb, coeff));
553  trouve = true;
554  }
555  }
556  }
557 
558  cp->vecteur = pv;
559  cp->succ = newpc;
560  newpc = cp;
561  }
562  *pc = newpc;
563 }
564 
565 
566 /*============================================================================*/
567 /* void pu_egalites_to_matrice(matrice a, int n m, Pcontrainte leg, Pbase b):
568  * constructs the matrix "a" with the equalities contained in "leg". The base
569  * "b" gives the column number of each variable. The first element of the
570  * matrix is a(1,1), the ACCESS macro makes the conversion to the C array
571  * numbering which begins at (0,0).
572  *
573  * The constant term is not included. The matrix "a" is supposed to have been
574  * already allocated in memory.
575  *
576  * "n" must be the exact number of equalities contained in "leg".
577  * "m" must be the exact number of variables contained in "b".
578  */
579 /* never called
580 void pu_egalites_to_matrice(a, n, m, leg, b)
581 matrice a;
582 int n;
583 int m;
584 Pcontrainte leg;
585 Pbase b;
586 {
587  Pvecteur v;
588  Pcontrainte peq;
589  int ligne = 1;
590 
591  matrice_nulle(a, n, m);
592 
593  for(peq = leg; peq != NULL; peq = peq->succ, ligne++) {
594  pips_assert("pu_egalites_to_matrice",ligne<=n);
595 
596  for(v = peq->vecteur; !VECTEUR_UNDEFINED_P(v); v = v->succ) {
597  int rank;
598  if(vecteur_var(v) != TCST) {
599  rank = base_find_variable_rank(base_dup(b), vecteur_var(v),
600  pu_variable_name);
601  pips_assert("pu_egalites_to_matrice", rank <= m);
602 
603  ACCESS(a, n, ligne, rank) = vecteur_val(v);
604  }
605  }
606  }
607 }
608 */
609 /* end MATRIX functions */
610 
611 
612 
613 /*=======================================================================*/
614 /* vertex in_dfg_vertex_list( (list) l, (vertex) v ) AL 30/06/93
615  * Input : A list l of vertices.
616  * A vertex v of a dependence graph.
617  * Returns vertex_undefined if v is not in list l.
618  * Returns v' that has the same statement_ordering than v.
619  */
621 {
622  vertex ver;
623  int in;
624 
625  pips_debug(9, "doing \n");
626 
628  vertex_vertex_label(v) );
629  for(;!ENDP(l); POP(l)) {
630  int prov_i;
631  ver = VERTEX(CAR( l ));
633  vertex_vertex_label(ver) );
634  if ( prov_i == in ) return( ver );
635  }
636 
637  return vertex_undefined;
638 }
639 
640 /*=======================================================================*/
641 /* vertex in_dg_vertex_list( (list) l, (vertex) v ) AL 30/06/93
642  * Input : A list l of vertices.
643  * A vertex v of a dependence graph.
644  * Returns vertex_undefined if v is not in list l.
645  * Returns v' that has the same statement_ordering than v.
646  */
648 {
649  vertex ver;
650  int in;
651 
652  pips_debug(9, "doing \n");
653 
655  vertex_vertex_label(v) );
656  for(;!ENDP(l); POP(l)) {
657  int prov_i;
658  ver = VERTEX(CAR( l ));
660  vertex_vertex_label(ver) );
661  if ( prov_i == in ) return( ver );
662  }
663 
664  return vertex_undefined;
665 }
666 
667 /*============================================================================*/
668 /* expression make_id_expression(string s): makes an expression with the
669  * name of a variable. For this variable, we create a new entity if it does not
670  * exist yet.
671  */
673 {
674  entity new_ent;
675  string exp_full_name;
676 
678  s, (char *) NULL));
679 
680  new_ent = gen_find_tabulated(exp_full_name, entity_domain);
681 
682  if(new_ent == entity_undefined)
683  new_ent = make_entity(exp_full_name,
685  make_variable(make_basic_int(4/*UU*/),
686  NIL, NIL)),
689 
691  make_reference(new_ent,NIL)),
693 }
694 
695 /*============================================================================*/
696 /* expression make_array_ref(list l): returns an expression which is a
697  * reference to an array. The list "l" is composed of expressions, the first
698  * one is the array itself and the others are the indices. In order to create
699  * the desire expression, we only have to put the CDR of "l" into the list of
700  * indices of the reference contained in the first expression of "l".
701  */
703 {
704  expression new_exp;
705  list array_inds;
706 
707  if(l == NIL)
708  pips_internal_error("No args for array ref");
709 
710  new_exp = EXPRESSION(CAR(l));
711  array_inds = CDR(l);
712 
713  if(! syntax_reference_p(expression_syntax(new_exp)))
714  pips_internal_error("Array ref is not a reference");
715 
716  reference_indices(syntax_reference(expression_syntax(new_exp))) = array_inds;
717 
718  return(new_exp);
719 }
720 
721 /*============================================================================*/
722 /* expression make_func_op(string func_name, list args): returns an expression
723  * that represent the call to "func_name" with "args" as arguments.
724  */
725 expression make_func_op(func_name, args)
726 string func_name;
727 list args;
728 {
729  entity func_ent;
730 
732  func_name), entity_domain);
733 
734  if(func_ent == entity_undefined)
735  pips_internal_error("Function unknown : %s", func_name);
736 
738  make_call(func_ent, args)),
740 }
741 
742 /*============================================================================*/
743 /* expression lisp_exp_to_ri_exp(lisp_expression le): returns the
744  * expression that represent the lisp_expression given in argument ("le"). A
745  * lisp_expression is a Newgen structure that defines an expression as a list
746  * with the operator as the first object and the arguments as the rest of the
747  * list.
748  *
749  * There are a few cases. If the operator is "aref" or "aset" then this lisp
750  * expression is a reference to an array. We use make_array_ref().
751  * If the operator is not one of the four operations (+,-,*,/), then we use
752  * make_func_op().
753  * Else (the operator is one of the four operation) we use rational_op_exp().
754  */
756 lisp_expression le;
757 {
758  expression exp1, exp2;
759  string exp_op = lisp_expression_operation(le);
760  list exp_args = lisp_expression_args(le);
761 
762  if( (strncmp(exp_op, "aref", 4) == 0) || (strncmp(exp_op, "aset", 4) == 0) )
763  return(make_array_ref(exp_args));
764 
765  if(! STRING_FOUR_OPERATION_P(exp_op))
766  return(make_func_op(exp_op, exp_args));
767 
768  exp1 = EXPRESSION(CAR(exp_args));
769  exp_args = CDR(exp_args);
770 
771  if(exp_args == NIL)
772  pips_internal_error("Only 1 argument for a binary (or more) operation");
773 
774  for(; exp_args != NIL; exp_args = CDR(exp_args))
775  {
776  exp2 = EXPRESSION(CAR(exp_args));
777 
778  exp1 = rational_op_exp(exp_op, exp1, exp2);
779  }
780  return(exp1);
781 }
782 
783 
784 /*============================================================================*/
785 /* expression negate_expression(expression exp): returns the negation of
786  * the expression given in argument "exp".
787  *
788  * In fact this computation is done only if the expression is linear with
789  * integer coefficients. If so, we use the Pvecteur form. Else, we return the
790  * duplication of the expression.
791  */
794 {
795  expression neg_exp;
796  normalized nexp;
797 
798  nexp = NORMALIZE_EXPRESSION(exp);
799 
800  if(normalized_complex_p(nexp))
801  neg_exp = copy_expression(exp);
802  else
803  {
804  Pvecteur vexp, new_vec;
805 
806  vexp = (Pvecteur) normalized_linear(nexp);
807  new_vec = vect_dup(vexp);
808  vect_chg_sgn(new_vec);
809 
810  neg_exp = make_vecteur_expression(new_vec);
811  }
812 
813  return(neg_exp);
814 }
815 
816 /*============================================================================*/
817 /* predicate expressions_to_predicate(list exp_l): returns the predicate
818  * that has the inequalities given as expressions in "exp_l". For example:
819  * if A is an expresion of "exp_l" then we'll have the inequality A <= 0 in the
820  * predicate.
821  *
822  * If an expression is not linear, we warn the user.
823  *
824  * Note: if "exp_l" is empty then we return an undefined predicate.
825  */
827 list exp_l;
828 {
829  predicate new_pred;
830  Psysteme new_sc;
831  list l;
832 
833  if(exp_l == NIL)
834  return(predicate_undefined);
835 
836  new_sc = sc_new();
837 
838  for(l = exp_l; l != NIL; l = CDR(l))
839  {
842 
843  if(normalized_linear_p(nexp))
844  {
845  Pvecteur new_vec = (Pvecteur) normalized_linear(nexp);
846  sc_add_inegalite(new_sc, contrainte_make(new_vec));
847  }
848  else
849  {
850  printf("\nNon linear expression :");
851  printf(" %s\n", expression_to_string(exp));
852  }
853  }
854 
855  sc_creer_base(new_sc);
856  new_pred = make_predicate(new_sc);
857 
858  return(new_pred);
859 }
860 
861 
862 /*============================================================================*/
863 /* int vertex_int_stmt(vertex v): returns the statement number contained
864  * in the vertex. It is a "dfg" vertex.
865  */
867 vertex v;
868 {
870 }
871 
872 
873 /*============================================================================*/
874 /* void comp_exec_domain(graph g, STS): computes the execution domain of
875  * each statement. The englobing loops are obtained through the static
876  * control map. */
878 graph g;
880 {
881  int stmt;
882  list loop_l, dfg_edge_l;
883 
884  /* We update the graph global variable with the exec domain. */
885  dfg_edge_l = graph_vertices(g);
886  for(; dfg_edge_l != NIL; dfg_edge_l = CDR(dfg_edge_l)) {
887  vertex v = VERTEX(CAR(dfg_edge_l));
888  dfg_vertex_label dvl;
889  Psysteme new_sc = sc_new();
890 
892  stmt = vertex_int_stmt(v);
894  (char *) ((long)stmt)));
895 
896  for( ; loop_l != NIL; loop_l = CDR(loop_l))
897  {
898  Pvecteur vect_index, vect;
899  normalized nub, nlb;
900  /* loop aux_loop = ENTITY(CAR(loop_l)); */
901  loop aux_loop = LOOP(CAR(loop_l));
902  entity index_ent = loop_index(aux_loop);
903 
904  vect_index = vect_new((char *) index_ent, VALUE_ONE);
905  nlb = NORMALIZE_EXPRESSION(range_lower(loop_range(aux_loop)));
906  nub = NORMALIZE_EXPRESSION(range_upper(loop_range(aux_loop)));
907 
908  if (normalized_linear_p(nlb))
909  {
910  vect = vect_substract((Pvecteur) normalized_linear(nlb), vect_index);
911  if(!VECTEUR_NUL_P(vect))
912  sc_add_inegalite(new_sc, contrainte_make(vect));
913  }
914  if (normalized_linear_p(nub))
915  {
916  vect = vect_substract(vect_index, (Pvecteur) normalized_linear(nub));
917  if(!VECTEUR_NUL_P(vect))
918  sc_add_inegalite(new_sc, contrainte_make(vect));
919  }
920  }
921  sc_creer_base(new_sc);
922 
924  }
925 }
926 
927 /*============================================================================*/
928 /* Psysteme make_expression_equalities(list le): returns a Psysteme that
929  * has equalities computed from "le", a list of expressions.
930  */
932 {
933  Psysteme new_sc;
934  list l;
935 
936  new_sc = sc_new();
937 
938  for(l = le; l != NIL; l = CDR(l))
939  {
942 
943  if(normalized_linear_p(nexp))
944  {
945  Pvecteur new_vec = (Pvecteur) normalized_linear(nexp);
946  sc_add_egalite(new_sc, contrainte_make(new_vec));
947  }
948  else
949  {
950  printf("\nNon linear expression :");
951  printf(" %s\n", expression_to_string(exp));
952  }
953  }
954  sc_creer_base(new_sc);
955  return(new_sc);
956 }
957 
958 /*============================================================================*/
959 /* static list find_el_with_num(int stmt): returns the englobing loops list
960  * corresponding to the statement number "stmt".
961  *
962  * This function uses an hash table, which contains the static_control
963  * associated to each statement. */
965 {
967 
968  static_control stct = (static_control) hash_get(scm, (char *) ((long)stmt));
969 
970  return(static_control_loops(stct));
971 }
972 
973 /*============================================================================*/
974 /* Pbase make_base_of_nest(int stmt): returns the Pbase that contains the
975  * indices of the englobing loops of "stmt".
976  */
978 {
979  Pbase new_b = NULL;
980  list el_l;
981 
982  for(el_l = find_el_with_num(stmt) ; el_l != NIL; el_l = CDR(el_l))
983  vect_add_elem((Pvecteur *) &new_b,
984  (Variable) loop_index(LOOP(CAR(el_l))),
985  VALUE_ONE);
986 
987  return(new_b);
988 }
989 
990 /*============================================================================*/
991 /* successor first_succ_of_vertex(vertex v): returns the first successor of
992  * "v".
993  */
995 {
996  return(SUCCESSOR(CAR(vertex_successors(v))));
997 }
998 
999 
1000 /*============================================================================*/
1001 /* dataflow first_df_of_succ(successor s): returns the first dataflow of
1002  * "s".
1003  */
1005 successor s;
1006 {
1008 successor_arc_label(s)))));
1009 }
1010 
1011 /*============================================================================*/
1012 /* loop loop_dup(loop l): returns the duplication of "l".
1013  */
1015 {
1016  /*
1017  loop new_loop;
1018 
1019  new_loop = make_loop(loop_index(l), range_dup(loop_range(l)), loop_body(l),
1020  loop_label(l), loop_execution(l), loop_locals(l));
1021 
1022  return(new_loop);
1023  */
1024  return copy_loop(l);
1025 }
1026 
1027 
1028  /* package mapping : Alexis Platonoff, july 1993 */
1029 
1030 /*============================================================================*/
1031 /* list static_control_to_indices(static_control stct): returns the list of
1032  * the loop indices (entities) corresponding to the list of loops contained in
1033  * "stct". The list of indices is in the same order than the list of loop, i.e.
1034  * for example, if "stct" contains a list of loops like (LOOP1, LOOP3, LOOP5,
1035  * LOOP2) then the list of indices will be (I1, I3, I5, I2).
1036  */
1038 static_control stct;
1039 {
1040  list lo_l = static_control_loops(stct);
1041  list ind_l = NIL;
1042 
1043  for( ; lo_l != NIL; lo_l = CDR(lo_l))
1044  {
1045  loop lo = LOOP(CAR(lo_l));
1046 
1047  /* We keep the same order. */
1048  ind_l = gen_nconc(ind_l, CONS(ENTITY, loop_index(lo), NIL));
1049  }
1050  return(ind_l);
1051 }
1052 
1053 
1054 
1055 
1056 /* ======================================================================== */
1057 /*
1058  * Pvecteur polynome_to_vecteur(Ppolynome pp)
1059  *
1060  * Translates a polynome "pp" into a vector. This is only possible if "pp"
1061  * is of degree one (1).
1062  */
1064 {
1065  Pvecteur new_pv = VECTEUR_NUL;
1066  Ppolynome ppp;
1067 
1068  for(ppp = pp; ppp != NULL; ppp = ppp->succ) {
1069  entity var;
1070  Value val;
1071  Pvecteur pv = (ppp->monome)->term;
1072 
1073  if(VECTEUR_NUL_P(pv))
1074  pips_internal_error("A null vector in a monome");
1075  else if(pv->succ != NULL)
1076  pips_internal_error("Polynome is not of degree one");
1077 
1078  var = (entity) pv->var;
1079  val = float_to_value((ppp->monome)->coeff);
1080  vect_add_elem(&new_pv, (Variable) var, val);
1081  }
1082  return(new_pv);
1083 }
1084 
1085 /* ======================================================================== */
1086 /*
1087  * Pcontrainte polynome_to_contrainte(Ppolynome pp)
1088  *
1089  * Translates a polynome "pp" into a constraint (inequality or equality,
1090  * depends on its usage). This is only possible if "pp" is of degree one (1)
1091  * because we tranform it into a Pvecteur.
1092  *
1093  * If you want an inequality, it will be: pp <= 0
1094  */
1096 Ppolynome pp;
1097 {
1098  return(contrainte_make(polynome_to_vecteur(pp)));
1099 }
1100 
1101 
1102 /*============================================================================*/
1103 /* Psysteme polynome_to_sc(Ppolynome pp, list l): returns a system of
1104  * equalities ("new_ps") computed from a polynome "pp" and a list of variables
1105  * "l".
1106  *
1107  * This list gives the variables of the polynome for which we need to nullify
1108  * the factor. Thus, the resulting system contains the equations that nullify
1109  * these factors (the degree of the polynome must be less or equal to two).
1110  *
1111  * When all these equations are computed, the remaining polynome, from each we
1112  * have removed all the occurences of these variables, is also nullify and the
1113  * equation added to the system (then, this remnant must be of degree 1).
1114  */
1116 Ppolynome pp;
1117 list l;
1118 {
1119  Ppolynome aux_pp = polynome_dup(pp);
1120  Psysteme new_ps = sc_new();
1121 
1122  /* For each variable, we nullify its factor in the polynome. */
1123  for( ; l != NIL; l = CDR(l))
1124  {
1125  /* We get the current variable. */
1126  entity var = ENTITY(CAR(l));
1127 
1128  /* We get its factor in the polynome. */
1129  Ppolynome pp_fac = polynome_factorize(aux_pp, (Variable) var, 1);
1130 
1131  /* We add a new equality in the system. */
1132  sc_add_egalite(new_ps, polynome_to_contrainte(pp_fac));
1133 
1134  /* We delete the occurences of this variable in the polynome. */
1135  aux_pp = prototype_var_subst(aux_pp, (Variable) var, POLYNOME_NUL);
1136  }
1137  /* The remnant is added to the system. */
1138  sc_add_egalite(new_ps, polynome_to_contrainte(aux_pp));
1139 
1140  sc_creer_base(new_ps);
1141  return(new_ps);
1142 }
1143 
1144 
1145 /*============================================================================*/
1146 /* Psysteme new_polynome_to_sc(Ppolynome pp, list l): returns a system of
1147  * equalities ("new_ps") computed from a polynome "pp" and a list of variables
1148  * "l".
1149  *
1150  * This list gives the variables of the polynome for which we need to nullify
1151  * the factor. Thus, the resulting system contains the equations that nullify
1152  * these factors (the degree of the polynome must be less or equal to two).
1153  *
1154  * When all these equations are computed, the remaining polynome, from each we
1155  * have removed all the occurences of these variables, is also nullify and the
1156  * equation added to the system (then, this remnant must be of degree 1).
1157  */
1159 Ppolynome pp;
1160 list l;
1161 {
1162  Ppolynome aux_pp = polynome_dup(pp);
1163  Psysteme new_ps = sc_new();
1164 
1165  /* For each variable, we nullify its factor in the polynome. */
1166  for( ; l != NIL; l = CDR(l))
1167  {
1168  /* We get the current variable. */
1169  entity var = ENTITY(CAR(l));
1170 
1171  /* We get its factor in the polynome. */
1172  Pvecteur pv_fac = prototype_factorize(aux_pp, (Variable) var);
1173 
1174  if(!VECTEUR_NUL_P(pv_fac)) {
1175  sc_add_egalite(new_ps, contrainte_make(pv_fac));
1176 
1177  /* We delete the occurences of this variable in the polynome. */
1178  aux_pp = prototype_var_subst(aux_pp, (Variable) var, POLYNOME_NUL);
1179  }
1180  }
1181  /* The remnant is added to the system. */
1182  sc_add_egalite(new_ps, polynome_to_contrainte(aux_pp));
1183 
1184  sc_creer_base(new_ps);
1185  return(new_ps);
1186 }
1187 
1188 
1189 /*============================================================================*/
1190 /* void substitute_var_with_vec(Psysteme ps, entity var, int val, Pvecteur vec):
1191  * Substitutes in a system ("ps") a variable ("var"), factor of a positive
1192  * value ("val"), by an expression ("vec").
1193  *
1194  * This substitution is done on all assertions of the system (equalities and
1195  * inequalities). For each assertion (represented by a vector Vold) we have:
1196  *
1197  * Vold = c*var + Vaux
1198  * val*var = vec
1199  *
1200  * Vnew represents the new assertion. With: p = pgcd(c, val) >= 1, we have:
1201  *
1202  * Vnew = (c/p)*vec + (val/p)*Vaux = (c/p)*vec + (val/p)*(Vold - c*var)
1203  *
1204  * Note: we have: Vold == 0 <=> (val/p)*Vold == 0
1205  * Vold > 0 <=> (val/p)*Vold > 0
1206  * ...
1207  *
1208  * because "val" is positive.
1209  */
1210 void substitute_var_with_vec(ps, var, val, vec)
1211 Psysteme ps;
1212 entity var;
1213 Value val;
1214 Pvecteur vec;
1215 {
1216  Variable Var = (Variable) var;
1218 
1219  ifdebug(7) {
1220 fprintf(stdout, "\t\t\tAvant Sub: \n");
1221 fprint_psysteme(stdout, ps);
1222 fprintf(stdout, "\n");
1223  }
1224 
1225  /* "val" must be positive. */
1226  if(value_neg_p(val)) {
1227  value_oppose(val);
1228  vect_chg_sgn(vec);
1229  }
1230 
1231  /* Vnew = (c/p)*vec + (val/p)*Vaux = (c/p)*vec + (val/p)*(Vold - c*var) */
1232  for(assert = ps->egalites; assert != NULL; assert = assert->succ) {
1233  Pvecteur v_old = assert->vecteur;
1234  Value coeff = vect_coeff(Var, v_old);
1235  if(value_notzero_p(coeff)) {
1236  Value p = pgcd_slow(coeff, val);
1237 
1238  assert->vecteur = vect_cl2_ofl_ctrl
1239  (value_div(coeff,p), vec,
1240  value_div(val,p),
1242  vect_new(Var, coeff),
1243  NO_OFL_CTRL),
1244  NO_OFL_CTRL);
1245  }
1246  }
1247  for(assert = ps->inegalites; assert != NULL; assert = assert->succ) {
1248  Pvecteur v_old = assert->vecteur;
1249  Value coeff = vect_coeff(Var, v_old);
1250  if(value_notzero_p(coeff)) {
1251  Value p = pgcd_slow(coeff, val);
1252 
1253  assert->vecteur = vect_cl2_ofl_ctrl
1254  (value_div(coeff,p), vec,
1255  value_div(val,p),
1257  vect_new(Var, coeff),
1258  NO_OFL_CTRL),
1259  NO_OFL_CTRL);
1260  }
1261  }
1262  vect_rm((Pvecteur) ps->base);
1263  ps->base = (Pbase) NULL;
1264  sc_creer_base(ps);
1265 
1266  ifdebug(7) {
1267  fprintf(stdout, "\t\t\tApres Sub: \n");
1268  fprint_psysteme(stdout, ps);
1269  fprintf(stdout, "\n");
1270  }
1271 
1272 }
1273 
1274 
1275 /*============================================================================*/
1276 /* bool is_entity_in_list_p(entity e, list l): returns true if entity "e" is
1277  * in the list of entities "l", false otherwise.
1278  */
1279 /* FI: many similar functions. See ri-util/arguments.c which deals
1280  with entity lists, i.e. entities. */
1282 {
1283  bool is_in_list = false;
1284  for( ; (l != NIL) && (! is_in_list); l = CDR(l))
1285  if(same_entity_p(e, ENTITY(CAR(l))))
1286  is_in_list = true;
1287  return(is_in_list);
1288 }
1289 
1290 /*============================================================================*/
1291 /* Psysteme elim_var_with_eg(Psysteme ps, list *init_l, list *elim_l):
1292  * Computes the elimination of variables in the system "ps" using its
1293  * equalities. All the used equalities are removed directly from "ps".
1294  *
1295  * However, we keep all these "used" equalities in "sc_elim". The return value
1296  * of this function is this system.
1297  *
1298  * Initially, "init_l" gives the list of variables that can be eliminated and
1299  * "elim_l" is empty. At the end, "init_l" contains the variables that are
1300  * not eliminated and "elim_l" contains the variables that are eliminated.
1301  *
1302  * At the end, to each equality of "sc_elim" will be associated a variable
1303  * of "elim_l". These lists are built so as to be able to match them directly.
1304  * Each variable of "elim_l" appears in one constraint of "sc_elim" and only
1305  * one. There will be as many equalities in "sc_elim" as variables in "elim_l"
1306  *
1307  * A variable can be eliminated using a given equality if it appears in this
1308  * equality, i.e. its associated coefficient is not equal to zero. Moreover, it
1309  * is easier to eliminate a variable with a value of 1 or -1. So, first we
1310  * try to find such a variable.
1311  *
1312  * Algo:
1313  * ----
1314  * BEGIN
1315  * vl = init_l;
1316  * el = NIL;
1317  * eqs = list of equalities of ps
1318  * sc_elim = system with no constraints
1319  * while eqs is not empty
1320  * init_vec = vector of the first equality of eqs
1321  * var_not_found = TRUE
1322  * coeff_one_not_found = TRUE
1323  * l = vl
1324  * while coeff_one_not_found and l is not empty
1325  * crt_var = first variable of l
1326  * crt_val = its value in init_vec
1327  * if crt_val is 1 or -1
1328  * coeff_one_not_found = FALSE
1329  * var_not_found = FALSE
1330  * (var, val) = (crt_var, crt_val)
1331  * else if crt_val is not 0 and var_not_found
1332  * var_not_found = FALSE
1333  * (var, val) = (crt_var, crt_val)
1334  * end if
1335  * l = CDR(l)
1336  * end while
1337  * if var_not_found is false (means that a variable has been found)
1338  * (var, val) = variable and its value to eliminate in init_vec
1339  * remove var from vl
1340  * add var to el
1341  * pv_elim = val*var - init_vec
1342  * substitute val*var by pv_elim in ps
1343  * substitute val*var by pv_elim in sc_elim
1344  * add init_vec to sc_elim
1345  * eqs = new list of equalities of ps
1346  * else
1347  * eqs = CDR(eqs)
1348  * end if
1349  * end while
1350  * init_l = vl
1351  * elim_l = el
1352  * END
1353  *
1354  * Note: the substitution of val*var by pv_elim in a vector V uses the gcd:
1355  * V = c*var + Vaux
1356  * p = gcd(val,c)
1357  * Vnew = (c/p)*pv_elim + (val/p)*Vaux
1358  *
1359  * BUG: reuse of freed memory.
1360  */
1361 Psysteme elim_var_with_eg(Psysteme ps, list * init_l, list * elim_l)
1362 {
1363  Psysteme sc_elim = sc_new();
1364  Pcontrainte eqs;
1365  list vl = *init_l, /* We use "vl" during the computation, not *init_l */
1366  el = NIL, /* We use "el" during the computation, not *elim_l */
1367  l;
1368 
1369  /* Nothing do if there is no variable to eliminate */
1370  if(!ENDP(vl)) {
1371  /* This elimination works only on equalities. While there remains
1372  * equalities, we can eliminate variables. */
1373  eqs = ps->egalites;
1374  while(eqs != NULL)
1375  {
1376  bool coeff_one_not_found, var_found;
1377  entity var = entity_undefined;
1378  Value val = VALUE_ZERO;
1379  Pvecteur init_vec, pv_elim;
1380  Pcontrainte next = eqs->succ;
1381 
1382  init_vec = vect_dup(eqs->vecteur);
1383 
1384  /* We look, in vl (i.e. init_l), for a variable that we can
1385  * eliminate in init_vec, i.e. with a coefficient not equal to
1386  * 0. We prefer a coefficient * equal to 1 or -1, so we scan
1387  * all the equality. We take the first * variable of "init_l"
1388  * that has a coeff of 1 or -1. If there is no such *
1389  * variable, we take the first with a coeff not equal to zero.
1390  */
1391  var_found = false;
1392  coeff_one_not_found = true;
1393 
1394  for(l = vl ; (l != NIL) && coeff_one_not_found; l = CDR(l))
1395  {
1396  entity crt_var = ENTITY(CAR(l));
1397  Value crt_val = vect_coeff((Variable) crt_var, init_vec);
1398 
1399  if(value_one_p(crt_val) || value_mone_p(crt_val))
1400  {
1401  coeff_one_not_found = false;
1402  var_found = true;
1403  var = crt_var;
1404  val = crt_val;
1405  }
1406  else if((value_notzero_p(crt_val)) && !var_found)
1407  {
1408  var_found = true;
1409  var = crt_var;
1410  val = crt_val;
1411  }
1412  }
1413 
1414  if(var_found) /* If we get such a variable, we eliminate it. */
1415  {
1416  /* First, we remove it from "vl". */
1417  gen_remove(&vl, (void *) var);
1418 
1419  /* Then, we add it to "el". */
1420  el = CONS(ENTITY, var, el);
1421 
1422  /* We compute the expression (pv_elim) by which we are
1423  * going to substitute our variable (var):
1424  *
1425  * We have: val*var = pv_elim
1426  *
1427  * The equality is: V = 0, with: V = val*var + Vaux
1428  *
1429  * So, we have: pv_elim = -Vaux, with: Vaux = V - val*var
1430  *
1431  * So: pv_elim = val*var - V
1432  *
1433  * ??? memory leak...
1434  */
1435  pv_elim = vect_cl2_ofl_ctrl
1436  (VALUE_MONE, vect_dup(init_vec),
1437  VALUE_ONE, vect_new((Variable) var, val),
1438  NO_OFL_CTRL);
1439 
1440  /* substitute "val*var" by its value (pv_elim) in the system */
1441  substitute_var_with_vec(ps, var, val, vect_dup(pv_elim));
1442  /*ps = sc_normalize(ps);*/
1443  ps = sc_elim_db_constraints(ps);
1444 
1445  /* We substitute var by its value (pv_elim) in "sc_elim". */
1446  substitute_var_with_vec(sc_elim, var, val, vect_dup(pv_elim));
1447 
1448  /* The initial equality is added to "sc_elim". */
1449  sc_add_egalite(sc_elim, contrainte_make(vect_dup(init_vec)));
1450 
1451  /* We reinitialize the list of equalities. */
1452  eqs = ps->egalites;
1453  }
1454  /* Else, we try on the next equality. */
1455  else
1456  eqs = next;
1457 
1458  vect_rm(init_vec);
1459  }
1460  }
1461  *init_l = vl;
1462  *elim_l = el;
1463  sc_elim->base = NULL;
1464  sc_creer_base(sc_elim);
1465 
1466  return(sc_elim);
1467 }
1468 
1469 
1470 /*============================================================================*/
1471 /* Psysteme better_elim_var_with_eg(Psysteme ps, list *init_l, list *elim_l):
1472  * Computes the elimination of variables in the system "ps" using its
1473  * equalities. All the used equalities are removed directly from "ps".
1474  *
1475  * However, we keep all these "used" equalities in "sc_elim". The return value
1476  * of this function is this system.
1477  *
1478  * Initially, "init_l" gives the list of variables that can be eliminated and
1479  * "elim_l" is empty. At the end, "init_l" contains the variables that are
1480  * not eliminated and "elim_l" contains the variables that are eliminated. We
1481  * keep the order of "init_l" in our process of elimination.
1482  *
1483  * At the end, to each equality of "sc_elim" will be associated a variable
1484  * of "elim_l". These lists are built so as to be able to match them directly.
1485  * Each variable of "elim_l" appears in one constraint of "sc_elim" and only
1486  * one. There will be as many equalities in "sc_elim" as variables in "elim_l"
1487  *
1488  * A variable can be eliminated using a given equality if it appears in this
1489  * equality, i.e. its associated coefficient is not equal to zero. Moreover,
1490  * for a given variable, we look for the equation in which it has the smallest
1491  * coefficient.
1492  *
1493  * Algo:
1494  * ----
1495  * BEGIN
1496  * vl = a copy of init_l;
1497  * el = NIL;
1498  * sc_elim = system with no constraints;
1499  * loop over the list of variables to eliminate vl
1500  * v = current variable;
1501  * eq = the equality of ps in which the coefficient of v is the smallest
1502  * if eq is not NULL
1503  * eq is taken off the list of equalities of ps
1504  * loop over the list of equalities of ps
1505  * eg = current equality
1506  * substitute in eg the value of v given by eq
1507  * end loop
1508  * loop over the list of inequalities of ps
1509  * eg = current inequality
1510  * substitute in eg the value of v given by eq
1511  * end loop
1512  * loop over the list of equalities of sc_elim
1513  * eg = current equality
1514  * substitute in eg the value of v given by eq
1515  * end loop
1516  * loop over the list of inequalities of sc_elim
1517  * eg = current inequality
1518  * substitute in eg the value of v given by eq
1519  * end loop
1520  * add eq in the list of equalities of sc_elim
1521  * remove v from init_l
1522  * add v in el
1523  * end if
1524  * end loop
1525  *
1526  * elim_l = el
1527  * END
1528  *
1529  * Note: Here is how we "substitute in eg the value of v given by eq":
1530  * if eg and eq are as follows (Vaux and Vsub do not contained v):
1531  * eg <=> c*v + Vaux = 0
1532  * eq <=> val*v = Vsub
1533  * let p = gcd(val,c)
1534  * after the substitution, we have:
1535  * eg <=> (c/p)*Vsub + (val/p)*Vaux = 0
1536  */
1538 Psysteme ps;
1539 list *init_l, *elim_l;
1540 {
1541  Psysteme sc_elim = sc_new();
1542 
1543  /* During the computation, we modify *init_l, so we duplicate it.
1544  * We use "el" not *elim_l, which should be empty at the beginning.
1545  */
1546  list vl = gen_append(*init_l, NIL),
1547  el = NIL,
1548  l;
1549  Pcontrainte eq, eg;
1550 
1551  for(l = vl; !ENDP(l); POP(l)) {
1552  Variable v = (Variable) ENTITY(CAR(l));
1553  Value coeff;
1554 
1555  if ((eq = contrainte_var_min_coeff(ps->egalites,v, &coeff, true))
1556  != NULL) {
1557 
1558  if(get_debug_level() > 7) {
1559 fprintf(stderr, "System is :");
1560 fprint_psysteme(stderr, ps);
1561 fprintf(stderr, "\t\tElim var %s in equation:", entity_local_name((entity) v));
1562 pu_vect_fprint(stderr, eq->vecteur);
1563 fprintf(stderr, "\n");
1564  }
1565 
1566  if(!egalite_normalize(eq))
1567  pips_internal_error("Strange equality");
1568 
1569  sc_nbre_egalites(ps)--;
1570  if (eq == (ps->egalites)) ps->egalites = eq->succ;
1571  /* si eq etait en tete il faut l'enlever de la liste, sinon, eq a
1572  ete enleve par la fonction contrainte_var_min_coeff(). */
1573 
1574  for(eg = ps->egalites; eg != NULL; eg = eg->succ)
1575  (void) contrainte_subst_ofl_ctrl(v, eq, eg, true, NO_OFL_CTRL);
1576  for(eg = ps->inegalites; eg != NULL; eg = eg->succ)
1577  (void) contrainte_subst_ofl_ctrl(v, eq, eg, false, NO_OFL_CTRL);
1578 
1579  for(eg = sc_elim->egalites; eg != NULL; eg = eg->succ)
1580  (void) contrainte_subst_ofl_ctrl(v, eq, eg, true, NO_OFL_CTRL);
1581  for(eg = sc_elim->inegalites; eg != NULL; eg = eg->succ)
1582  (void) contrainte_subst_ofl_ctrl(v, eq, eg, false, NO_OFL_CTRL);
1583 
1584  sc_add_egalite(sc_elim, eq);
1585  gen_remove(init_l, (void *) v);
1586  el = CONS(ENTITY, (entity) v, el);
1587  }
1588  }
1589 
1590  *elim_l = el;
1591  sc_elim->base = NULL;
1592  sc_creer_base(sc_elim);
1593 
1594  ifdebug(7) {
1595 fprintf(stderr, "[new_elim_var_with_eg] Results:\n");
1596 fprintf(stderr, "Elim sys:\n");
1597 fprint_entity_list(stderr, el);
1598 fprint_psysteme(stderr, sc_elim);
1599 fprintf(stderr, "Remnants sys:\n");
1600 fprint_entity_list(stderr, *init_l);
1601 fprint_psysteme(stderr, ps);
1602 fprintf(stderr, "\n");
1603  }
1604 
1605  return(sc_elim);
1606 }
1607 
1608 
1609 /*============================================================================*/
1610 /* bool single_var_vecteur_p(Pvecteur pv): returns true if the vector "pv"
1611  * contains only one element.
1612  *
1613  * Note: This element should not be a constant term (this is not tested).
1614  */
1616 {
1617  return(vect_size(pv) == 1);
1618 }
1619 
1620 
1621 /*============================================================================*/
1622 /* list vecteur_to_list(Pvecteur v): translates a Pvecteur into a list of
1623  * entities, in the same order.
1624  */
1625 /* FI: same comment as above: to be moved */
1627 {
1628  list l = NIL;
1629 
1630  for( ; v != NULL; v = v->succ)
1631  {
1632  entity var = (entity) v->var;
1633  if(var != (entity) TCST)
1634  l = gen_nconc(l, CONS(ENTITY, var, NIL));
1635  }
1636 
1637  return(l);
1638 }
1639 
1640 
1641 
1642 
1643 /*============================================================================*/
1644 /* Ppolynome old_vecteur_to_polynome(Pvecteur vec): translates a Pvecteur into a
1645  * Ppolynome.
1646  */
1647 /* FI: To be moved*/
1649 {
1650  Ppolynome pp_new = POLYNOME_NUL;
1651 
1652  for( ; vec != NULL; vec = vec->succ)
1653  polynome_add(&pp_new,
1654  make_polynome(VALUE_TO_FLOAT(vec->val), vec->var, VALUE_ONE));
1655 
1656  return(pp_new);
1657 }
1658 
1659 
1660 
1661 
1662 /*============================================================================*/
1663 /* list meld(list l1, list l2, bool (*compare_obj)()):
1664  */
1665 list meld(l1, l2, compare_obj)
1666 list l1, l2;
1667 bool (*compare_obj)();
1668 {
1669  if( ENDP(l1) ) {
1670  return(l2);
1671  }
1672  else if( ENDP(l2) ) {
1673  return(l1);
1674  }
1675  else if(compare_obj(CHUNK(CAR(l1)), CHUNK(CAR(l2)))) {
1676  return(gen_nconc(CONS(CHUNK, CHUNK(CAR(l1)), NIL),
1677  meld(CDR(l1), l2, compare_obj)));
1678  }
1679  else {
1680  return(gen_nconc(CONS(CHUNK, CHUNK(CAR(l2)), NIL),
1681  meld(l1, CDR(l2), compare_obj)));
1682  }
1683 }
1684 
1685 
1686 /*============================================================================*/
1687 /* list general_merge_sort(list l, bool (*compare_obj)()): returns the
1688  * result of sorting the list "l" using the comparison function
1689  * "compare_obj". This bool function should retuns true if its first
1690  * argument has to be placed before its second argument in the sorted
1691  * list, else FALSE.
1692  *
1693  * This is a generic function that accepts any homogene list of newgen
1694  * objects. The comparison function must be coded by the user, its
1695  * prototype should be: bool my_compare_obj(chunk * obj1, chunk *
1696  * obj2);
1697  *
1698  * This function uses the merge sort algorithm which has a mean and worst
1699  * case complexity of n*log(n). There are two steps. First, we look for
1700  * sublists that are in the right order, each time we found one we put it
1701  * in a list of lists, a LIFO queue ("head" is the out point, "tail" is
1702  * the in point). Second, we take the first two lists of our LIFO queue
1703  * (i.e. at the "head") and meld then into one list that we put again in
1704  * our LIFO (i.e. at the "tail"). We continue until there remains only
1705  * one list in our LIFO queue, which in that case is the sorted list we
1706  * wanted.
1707  */
1708 
1709 /* hack to preserve the bool comparison while using qsort...
1710  */
1712 static int compare_objects(p1, p2)
1713 gen_chunk **p1, **p2;
1714 {
1715  return(bool_compare_objects(*p2, *p1)-bool_compare_objects(*p1, *p2));
1716 }
1717 
1718 /* no way validate Prgm_mapping with this function...
1719  */
1721 list l;
1722 bool (*compare_obj)();
1723 {
1724  bool (*current)();
1725  list lnew = gen_copy_seq(l);
1726 
1727  /* push
1728  */
1730  bool_compare_objects = compare_obj;
1731 
1732  /* sort
1733  */
1735 
1736  /* pop
1737  */
1739 
1740  return(lnew);
1741 }
1742 
1743 /* I guess there is some kind of memory leaks here...
1744  * I tried the one above, but I could not go thru the validation...
1745  *
1746  * FC 02/01/94
1747  */
1748 list general_merge_sort(l, compare_obj)
1749 list l;
1750 bool (*compare_obj)();
1751 {
1752  list ch1, ch2, ch, ch_t, aux_l, head = NIL, tail = NIL;
1753  void * crt_obj, * prev_obj;
1754 
1755  pips_debug(9, "Debut\n");
1756 
1757  if( ENDP(l) || ENDP(CDR(l)) )
1758  return(l);
1759 
1760  /* First step */
1761  ch = l; /* current sublist containing sorted objects */
1762  ch_t = ch; /* tail of "ch" */
1763  prev_obj = CHUNK(CAR(l));
1764  for(aux_l = CDR(ch_t); !ENDP(aux_l); aux_l = CDR(ch_t), prev_obj = crt_obj) {
1765  crt_obj = CHUNK(CAR(aux_l));
1766  if(compare_obj(crt_obj, prev_obj)) {
1767  /* Current sublist stops here, we put it in our LIFO queue and ... */
1768  if(tail == NIL) {
1769  head = CONS(CONSP, ch, NIL);
1770  tail = head;
1771  }
1772  else {
1773  CDR(tail) = CONS(CONSP, ch, NIL);
1774  POP(tail);
1775  }
1776 
1777  /* ... we reinitialize our current sublist. */
1778  ch = CDR(ch_t);
1779  CDR(ch_t) = NIL;
1780  ch_t = ch;
1781  }
1782  else
1783  /* Else, current sublist increases. */
1784  POP(ch_t);
1785  }
1786  /* The last current sublist is put in our LIFO queue. */
1787  if(tail == NIL) {
1788  head = CONS(CONSP, ch, NIL);
1789  tail = head;
1790  }
1791  else {
1792  CDR(tail) = CONS(CONSP, ch, NIL);
1793  POP(tail);
1794  }
1795 
1796  /* Second step */
1797  for( ; ! ENDP(CDR(head)) ; ) {
1798  ch1 = CONSP(CAR(head));
1799  POP(head);
1800  ch2 = CONSP(CAR(head));
1801  POP(head);
1802  ch = meld(ch1, ch2, compare_obj);
1803 
1804  if(head == NIL) {
1805  head = CONS(CONSP, ch, NIL);
1806  tail = head;
1807  }
1808  else {
1809  CDR(tail) = CONS(CONSP, ch, NIL);
1810  POP(tail);
1811  }
1812  }
1813  pips_debug(9, "Fin\n");
1814 
1815  return(CONSP(CAR(head)));
1816 }
1817 
1818 
1819 /* ======================================================================== */
1820 /* expression rational_op_exp(char *op_name, expression exp1 exp2):
1821  * Returns an expression containing the operation "op_name" between "exp1"
1822  * and "exp2".
1823  * "op_name" must be one of the four classic operations : +, -, * or /.
1824  *
1825  * If both expressions are integer constant values and the operation
1826  * result is an integer then the returned expression contained the
1827  * calculated result, but this calculus is a rational one, not an integer one
1828  * as in make_op_exp().
1829  *
1830  * Else, we treat five special cases :
1831  * _ exp1 and exp2 are integer linear and op_name is + or -.
1832  * This case is resolved by make_lin_op_exp().
1833  * _ exp1 = 0
1834  * _ exp1 = 1
1835  * _ exp2 = 0
1836  * _ exp2 = 1
1837  *
1838  * Else, we create a new expression with a binary call.
1839  *
1840  * Note: The function MakeBinaryCall() comes from Pips/.../syntax/expression.c
1841  * The function int_to_expression() comes from ri-util.
1842  * Note: This function is almost equivalent to make_op_exp() but for the
1843  * rational calculus.
1844  */
1845 /* FI: to be moved in ri-util/expression.c */
1847 {
1848  expression result_exp = expression_undefined;
1849  entity op_ent, unary_minus_ent;
1850 
1851  pips_debug(7, "doing\n");
1853  op_name), entity_domain);
1854  unary_minus_ent =
1857  entity_domain);
1858 
1859  pips_debug(5, "begin OP EXP : %s %s %s\n",
1860  expression_to_string(exp1),
1861  op_name,
1862  expression_to_string(exp2));
1863 
1864  if( ! ENTITY_FOUR_OPERATION_P(op_ent) )
1865  user_error("rational_op_exp", "operation must be : +, -, * or /");
1866 
1867  if( expression_constant_p(exp1) && expression_constant_p(exp2) ) {
1868  int val1, val2;
1869 
1870  pips_debug(6, "Constant expressions\n");
1871  val1 = expression_to_int(exp1);
1872  val2 = expression_to_int(exp2);
1873 
1874  if (ENTITY_PLUS_P(op_ent))
1875  result_exp = int_to_expression(val1 + val2);
1876  else if(ENTITY_MINUS_P(op_ent))
1877  result_exp = int_to_expression(val1 - val2);
1878  else if(ENTITY_MULTIPLY_P(op_ent))
1879  result_exp = int_to_expression(val1 * val2);
1880  else { /* ENTITY_DIVIDE_P(op_ent) */
1881  /* rational calculus */
1882  if((val1 % val2) == 0)
1883  result_exp = int_to_expression((int) (val1 / val2));
1884  }
1885  }
1886  else {
1887  /* We need to know the integer linearity of both expressions. */
1888  normalized nor1 = NORMALIZE_EXPRESSION(exp1);
1889  normalized nor2 = NORMALIZE_EXPRESSION(exp2);
1890 
1891  if((normalized_tag(nor1) == is_normalized_linear) &&
1892  (normalized_tag(nor2) == is_normalized_linear) &&
1893  (ENTITY_PLUS_P(op_ent) || ENTITY_MINUS_P(op_ent)) ) {
1894  pips_debug(6, "Linear operation\n");
1895 
1896  result_exp = make_lin_op_exp(op_ent, exp1, exp2);
1897  }
1898  else if(expression_equal_integer_p(exp1, 0)) {
1899  if (ENTITY_PLUS_P(op_ent))
1900  result_exp = exp2;
1901  else if(ENTITY_MINUS_P(op_ent))
1902  result_exp = MakeUnaryCall(unary_minus_ent, exp2);
1903  else /* ENTITY_MULTIPLY_P(op_ent) || ENTITY_DIVIDE_P(op_ent) */
1904  result_exp = int_to_expression(0);
1905  }
1906  else if(expression_equal_integer_p(exp1, 1)) {
1907  if(ENTITY_MULTIPLY_P(op_ent))
1908  result_exp = exp2;
1909  }
1910  else if(expression_equal_integer_p(exp2, 0)) {
1911  if (ENTITY_PLUS_P(op_ent) || ENTITY_MINUS_P(op_ent))
1912  result_exp = exp1;
1913  else if (ENTITY_MULTIPLY_P(op_ent))
1914  result_exp = int_to_expression(0);
1915  else /* ENTITY_DIVIDE_P(op_ent) */
1916  user_error("rational_op_exp", "division by zero");
1917  }
1918  else if(expression_equal_integer_p(exp2, 1)) {
1919  if(ENTITY_MULTIPLY_P(op_ent) || ENTITY_DIVIDE_P(op_ent))
1920  result_exp = exp1;
1921  }
1922 
1923  /* Both expressions are unnormalized because they might be reused in
1924  * an unnormalized expression. */
1925  unnormalize_expression(exp1);
1926  unnormalize_expression(exp2);
1927  }
1928 
1929  if(result_exp == expression_undefined)
1930  result_exp = MakeBinaryCall(op_ent, exp1, exp2);
1931 
1932  pips_debug(5, "end OP EXP : %s\n",
1933  expression_to_string(result_exp));
1934 
1935  return (result_exp);
1936 }
1937 
1938 
1939 /*==================================================================*/
1940 /* Pvecteur vect_var_subst(vect,var,new_vect): substitute in the
1941  * vector "vect", the variable "var" by new_vect.
1942  * (vect) = (val)x(var) + (vect_aux)
1943  * => (vect) = (val)x(new_vect) + (vect_aux)
1944  *
1945  * AC 93/12/06
1946  */
1947 
1948 Pvecteur vect_var_subst(vect,var,new_vect)
1949 
1950  Pvecteur vect,new_vect;
1951  Variable var;
1952 {
1954  Value val;
1955 
1956  if ((val = vect_coeff(var,vect)) != 0)
1957  {
1958  vect_erase_var(&vect,var);
1959  vect_aux = vect_multiply(new_vect,val);
1960  vect = vect_add(vect, vect_aux);
1961  }
1962 
1963  return(vect);
1964 }
1965 
1966 /*==================================================================*/
1967 /*
1968  * Ppolynome prototype_var_subst(Ppolynome pp, Variable var,
1969  * Ppolynome ppsubst)
1970  *
1971  * Substitutes in polynome "pp" variable "var" by polynome "ppsubst".
1972  * "pp" is a prototype polynome, i.e. a linear fonction with symbolic
1973  * constants. Thus, there is no squared variables.
1974  *
1975  * This function takes advantage of that fact only when ppsubst in equal
1976  * to zero, else it uses polynome_var_subst().
1977  */
1979 Ppolynome pp;
1980 Variable var;
1981 Ppolynome ppsubst;
1982 {
1983  Ppolynome newpp;
1984 
1985  if(POLYNOME_NUL_P(ppsubst)) {
1986  Ppolynome ppp, p = POLYNOME_UNDEFINED;
1987  Pvecteur pv;
1988 
1989  newpp = polynome_dup(pp);
1990  for(ppp = newpp; ppp != NULL; ppp = ppp->succ) {
1991  entity first = entity_undefined,
1992  second = entity_undefined;
1993  pv = (ppp->monome)->term;
1994  for(; (pv != NULL) && (second == entity_undefined); pv = pv->succ) {
1995  second = first;
1996  first = (entity) pv->var;
1997  }
1998  if(pv != NULL)
1999  pips_internal_error("Vecteur should contains 2 var");
2000  else if( same_entity_p(first, (entity) var) ||
2001  same_entity_p(second, (entity) var)) {
2002  if(POLYNOME_UNDEFINED_P(p)) {
2003  newpp = ppp->succ;
2004  }
2005  else
2006  p->succ = ppp->succ;
2007  }
2008  else
2009  p = ppp;
2010  }
2011  }
2012  else
2013  newpp = polynome_var_subst(pp, var, ppsubst);
2014  return(newpp);
2015 }
2016 
2017 
2018 /* ======================================================================== */
2019 /*
2020  * Ppolynome vecteur_mult(Pvecteur v1, v2)
2021  *
2022  * Does the multiplication of two vectors, the result is a polynome.
2023  */
2025 {
2026  Ppolynome pp = POLYNOME_NUL, new_pp;
2027  Pvecteur pv1, pv2, ppv;
2028 
2029  if(VECTEUR_NUL_P(v1) || VECTEUR_NUL_P(v2))
2030  return(POLYNOME_NUL);
2031 
2032  for(pv1 = v1; pv1 != NULL; pv1 = pv1->succ) {
2033  Variable var1 = pv1->var;
2034  Value val1 = pv1->val;
2035  for(pv2 = v2; pv2 != NULL; pv2 = pv2->succ) {
2036  Variable var2 = pv2->var;
2037  Value val2 = pv2->val;
2038  Value p = value_mult(val1,val2);
2039  float f = VALUE_TO_FLOAT(p);
2040 
2041  if(var1 == TCST)
2042  new_pp = make_polynome(f, var2, VALUE_ONE);
2043  else if(var2 == TCST)
2044  new_pp = make_polynome(f, var1, VALUE_ONE);
2045  else if(same_entity_p((entity) var1, (entity) var2))
2046  new_pp = make_polynome(f, var1, VALUE_CONST(2));
2047  else {
2048  new_pp = make_polynome(f, var1, VALUE_ONE);
2049  ppv = (new_pp->monome)->term;
2050  pips_assert("succ is NULL", ppv->succ == NULL);
2051  ppv->succ = vect_new(var2, VALUE_ONE);
2052  }
2053  polynome_add(&pp, new_pp);
2054  }
2055  }
2056  return(pp);
2057 }
2058 
2059 
2060 /* ======================================================================== */
2061 /*
2062  * Pvecteur prototype_factorize(Ppolynome pp, Variable var)
2063  * returns the (linear) coefficient of var in polynomial pp.
2064  * "pp" is a prototype polynome, i.e. a linear fonction with symbolic
2065  * constants. Thus, there is no squared variables.
2066  *
2067  * This function takes plainly advantage of this property, and then is much
2068  * faster than polynome_factorize().
2069  */
2071 {
2072  Pvecteur pv = NULL;
2073 
2074  if(POLYNOME_NUL_P(pp))
2075  pv = VECTEUR_NUL;
2076  else if(var == TCST)
2077  {
2078  float f = polynome_TCST(pp);
2079  pv = vect_new(TCST, float_to_value(f));
2080  }
2081  else {
2082  Ppolynome ppp;
2083 
2084  for(ppp = pp; ppp != NULL; ppp = ppp->succ) {
2085  Variable newvar = VARIABLE_UNDEFINED;
2086  Value newval;
2087  Pvecteur vec, newpv;
2088  entity first = entity_undefined, second = entity_undefined;
2089  bool factor_found = true;
2090 
2091  vec = (ppp->monome)->term;
2092  for(; (vec != NULL) && (second == entity_undefined); vec = vec->succ) {
2093  second = first;
2094  first = (entity) vec->var;
2095  }
2096  if(vec != NULL)
2097  pips_internal_error("Vecteur should contains 2 var");
2098  else if(same_entity_p(first, (entity) var))
2099  if(second == entity_undefined)
2100  newvar = TCST;
2101  else
2102  newvar = (Variable) second;
2103  else if(same_entity_p(second, (entity) var))
2104  newvar = (Variable) first;
2105  else
2106  factor_found = false;
2107 
2108  if(factor_found) {
2109  newval = float_to_value((ppp->monome)->coeff);
2110  newpv = vect_new(newvar, newval);
2111  newpv->succ = pv;
2112  pv = newpv;
2113  }
2114  }
2115  }
2116 
2117  return(pv);
2118 }
2119 
2120 
2121 #define MINMAX_REF_NAME "MMREF"
2122 
2123 /*=================================================================== */
2124 /*
2125  * Pcontrainte simplify_minmax_contrainte(Pcontrainte pc, Psysteme
2126  * ps_cont, int min_or_max) :
2127  *
2128  * Parameters :
2129  * _ pc : a Pcontrainte, i.e. a list of vectors, noted (V1, ..., Vn)
2130  * _ ps_cont : a system of equations, called the context.
2131  * _ min_or_max : flag, says in which case we are (MIN or MAX)
2132  *
2133  * Result : list of vectors, a Pcontrainte
2134  *
2135  * Aims : simplify "pc", i.e. suppress one or more of its vectors. A
2136  * given vector can be suppressed if it surely smaller (case MAX) or
2137  * greater (case MIN) than one of the other. The case (MIN or MAX) is
2138  * given by "min_or_max". If two vectors can not be compared, both are
2139  * kept. The context allows the user to introduce relationship between
2140  * variables without which some vectors can not be eliminate.
2141  *
2142  * Algorithm : we use a function that eliminates redundances in a
2143  * system, sc_elim_redund(). This system corresponds to the context
2144  * augmented of following equations (i in {1, ...n}):
2145  * _ Case MAX : Vi - X <= 0
2146  * _ Case MIN : X - Vi <= 0
2147  * X is a special variable that represents the MAX or the MIN of our
2148  * vectors. This elimination returns a new system in which we only
2149  * have to get the equations containing X and remove this variable to
2150  * obtain our simplified list of vectors.
2151  *
2152  * Note : "pc" is not changed, the returned list of vectors is a new one. */
2153 
2154 Pcontrainte simplify_minmax_contrainte(pc, ps_cont, min_or_max)
2155 Pcontrainte pc;
2156 Psysteme ps_cont;
2157 int min_or_max;
2158 {
2159  Pcontrainte newnew_pc, new_pc, apc, pcc = CONTRAINTE_UNDEFINED,
2160  epc = CONTRAINTE_UNDEFINED;
2161  Psysteme psc, new_ps;
2162  entity ref_ent;
2163  int count;
2164  string exp_full_name;
2165 
2166  /* We get (or create) our special variable "X". */
2167  exp_full_name = strdup(concatenate(PAF_UTIL_MODULE_NAME,
2169  MINMAX_REF_NAME, (char *) NULL));
2170  ref_ent = gen_find_tabulated(exp_full_name, entity_domain);
2171  if(ref_ent == entity_undefined)
2172  ref_ent = make_entity(exp_full_name,
2174  make_variable(make_basic_int(4/*UU*/),
2175  NIL, NIL)),
2177  make_value_unknown());
2178 
2179 
2180  /* We put our special variable in our vectors. */
2181  for(apc = pc, count = 0; apc != NULL; apc = apc->succ, count++) {
2182  Pvecteur pv;
2183  Pcontrainte aapc;
2184 
2185  pv = vect_dup(apc->vecteur);
2186  if(min_or_max == IS_MIN) {
2187  vect_chg_sgn(pv);
2188  vect_add_elem(&pv, (Variable) ref_ent, (Value) 1);
2189  }
2190  else {/* min_or_max == IS_MAX */
2191  vect_add_elem(&pv, (Variable) ref_ent, (Value) -1);
2192  }
2193 
2194  aapc = contrainte_make(pv);
2195  if(CONTRAINTE_UNDEFINED_P(pcc)) {
2196  pcc = aapc;
2197  epc = aapc;
2198  }
2199  else {
2200  epc->succ = aapc;
2201  epc = epc->succ;
2202  }
2203  }
2204 
2205  /* We add the context. */
2206  psc = sc_dup(ps_cont);
2207  epc->succ = psc->inegalites;
2208  psc->inegalites = pcc;
2209  psc->nb_ineq += count;
2210  psc->base = NULL;
2211  sc_creer_base(psc);
2212 
2213  new_ps = sc_elim_redund(psc);
2214 
2215  new_pc = new_ps->inegalites;
2216 
2217  /* We remove our MINMAX variable. */
2218  newnew_pc = CONTRAINTE_UNDEFINED;
2219  for(apc = new_pc; apc != NULL; apc = apc->succ) {
2220  Pvecteur pv;
2221  Pcontrainte aapc;
2222  Value xc;
2223 
2224  pv = vect_dup(apc->vecteur);
2225  xc = vect_coeff((Variable) ref_ent, pv);
2226  if(value_one_p(xc) && (min_or_max == IS_MIN)) {
2227  vect_erase_var(&pv, (Variable) ref_ent);
2228  vect_chg_sgn(pv);
2229  aapc = contrainte_make(pv);
2230  aapc->succ = newnew_pc;
2231  newnew_pc = aapc;
2232  }
2233  else if(value_mone_p(xc) && (min_or_max == IS_MAX)) {
2234  vect_erase_var(&pv, (Variable) ref_ent);
2235  aapc = contrainte_make(pv);
2236  aapc->succ = newnew_pc;
2237  newnew_pc = aapc;
2238  }
2239  }
2240  return(newnew_pc);
2241 }
2242 
2243 
2244 /*================================================================== */
2246 Pcontrainte pc;
2247 {
2248  list lexp = NIL;
2249  Pcontrainte apc;
2250 
2251  for(apc = pc; apc != NULL; apc = apc->succ) {
2252  expression new_exp = make_vecteur_expression(apc->vecteur);
2253  ADD_ELEMENT_TO_LIST(lexp, EXPRESSION, new_exp);
2254  }
2255  return(lexp);
2256 }
2257 
2258 
2259 /*================================================================== */
2261 list lexp;
2262 {
2263  list ll;
2265 
2266  for(ll = lexp; !ENDP(ll); POP(ll)){
2267  Pvecteur pv;
2268  expression cexp = EXPRESSION(CAR(ll));
2269  normalized cnor;
2270 
2271  cnor = NORMALIZE_EXPRESSION(cexp);
2273  pips_internal_error("Expressions MUST be linear");
2274 
2275  pv = (Pvecteur) normalized_linear(cnor);
2276 
2277  if(CONTRAINTE_UNDEFINED_P(pc)) {
2278  pc = contrainte_make(pv);
2279  epc = pc;
2280  }
2281  else {
2282  Pcontrainte apc = contrainte_make(pv);
2283  epc->succ = apc;
2284  epc = epc->succ;
2285  }
2286  }
2287  return(pc);
2288 }
2289 
2290 
2291 /*================================================================== */
2292 /* list simplify_minmax(list lexp, Psysteme ps_cont, int min_or_max)
2293  *
2294  * Parameters :
2295  * _ lexp : list of LINEAR expressions
2296  * _ ps_cont : system of equations, called the context
2297  * _ min_or_max : flag, says in which case we are (MIN or MAX)
2298  *
2299  * Result : list of LINEAR expressions
2300  *
2301  * Aims : simplify "lexp", i.e. suppress one or more of its
2302  * expressions. A given expression can be suppressed if it surely
2303  * smaller (case MAX) or greater (case MIN) than one of the other. The
2304  * case (MIN or MAX) is given by "min_or_max". If two expressions can
2305  * not be compared, both are kept.The context allows the user to
2306  * introduce relationship between variables without which some vectors
2307  * can not be eliminate.
2308  *
2309  * Algorithm : see simplify_minmax_contrainte().
2310  *
2311  * Note : "lexp" is not changed, the returned list of expressions is a
2312  * new one. */
2313 list simplify_minmax(lexp, ps_cont, min_or_max)
2314 list lexp;
2315 Psysteme ps_cont;
2316 int min_or_max;
2317 {
2318  list new_lexp = NIL;
2319  Pcontrainte pc, new_pc;
2320 
2322 
2323  new_pc = simplify_minmax_contrainte(pc, ps_cont, min_or_max);
2324 
2325  new_lexp = vectors_to_expressions(new_pc);
2326 
2327  return(new_lexp);
2328 }
2329 
2330 
2331 /* ======================================================================== */
2332 /*
2333  * Psysteme find_implicit_equation(Psysteme ps)
2334  *
2335  * Returns a system containing the implicit equations of the system "ps".
2336  *
2337  * Each inequality may hides an implicit equation which means that all
2338  * solutions verify this equation. In order to find these implicit
2339  * equations, we have to test all the inequalities.
2340  *
2341  * Let Expr <= 0 be the current inequality, we replace it with Expr + 1 <=
2342  * 0. If the system is infeasible then we have found an implicit
2343  * equation.
2344  *
2345  * Explanation: Expr + 1 <= 0 means Expr <= -1. Then, if the new system is
2346  * infeasible though the original one is feasible, then Expr = 0 is
2347  * verified by all the solutions of the original system (it is an implicit
2348  * equation).
2349  * */
2351 {
2352  Pcontrainte ineg, eg;
2353  Psysteme impl_ps, aux_ps;
2354 
2355  if(ps == NULL)
2356  return(NULL);
2357 
2358  /* We put the equalities of the system in our implicit system. */
2359  impl_ps = sc_new();
2360  for(eg = ps->egalites; eg != NULL; eg = eg->succ)
2361  sc_add_egalite(impl_ps, contrainte_dup(eg));
2362 
2363  /* We duplicate "ps" in order to keep it unchanged. */
2364  aux_ps = sc_dup(ps);
2365 
2366  /* We make the test on each inequality. We count them. */
2367  for(ineg = aux_ps->inegalites; ineg != NULL; ineg = ineg->succ) {
2368  Pvecteur expr;
2369 
2370  /* We replace the original inequality (Expr <= 0) by the modified
2371  * one (Expr + 1 <= 0).
2372  */
2373  expr = ineg->vecteur;
2374  ineg->vecteur = vect_add(expr, vect_new(TCST, VALUE_ONE));
2375 
2376  /* We test the feasibility. If it is not feasible, we add one more
2377  * implicit equation in our implicit system : Expr == 0.
2378  */
2379  if(! sc_rational_feasibility_ofl_ctrl(aux_ps, NO_OFL_CTRL, true)) {
2380  Pcontrainte pc_expr = contrainte_make(expr);
2381 
2382  if(get_debug_level() > 7) {
2383  fprintf(stderr, "Equation implicit : ");
2384  pu_egalite_fprint(stderr, pc_expr, entity_local_name);
2385  fprintf(stderr, "\n");
2386  }
2387  sc_add_egalite(impl_ps, pc_expr);
2388  }
2389 
2390  /* We put the old value back */
2391  ineg->vecteur = expr;
2392  }
2393 
2394  sc_creer_base(impl_ps);
2395  impl_ps = sc_normalize(impl_ps);
2396 
2397  return(impl_ps);
2398 }
2399 
2400 
2401 
2402 /* These three functions respectively initialize, return and reset the
2403  static map of the static control on the statements. */
2404 
2406 
2407 /* ======================================================================== */
2409 {
2410  pips_assert("current_stco_map is defined", current_stco_map ==
2412 
2413  current_stco_map = scm;
2414 }
2415 
2416 /* ======================================================================== */
2418 {
2419  return current_stco_map;
2420 }
2421 
2422 /* ======================================================================== */
2424 {
2426 }
2427 
2428 /* ======================================================================== */
2430 {
2432 
2434 }
2435 
2436 /*======================================================================*/
2437 /* expression make_rational_exp(v, d)
2438  *
2439  * From the vector v and the integer d creates the expression of the
2440  * following form: v/d . AC 94/03/25
2441  *
2442  * Modification: this is an extension that verifies that v is not a
2443  * multiple of d, in which case it can be simplified, and no divide
2444  * operation is needed. AP 94/08/19 */
2445 
2447 Pvecteur v;
2448 Value d;
2449 {
2450  expression e;
2451 
2452  if(VECTEUR_NUL_P(v))
2453  /* make a "zero" expression */
2454  e = int_to_expression(0);
2455  else if(value_zero_p(value_mod(vect_pgcd_all(v), value_abs(d))))
2456  /* divide "v" by "d", and make the expression with no denominator */
2457  e = make_vecteur_expression(vect_div(v, d));
2458  else {
2459  expression e1, e2;
2460  entity ent;
2461  list le = NIL;
2462 
2463  /* build the denominator */
2464  e2 = Value_to_expression(d);
2465  le = CONS(EXPRESSION, e2, NIL);
2466 
2467  /* build the numerator */
2468  vect_normalize(v);
2469  e1 = make_vecteur_expression(v);
2470  le = CONS(EXPRESSION, e1, le);
2471 
2472  /* create the symbol of dividing */
2475  entity_domain);
2476 
2477  /* make the expression */
2479  make_call(ent, le)),
2481  }
2482 
2483  return(e);
2484 }
2485 
2486 
2487 
2488 /* AP, sep 25th 1995 : I have added a function from
2489  static_controlise/utils.c */
2490 
2491 /*=======================================================================*/
2492 /* int stco_common_loops_of_statements(in_map, in_s, in_s2 ) AL 22/10/93
2493  * Input : A statement mapping in_map wich associates a static_control
2494  * to each statement, and two statements in_s and in_s2.
2495  * Output : Number of same enclosing loops around ins_s and in_s2.
2496  */
2497 int stco_common_loops_of_statements(in_map, in_s, in_s2 )
2498 statement_mapping in_map;
2499 statement in_s, in_s2;
2500 {
2501  debug(9, "stco_common_loops_of_statements","doing\n");
2502  return( gen_length(stco_same_loops( in_map, in_s, in_s2 )) );
2503 }
call make_call(entity a1, list a2)
Definition: ri.c:269
loop copy_loop(loop p)
LOOP.
Definition: ri.c:1265
value make_value_unknown(void)
Definition: ri.c:2847
expression make_expression(syntax a1, normalized a2)
Definition: ri.c:886
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
basic make_basic_int(intptr_t _field_)
Definition: ri.c:158
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
syntax make_syntax(enum syntax_utype tag, void *val)
Definition: ri.c:2491
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
static int count
Definition: SDG.c:519
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static hash_table STS
The "STS" global variable is the hash table that maps the static_control on the statements.
Definition: adg_read_paf.c:155
#define VALUE_ZERO
#define value_mone_p(val)
#define value_oppose(ref)
#define value_notzero_p(val)
#define VALUE_CONST(val)
#define float_to_value(f)
#define value_one_p(val)
#define VALUE_MONE
#define value_zero_p(val)
int Value
#define VALUE_TO_FLOAT(val)
#define VALUE_ONE
#define value_abs(val)
#define value_mult(v, w)
whether the default is protected or not this define makes no sense any more...
#define value_mod(v1, v2)
#define value_neg_p(val)
#define value_div(v1, v2)
Value pgcd_slow(Value, Value)
pgcd.c
Definition: pgcd.c:44
static list lexp
Pbase base_union(Pbase b1, Pbase b2)
Pbase base_union(Pbase b1, Pbase b2): compute a new basis containing all elements of b1 and all eleme...
Definition: base.c:428
#define A(i, j)
comp_matrice.c
Definition: comp_matrice.c:63
#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
Pcontrainte contrainte_new(void)
package contrainte - allocations et desallocations
Definition: alloc.c:47
int contrainte_subst_ofl_ctrl(Variable v, Pcontrainte def, Pcontrainte c, bool eq_p, int ofl_ctrl)
int contrainte_subst_ofl_ctrl(Variable v, Pcontrainte def, Pcontrainte c Boolean eq_p,...
Definition: binaires.c:107
Pcontrainte contrainte_var_min_coeff(Pcontrainte, Variable, Value *, bool)
Pcontrainte contrainte_var_min_coeff(Pcontrainte contraintes, Variable v, int *coeff) input : a list ...
Definition: unaires.c:345
bool egalite_normalize(Pcontrainte)
bool egalite_normalize(Pcontrainte eg): reduction d'une equation diophantienne par le pgcd de ses coe...
Definition: normalize.c:136
#define dg_vertex_label_statement(x)
Definition: dg.h:235
string make_entity_fullname(const char *module_name, const char *local_name)
END_EOLE.
Definition: entity_names.c:230
#define CHUNK(x)
Definition: genC.h:90
#define CONSP(x)
Definition: genC.h:88
#define vertex_undefined
Definition: graph.h:128
#define successor_arc_label(x)
Definition: graph.h:116
#define vertex_vertex_label(x)
Definition: graph.h:152
#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
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
list gen_append(list l1, const list l2)
Definition: list.c:471
void gen_sort_list(list l, gen_cmp_func_t compare)
Sorts a list of gen_chunks in place, to avoid allocations...
Definition: list.c:796
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
void fprint_entity_list(FILE *fp, list l)
void fprint_entity_list(FILE *fp,list l): prints a list of entities on file fp.
Definition: entity.c:3188
#define B(A)
Definition: iabrev.h:61
#define ADD_ELEMENT_TO_LIST(_list, _type, _element)
Definition: icfg-local.h:50
static void term(Pproblem XX, int s, Value k, int x)
Definition: isolve.c:315
Value vect_pgcd_all(Pvecteur v)
Value vect_pgcd(Pvecteur v): calcul du pgcd de tous les coefficients non nul d'un vecteur v.
Definition: reductions.c:108
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 ACCESS(matrix, column, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrice-local.h:86
Value * matrice
package matrice
Definition: matrice-local.h:71
void matrice_nulle(matrice Z, int n, int m)
void matrice_nulle(matrice Z, int n, int m): Initialisation de la matrice Z a la valeur matrice nulle
Definition: matrice.c:311
#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 user_error(fn,...)
Definition: misc-local.h:265
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
Definition: debug.c:67
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define MODULE_SEP_STRING
Definition: naming-local.h:30
#define GET_STATEMENT_MAPPING(map, stat)
Definition: newgen-local.h:49
#define assert(ex)
Definition: newgen_assert.h:41
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
int bool
we cannot use an enum or stdbool because we need to be compatible with newgen, thus boolean need to h...
Definition: newgen_types.h:78
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define PAF_UTIL_MODULE_NAME
#define IS_MIN
#define IS_MAX
#define DFG_MODULE_NAME
dataflow first_df_of_succ(successor s)
===========================================================================
Definition: utils.c:1004
expression rational_op_exp(string op_name, expression exp1, expression exp2)
========================================================================
Definition: utils.c:1846
#define ENTITY_FOUR_OPERATION_P(s)
Definition: utils.c:107
void substitute_var_with_vec(Psysteme ps, entity var, Value val, Pvecteur vec)
===========================================================================
Definition: utils.c:1210
dfg_arc_label arc_label
Name : utils.c Package : paf-util Author : Alexis Platonoff Date : july 1993.
Definition: utils.c:88
void matrices_to_contraintes_with_sym_cst(Pcontrainte *pc, Pbase index_base, Pbase const_base, matrice A, matrice B, int n, int m1, int m2)
Definition: utils.c:503
vertex in_dg_vertex_list(list l, vertex v)
======================================================================
Definition: utils.c:647
#define MINMAX_REF_NAME
Definition: utils.c:2121
bool is_entity_in_list_p(entity e, list l)
===========================================================================
Definition: utils.c:1281
expression make_id_expression(string s)
===========================================================================
Definition: utils.c:672
Ppolynome old_vecteur_to_polynome(Pvecteur vec)
===========================================================================
Definition: utils.c:1648
Pvecteur polynome_to_vecteur(Ppolynome pp)
========================================================================
Definition: utils.c:1063
Pcontrainte expressions_to_vectors(list lexp)
=================================================================
Definition: utils.c:2260
list vecteur_to_list(Pvecteur v)
===========================================================================
Definition: utils.c:1626
successor first_succ_of_vertex(vertex v)
===========================================================================
Definition: utils.c:994
list general_merge_sort(list l, bool(*compare_obj)())
I guess there is some kind of memory leaks here...
Definition: utils.c:1748
Psysteme better_elim_var_with_eg(Psysteme ps, list *init_l, list *elim_l)
===========================================================================
Definition: utils.c:1537
list static_control_to_indices(static_control stct)
package mapping : Alexis Platonoff, july 1993
Definition: utils.c:1037
Ppolynome vecteur_mult(Pvecteur v1, Pvecteur v2)
========================================================================
Definition: utils.c:2024
int stco_common_loops_of_statements(statement_mapping in_map, statement in_s, statement in_s2)
AP, sep 25th 1995 : I have added a function from static_controlise/utils.c.
Definition: utils.c:2497
void pu_matrices_to_contraintes(Pcontrainte *pc, Pbase b, matrice A, matrice B, int n, int m)
Global variables
Definition: utils.c:350
Psysteme find_implicit_equation(Psysteme ps)
========================================================================
Definition: utils.c:2350
expression negate_expression(expression exp)
===========================================================================
Definition: utils.c:792
loop loop_dup(loop l)
===========================================================================
Definition: utils.c:1014
dfg_vertex_label vertex_label
Definition: utils.c:89
Pcontrainte simplify_minmax_contrainte(Pcontrainte pc, Psysteme ps_cont, int min_or_max)
==================================================================
Definition: utils.c:2154
static statement_mapping current_stco_map
These three functions respectively initialize, return and reset the static map of the static control ...
Definition: utils.c:2405
list vectors_to_expressions(Pcontrainte pc)
=================================================================
Definition: utils.c:2245
Psysteme make_expression_equalities(list le)
===========================================================================
Definition: utils.c:931
expression make_array_ref(list l)
===========================================================================
Definition: utils.c:702
static int compare_objects(gen_chunk **p1, gen_chunk **p2)
Definition: utils.c:1712
list meld(list l1, list l2, bool(*compare_obj)())
===========================================================================
Definition: utils.c:1665
Ppolynome prototype_var_subst(Ppolynome pp, Variable var, Ppolynome ppsubst)
=================================================================
Definition: utils.c:1978
Pbase make_base_of_nest(int stmt)
===========================================================================
Definition: utils.c:977
void reset_current_stco_map(void)
========================================================================
Definition: utils.c:2423
int vertex_int_stmt(vertex v)
===========================================================================
Definition: utils.c:866
list new_general_merge_sort(list l, bool(*compare_obj)())
no way validate Prgm_mapping with this function...
Definition: utils.c:1720
expression make_rational_exp(Pvecteur v, Value d)
=====================================================================
Definition: utils.c:2446
static_control get_stco_from_current_map(statement s)
========================================================================
Definition: utils.c:2429
Pvecteur prototype_factorize(Ppolynome pp, Variable var)
========================================================================
Definition: utils.c:2070
Psysteme polynome_to_sc(Ppolynome pp, list l)
===========================================================================
Definition: utils.c:1158
void contraintes_with_sym_cst_to_matrices(Pcontrainte pc, Pbase index_base, Pbase const_base, matrice A, matrice B, int n, int m1, int m2)
Creation de la matrice A correspondant au systeme lineaire et de la matrice correspondant a la partie...
Definition: utils.c:446
#define STRING_FOUR_OPERATION_P(s)
Macro functions.
Definition: utils.c:102
static list find_el_with_num(int stmt)
===========================================================================
Definition: utils.c:964
bool single_var_vecteur_p(Pvecteur pv)
===========================================================================
Definition: utils.c:1615
predicate expressions_to_predicate(list exp_l)
===========================================================================
Definition: utils.c:826
expression make_func_op(string func_name, list args)
===========================================================================
Definition: utils.c:725
vertex in_dfg_vertex_list(list l, vertex v)
===========================================================================
Definition: utils.c:620
static bool(* bool_compare_objects)()
===========================================================================
Definition: utils.c:1711
list simplify_minmax(list lexp, Psysteme ps_cont, int min_or_max)
=================================================================
Definition: utils.c:2313
expression lisp_exp_to_ri_exp(lisp_expression le)
===========================================================================
Definition: utils.c:755
Psysteme elim_var_with_eg(Psysteme ps, list *init_l, list *elim_l)
===========================================================================
Definition: utils.c:1361
void pu_contraintes_to_matrices(Pcontrainte pc, Pbase b, matrice A, matrice B, int n, int m)
===========================================================================
Definition: utils.c:408
void comp_exec_domain(graph g, hash_table STS)
===========================================================================
Definition: utils.c:877
void set_current_stco_map(statement_mapping scm)
========================================================================
Definition: utils.c:2408
statement_mapping get_current_stco_map(void)
========================================================================
Definition: utils.c:2417
Psysteme old_polynome_to_sc(Ppolynome pp, list l)
===========================================================================
Definition: utils.c:1115
Pvecteur vect_var_subst(Pvecteur vect, Variable var, Pvecteur new_vect)
=================================================================
Definition: utils.c:1948
Pcontrainte polynome_to_contrainte(Ppolynome pp)
========================================================================
Definition: utils.c:1095
void pu_vect_fprint(FILE *, Pvecteur)
===========================================================================
Definition: print.c:446
void pu_egalite_fprint(FILE *, Pcontrainte, const char *(*)(entity))
void fprint_psysteme(FILE *, Psysteme)
===========================================================================
Definition: print.c:302
#define static_control_loops(x)
Definition: paf_ri.h:757
#define DATAFLOW(x)
DATAFLOW.
Definition: paf_ri.h:308
struct _newgen_struct_static_control_ * static_control
Definition: paf_ri.h:184
#define dfg_arc_label_dataflows(x)
Definition: paf_ri.h:378
#define lisp_expression_operation(x)
Definition: paf_ri.h:487
struct _newgen_struct_dfg_vertex_label_ * dfg_vertex_label
Definition: paf_ri.h:112
#define dfg_vertex_label_statement(x)
Definition: paf_ri.h:413
#define lisp_expression_args(x)
Definition: paf_ri.h:489
#define dfg_vertex_label_exec_domain(x)
Definition: paf_ri.h:415
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
Ppolynome make_polynome(float coeff, Variable var, Value expo)
Ppolynome make_polynome(float coeff, Variable var, Value expo) PRIVATE allocates space for,...
Definition: pnome-alloc.c:100
Ppolynome polynome_dup(Ppolynome pp)
Ppolynome polynome_dup(Ppolynome pp) creates and returns a copy of pp.
Definition: pnome-alloc.c:211
void polynome_add(Ppolynome *ppp, Ppolynome pp2)
void polynome_add(Ppolynome* ppp, Ppolynome pp2) (*ppp) = (*ppp) + pp2.
Definition: pnome-bin.c:171
float polynome_TCST(Ppolynome pp)
float polynome_TCST(Ppolynome pp) returns the constant term of polynomial pp.
Definition: pnome-reduc.c:156
Ppolynome polynome_var_subst(Ppolynome pp, Variable var, Ppolynome ppsubst)
Ppolynome polynome_var_subst(Ppolynome pp, Variable var, Ppolynome ppsubst) creates and returns a Ppo...
Definition: pnome-reduc.c:47
Ppolynome polynome_factorize(Ppolynome pp, Variable var, int n)
Ppolynome polynome_factorize(Ppolynome pp, Variable var, int n) returns the (polynomial) coefficient ...
Definition: pnome-reduc.c:131
#define POLYNOME_NUL
#define POLYNOME_UNDEFINED
#define POLYNOME_UNDEFINED_P(pp)
#define POLYNOME_NUL_P(pp)
string expression_to_string(expression e)
Definition: expression.c:77
#define ENTITY_DIVIDE_P(e)
#define ENTITY_MINUS_P(e)
#define ENTITY_PLUS_P(e)
#define ENTITY_MULTIPLY_P(e)
#define NORMALIZE_EXPRESSION(e)
#define make_entity(n, t, s, i)
#define DIVIDE_OPERATOR_NAME
#define UNARY_MINUS_OPERATOR_NAME
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 same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
expression make_vecteur_expression(Pvecteur pv)
make expression for vector (Pvecteur)
Definition: expression.c:1650
expression make_lin_op_exp(entity op_ent, expression exp1, expression exp2)
================================================================
Definition: expression.c:2147
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
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
expression Value_to_expression(Value v)
added interface for linear stuff.
Definition: expression.c:1251
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
bool expression_equal_integer_p(expression exp, int i)
================================================================
Definition: expression.c:1977
#define normalized_undefined
Definition: ri.h:1745
#define syntax_reference_p(x)
Definition: ri.h:2728
#define LOOP(x)
LOOP.
Definition: ri.h:1606
#define syntax_reference(x)
Definition: ri.h:2730
#define normalized_complex_p(x)
Definition: ri.h:1782
#define normalized_linear_p(x)
Definition: ri.h:1779
#define range_upper(x)
Definition: ri.h:2290
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define ram_undefined
Definition: ri.h:2221
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
@ is_storage_ram
Definition: ri.h:2492
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define normalized_tag(x)
Definition: ri.h:1778
#define predicate_undefined
Definition: ri.h:2046
#define reference_indices(x)
Definition: ri.h:2328
#define range_lower(x)
Definition: ri.h:2288
#define loop_range(x)
Definition: ri.h:1642
@ is_type_variable
Definition: ri.h:2900
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define loop_index(x)
Definition: ri.h:1640
@ is_normalized_linear
Definition: ri.h:1760
@ is_normalized_complex
Definition: ri.h:1761
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_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
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_elim_redund(Psysteme ps)
Psysteme sc_elim_redund(Psysteme ps): elimination des contraintes lineaires redondantes dans le syste...
Psysteme sc_elim_db_constraints(Psysteme ps)
Psysteme sc_elim_db_constraints(Psysteme ps): elimination des egalites et des inegalites identiques o...
bool sc_rational_feasibility_ofl_ctrl(Psysteme sc, int ofl_ctrl, bool ofl_res)
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
int printf()
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
Pvecteur vect_div(Pvecteur v, Value x)
Pvecteur vect_div(Pvecteur v, Value x): division du vecteur v par le scalaire x, si x est different d...
Definition: scalaires.c:52
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
#define ifdebug(n)
Definition: sg.c:47
Pvecteur vect_aux
Definition: solpip.c:102
list stco_same_loops(statement_mapping in_map, statement in_s, statement in_s2)
======================================================================
Definition: utils.c:98
static size_t current
Definition: string.c:115
Definition: pip__tab.h:25
Pvecteur vecteur
struct Scontrainte * succ
Pmonome monome
struct Spolynome * succ
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
Pbase base
Definition: sc-local.h:75
int nb_ineq
Definition: sc-local.h:73
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Value val
Definition: vecteur-local.h:91
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
Definition: statement.c:54
A gen_chunk is used to store every object.
Definition: genC.h:58
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define NO_OFL_CTRL
struct Svecteur * Pbase
struct Svecteur * Pvecteur
#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 VARIABLE_UNDEFINED
Definition: vecteur-local.h:64
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
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_cl2_ofl_ctrl(Value x1, Pvecteur v1, Value x2, Pvecteur v2, int ofl_ctrl)
Pvecteur vect_cl2_ofl(Value x1, Pvecteur v1, Value x2, Pvecteur v2): allocation d'un vecteur v dont l...
Definition: binaires.c:204
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75
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
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
void vect_normalize(Pvecteur v)
void vect_normalize(Pvecteur v): division de tous les coefficients de v par leur pgcd; "normalisation...
Definition: unaires.c:59