PIPS
testdep_util.c
Go to the documentation of this file.
1 /*
2 
3  $Id: testdep_util.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 /* here is a collection of function intended to create and manipulate "di"
28  variables and test of dependence. di variables are pseudo variables
29  created by PIPS and not accessible to the user that represent the
30  distance between two dependent statement iterations. the sign of this
31  distance is sufficient for Kennedy's way of parallelizing programs, but
32  the exact value migth be of interest for other algorithms such as
33  systolic algorithms.
34 
35  Written by Remi, Yi-Qing; reorganized by Yi-Qing (18/09/91)
36  */
37 
38 #include "local.h"
39 #include "prettyprint.h" // for egalite_debug() and sc_syst_debug()
40 
41 /* To deal with overflow errors occuring during the projection
42  * of a Psysteme along a variable */
43 
44 /* The tables of di variables, li variables and ds variables.
45  *
46  * Variable DiVars[i-1] or LiVars[i-1] is associated to the loop at nesting
47  * level i. A di variable represents the difference in iteration number
48  * between the two references considered.
49  *
50  * The variable DsiVars[i] is associated to the ith element in the list
51  * of scalar variables modified in the loops
52  */
56 
57 /* This function creates di variables. There are MAXDEPTH di variables
58  which means that programs with more than MAXDEPTH nested loops cannot be
59  parallelized by pips.
60 
61  @param l is the nesting level of the variable to create
62  */
63 entity MakeDiVar(int l) {
64  entity e;
65  string s;
66  /* Create a variable of this format: "d#X" */
67  asprintf(&s, "%s%sd#%d", DI_VAR_MODULE_NAME, MODULE_SEP_STRING, l);
68 
71  else
72  free(s);
73 
74  return (e);
75 }
76 
77 /* This functions looks up a di variable of nesting level l in table
78  DiVars. di variables are created if they do not exist. */
80  int l; {
81  entity e;
82 
83  if(l < 1 || l > MAXDEPTH)
84  user_error("parallelize", "too many nested loops\n");
85 
86  if((e = DiVars[l - 1]) == (entity)0) {
87  int i;
88  for (i = 0; i < MAXDEPTH; i++)
89  DiVars[i] = MakeDiVar(i + 1);
90 
91  e = DiVars[l - 1];
92  }
93 
94  return (e);
95 }
96 
97 /* This function creates li variables(thee ith loop index variable).
98 
99  There are MAXDEPTH li variables which means that programs with more
100  than MAXDEPTH nested loops cannot be parallelized by pips.
101 
102  @param l is the nesting level of the variable to create */
104  entity e;
105  string s;
106  /* Create a variable of this format: "l#X" */
107  asprintf(&s, "%s%sl#%d", DI_VAR_MODULE_NAME, MODULE_SEP_STRING, l);
108 
111  else
112  free(s);
113 
114  return (e);
115 }
116 
117 /*
118  this functions looks up a li variable of nesting level l in table
119  LiVars. li variables are created if they do not exist.
120  */
122  int l; {
123  entity e;
124 
125  if(l < 1 || l > MAXDEPTH)
126  user_error("parallelize", "too many nested loops\n");
127 
128  if((e = LiVars[l - 1]) == (entity)0) {
129  int i;
130  for (i = 0; i < MAXDEPTH; i++)
131  LiVars[i] = MakeLiVar(i + 1);
132 
133  e = LiVars[l - 1];
134  }
135 
136  return (e);
137 }
138 
139 /* This function creates dsi variables.
140 
141  There are MAXSV dsi variables which means that programs with more than
142  MAXSV scalar variables cannot be parallelized by PIPS.
143 
144  @param l means to create Dsi[l] variable
145  */
147  entity e;
148  string s;
149  /* Create a variable of this format: "ds#XXXX" */
150  asprintf(&s, "%s%sds#%.4d", DI_VAR_MODULE_NAME, MODULE_SEP_STRING, l);
151 
154  else
155  free(s);
156 
157  return (e);
158 }
159 
160 /*
161  this functions looks up a dsi variable of the lth varable in table
162  DsiVars. dsi variables are created if they do not exist.
163  */
165  int l; {
166  entity e;
167 
168  if(l < 1 || l > MAXSV)
169  user_error("parallelize", "too many scalar variables\n");
170 
171  if((e = DsiVars[l - 1]) == (entity)0) {
172  int i;
173  for (i = 0; i < MAXSV; i++)
174  DsiVars[i] = MakeDsiVar(i + 1);
175 
176  e = DsiVars[l - 1];
177  }
178 
179  return (e);
180 }
181 
182 /*
183  this function returns the nesting level of a given di variable e.
184  */
186  entity e; {
187  int i;
188 
189  for (i = 0; i < MAXDEPTH; i++)
190  if(e == DiVars[i])
191  return (i + 1);
192 
193  return (0);
194 }
195 
196 
197 /*
198  this function replaces each occurrence of variable e in system s by
199  (e+dl) where dl is the di variable of nesting level l.
200 
201  l is the nesting level.
202 
203  e is the variable to replace.
204 
205  s is the system where replacements are to be done.
206 
207  li is the numerical value of the loop increment expression.
208  */
209 void sc_add_di(l, e, s, li)
210  int l;entity e;Psysteme s;int li; {
211  Variable v = (Variable)GetDiVar(l);
212  Value vli = int_to_value(li);
213  Pcontrainte pc;
214 
215  for (pc = s->egalites; pc != NULL; pc = pc->succ) {
216  Value ve = vect_coeff((Variable)e, pc->vecteur);
217  value_product(ve, vli);
218  vect_add_elem(&(pc->vecteur), v, ve);
219  }
220 
221  for (pc = s->inegalites; pc != NULL; pc = pc->succ) {
222  Value ve = vect_coeff((Variable)e, pc->vecteur);
223  value_product(ve, vli);
224  vect_add_elem(&(pc->vecteur), v, ve);
225  }
226 }
227 
228 /*
229  this function replaces each occurrence of variable e in system s by
230  (e+dsl) where dsl is the dsi variable of the lth element in the list of scalar variable.
231 
232  l is the order of e in the list.
233 
234  e is the variable to replace.
235 
236  s is the system where replacements are to be done.
237  */
238 void sc_add_dsi(l, e, s)
239  int l;entity e;Psysteme s; {
240  Variable v = (Variable)GetDsiVar(l);
241  Pcontrainte pc;
242  for (pc = s->egalites; pc != NULL; pc = pc->succ) {
243  vect_add_elem(&(pc->vecteur), v, vect_coeff((Variable)e, pc->vecteur));
244  }
245 
246  for (pc = s->inegalites; pc != NULL; pc = pc->succ) {
247  vect_add_elem(&(pc->vecteur), v, vect_coeff((Variable)e, pc->vecteur));
248  }
249 }
250 
251 
252 
253 /*
254  this function projects a system on a set of di variables. this set is
255  defined by cl, the common nesting level of the two array references
256  being tested: only di variables whose nesting level is less or equal
257  than cl are kept in the projected system.
258 
259  projection is done by eliminating variables (Fourier-Motzkin) which are
260  not part of the set.
261 
262  cl is the common nesting level.
263 
264  s is the system to project. s is modified.
265  */
266 
267 int sc_proj_on_di(cl, s)
268  int cl;Psysteme s; {
269  Pbase coord;
270 
271  for (coord = s->base; !VECTEUR_NUL_P(coord); coord = coord->succ) {
272  Variable v = vecteur_var(coord);
273  int l = DiVarLevel((entity)v);
274 
275  if(l <= 0 || l > cl) {
276  debug(8,
277  "ProjectOnDi",
278  "projection sur %s\n",
280  if(SC_EMPTY_P(s = sc_projection_pure(s, v))) {
281  debug(8, "ProjectOnDi", "infaisable\n");
282  return (false);
283  }
284  debug(8, "ProjectOnDi", "faisable\n");
285  }
286  }
287 
288  return (true);
289 }
290 
291 
292 
293 /* Pbase MakeDibaseinorder(int n) make a base of D#1 ... D#n in order of
294  * D#1-> D#2, ...-> D#n.
295  */
297  int n; {
298  Pbase Dibase = BASE_NULLE;
299  int i;
300 
301  for (i = 1; i <= n; i++) {
302  Dibase = vect_add_variable(Dibase, (Variable)GetDiVar(n - i + 1));
303  }
304  return (Dibase);
305 }
306 
308  cons *n1, *n2; {
309  int cl = 0;
310 
311  while(n1 != NIL && n2 != NIL) {
312  if(LOOP(CAR(n1)) != LOOP(CAR(n2)))
313  break;
314  n1 = CDR(n1);
315  n2 = CDR(n2);
316  cl += 1;
317  }
318 
319  return (cl);
320 }
321 
322 
323 /* Management of loop counters */
324 
325 #define ILCMAX 100000
326 
327 static int ilc = ILCMAX;
328 
330  ilc = 0;
331 }
332 
333 /* Create a new loop counter variable */
335  entity e;
336  string s;
337  //static char lcn[] = "lc#XXXXXX";
338 
339  while(1) {
340  /* Create a variable of this format: "lc#XXXXXX" */
341  asprintf(&s,
342  "%s%slc#%06d",
345  ilc);
346 
348  pips_debug(8, "loop counter is %s\n", s);
349  return make_entity(strdup(s),
353  } else
354  free(s);
355 
356  /* Try a new free one: */
357  if((ilc += 1) == ILCMAX)
358  break;
359  }
360 
361  pips_internal_error("too many loop counters");
362  return (entity_undefined);
363 }
364 
365 
366 /* int dep_type(action ac1,action ac2)
367  * This function test the type of the dependence. ac1, ac2 are the action of
368  * two references.The representations of the result are as follows.
369  * 0 ---- def-use dependence
370  * 1 ---- use-def dependence
371  * 2 ---- def-def dependence
372  * 3 ---- use-use dependence (added in 20/01/92)
373  * FI->YY: we also have use-use dependence (also called input dependence);
374  * there is no reason to abort here; input dependences should just be
375  * ignored for parallelization, but not for tiling or cache optimization
376  */
377 
378 int dep_type(ac1, ac2)
379  action ac1, ac2; {
380  if(action_write_p(ac1) && action_read_p(ac2))
381  return (0);
382  else if(action_read_p(ac1) && action_write_p(ac2))
383  return (1);
384  else if(action_write_p(ac1) && action_write_p(ac2))
385  return (2);
386  else if(action_read_p(ac1) && action_read_p(ac2))
387  return (3);
388  else
389  pips_internal_error("A undefined chain ---chains fault");
390 
391  /* to please gcc */
392  return -1;
393 }
394 
395 /* int sc_proj_optim_on_di_ofl(cl, sc)
396  *
397  * This function projects a system onto a set of di variables. This set is
398  * defined by cl, the common nesting level of the two array references
399  * being tested: only di variables whose nesting level is less than or equal to
400  * cl are kept in the projected system (i.e. outermost loops).
401  *
402  * The projection is performed by first eliminating variables in the
403  * equations. Variables whose coefficients are 1 or -1 are considered first.
404  * (in such case it's integer elimination). Remaining inequalities are
405  * projected by Fourier-Motzkin elimination.
406  *
407  * cl is the common nesting level.
408  * sc is the system to project. sc is modified but psc always points to
409  * a consistent Psysteme on return (i.e. it's up to the caller to free it).
410  * *psc on return is sc_empty() if *psc on entry turns out to be
411  * non-feasible.
412  * a long jump buffer must have been initialized to handle overflows
413  * The value returned is true if the system is feasible, false otherwise.
414  */
416 {
417  Pbase coord;
418  Pvecteur pv = VECTEUR_NUL;
419  Variable v;
420  int l;
421  int res;
422 
423  pips_debug(6, "begin\n");
424 
425  /* find the set of variables to be eliminated */
426  for (coord = (*psc)->base; !VECTEUR_NUL_P(coord); coord = coord->succ) {
427  v = vecteur_var(coord);
428  l = DiVarLevel((entity)v);
429 
430  if(l <= 0 || l > cl) /* find one */
431  vect_add_elem(&pv, v, 1);
432  }
433 
434  ifdebug(6) {
435  fprintf(stderr, "The list of variables to be eliminated is :\n");
436  vect_debug(pv);
437  }
438  is_test_Di = true;
439 
440  pips_assert("Dependence system *psc is consistent before projection",
441  sc_consistent_p(*psc));
442 
443  *psc = sc_projection_optim_along_vecteur_ofl(*psc, pv);
444 
445  pips_assert("Dependence system *psc is consistent after projection",
446  sc_consistent_p(*psc));
447 
448  if(sc_empty_p(*psc))
449  res = false;
450  else
451  res = true;
452 
453 
454  vect_rm(pv);
455 
456 
457  pips_assert("Dependence system *psc is consistent after empty test",
458  sc_consistent_p(*psc));
459  pips_debug(6, "end\n");
460 
461  return res;
462 }
463 
464 /* bool sc_faisabilite_optim (Psysteme sc) :
465  *
466  * Test system sc feasibility by successive projections
467  * along all variables in its basis.
468  *
469  * carry out the projection with function sc_projection_optim_along_vecteur().
470  *
471  * sc_normalize() is called here before the projection, which means
472  * that sc may be deallocated
473  *
474  * result :
475  *
476  * boolean : true if system is faisable
477  * false else
478  *
479  * Modification:
480  * - call to sc_rm() added when sc_projection_optim_along_vecteur_ofl()
481  * returns sc_empty; necessary to have a consistent interface: when FALSE
482  * is returned, sc always has been freed.
483  */
485  Psysteme sc; {
486  debug(6, "sc_faisabilite_optim", "begin\n");
487  sc = sc_normalize(sc);
488  if(!sc_empty_p(sc)) {
489  /* Automatic variables read in a CATCH block need to be declared volatile as
490  * specified by the documentation*/
491  Psysteme volatile sc1 = sc_dup(sc);
492  is_test_Di = false;
493 
495  pips_debug(7, "overflow error, returning TRUE. \n");
496  sc_rm(sc1);
497  debug(6, "sc_faisabilite_optim", "end\n");
498  return (true);
499 
500  } TRY {
501  Pbase base_sc1 = base_dup(sc1->base);
502  sc1 = sc_projection_optim_along_vecteur_ofl(sc1, base_sc1);
503  base_rm(base_sc1);
504  if(sc_empty_p(sc1)) {
505  debug(7, "sc_faisabilite_optim", "system not feasible\n");
506  debug(6, "sc_faisabilite_optim", "end\n");
507  sc_rm(sc);
509  return (false);
510  } else {
511  sc_rm(sc1);
512  debug(7, "sc_faisabilite_optim", "system feasible\n");
513  debug(6, "sc_faisabilite_optim", "end\n");
515  return (true);
516  }
517  }
518  } else {
519  debug(7, "sc_faisabilite_optim", "normalized system not feasible\n");
520  debug(6, "sc_faisabilite_optim", "end\n");
521  sc_rm(sc);
522  return (false);
523  }
524 }
525 
526 /* bool combiner_ofl_with_test(Psysteme sc, Variable v):
527  *
528  * the copy of combiner() adding the test of suffisants conditions of integer
529  * combination.
530  *
531  * It returns true if exact
532  */
534 {
535  Psysteme sc1;
536  Pcontrainte pos, neg, nul;
537  Pcontrainte pc, pcp, pcn;
538  Value c;
539  int nnul, np, nn, i;
540 
541  pc = sc->inegalites;
542 
543  if(pc == NULL) {
544  FMComp[0]++;
545  return (true);
546  }
547 
548  sc1 = sc_dup(sc);
549  pos = neg = nul = NULL;
550  nnul = 0;
551  while(pc != NULL) {
552  Pcontrainte pcs = pc->succ;
553 
554  if(value_pos_p(c = vect_coeff(v,pc->vecteur))) {
555  pc->succ = pos;
556  pos = pc;
557  }
558  else if(value_neg_p(c)) {
559  pc->succ = neg;
560  neg = pc;
561  }
562  else {
563  pc->succ = nul;
564  nul = pc;
565  nnul += 1;
566  }
567 
568  pc = pcs;
569  }
570  sc->inegalites = NULL;
571  sc->nb_ineq = 0;
572 
573  np = nb_elems_list(pos);
574  nn = nb_elems_list(neg);
575 
576  if((i = np * nn) <= 16)
577  FMComp[i]++;
578  else
579  FMComp[17]++;
580 
581  for (pcp = pos; pcp != NULL; pcp = pcp->succ) {
582  for (pcn = neg; pcn != NULL; pcn = pcn->succ) {
583  bool int_comb_p = true;
584  Pcontrainte pcnew =
585  sc_integer_inequalities_combination_ofl_ctrl(sc1,
586  pcp,
587  pcn,
588  v,
589  &int_comb_p,
590  FWD_OFL_CTRL);
591 
592  if(contrainte_constante_p(pcnew)) {
593  if(contrainte_verifiee(pcnew, false)) {
594  contrainte_free(pcnew);
595  } else {
596  contraintes_free(pos);
597  contraintes_free(neg);
598  contraintes_free(nul);
599  contraintes_free(pcnew);
600  sc_rm(sc1);
601  return (false);
602  }
603  } else {
604  pcnew->succ = nul;
605  nul = pcnew;
606  nnul += 1;
607  if(!int_comb_p) {
608  if(is_test_exact)
609  is_test_exact = false;
610  if(is_test_inexact_fm == false)
611  is_test_inexact_fm = true;
612  }
613  }
614  }
615  }
616 
617  /* apres les combinaisons eliminer les elements devenus inutiles */
618  contraintes_free(pos);
619  contraintes_free(neg);
620 
621  /* mise a jour du systeme */
622  sc->inegalites = nul;
623  sc->nb_ineq = nnul;
624  sc_rm(sc1);
625  return (true);
626 }
627 
628 /* Psysteme sc_projection_optim_along_vecteur_ofl(Psysteme sc, Pvecteur pv)
629  *
630  * This fonction returns the projected system resulting of the
631  * SUCCESSIVE projections of the system sc along the variables
632  * contained in vecteur pv. Variables are only more or less projected
633  * according to their order in pv.
634  *
635  * The projection is done first by eliminating variables constrained
636  * by equations. The variables whose coefficients are 1 (or -1?) are
637  * considered first (in such case it is a valide integer elimination),
638  * then variables appearing in equations with non unit coefficient,
639  * and finally all left over variables in pv using Fourier-Motzkin
640  * elimination. At each step, the order in pv is used.
641  *
642  * If the system sc is not faisable, SC_EMPTY is returned.
643  *
644  * FI: this function could be moved to linear... but for the debugging
645  * stuff. Also, it could be broken into three parts. And the number of
646  * return statements should be reduced to one.
647  */
649 {
650  Pcontrainte eq;
651  Pvecteur pv1, prv, pve;
652  Variable v;
653  Value coeff;
654  int syst_size_init;
655  Pbase base_sc = base_dup(sc->base);
656  Pbase lb = BASE_NULLE;
657 
658  pips_assert("The input constraint system is consistent", sc_consistent_p(sc));
659  ifdebug(7) {
660  pips_debug(7, "All variables to project: ");
661  vect_dump(pv);
662  }
663 
664  pve = vect_dup(pv);
665  Pvecteur pve_to_free = pve;
666 
667  do {
668  /* The elimination of variables using equations */
669  if(pve != NULL && sc->nb_eq != 0) {
670 
671  /* First,carry out the integer elimination possible */
672  pips_debug(7, "carry out the integer elimination by equation:\n");
673 
674  prv = NULL;
675  pv1 = pve;
676  while(!VECTEUR_NUL_P(pv1) && (sc->nb_eq != 0)) {
677  v = pv1->var;
678  eq = contrainte_var_min_coeff(sc->egalites, v, &coeff, false);
679  if((eq == NULL) || value_notone_p(coeff)) {
680  prv = pv1;
681  pv1 = pv1->succ;
682  } else {
683  ifdebug(7) {
684  fprintf(stderr, "eliminate %s by :", entity_local_name((entity)v));
685  egalite_debug(eq);
686  }
687  /* coeff == 1, do this integer elimination for variable
688  * v with the others contrainte(equations and inequations */
689  sc = sc_variable_substitution_with_eq_ofl_ctrl(sc, eq, v, FWD_OFL_CTRL);
690 
691  if(sc_empty_p(sc)) {
692  if(is_test_Di)
693  NbrTestProjEqDi++;
694  else
695  NbrTestProjEq++;
696  pips_debug(7, "projection infaisable\n");
697  for (pv1 = pv; pv1 != NULL; pv1 = pv1->succ) {
698  v = pv1->var;
700  }
701  base_rm(base_sc);
702  vect_rm(pve_to_free);
703 
704  pips_debug(7, "Return 1: empty\n");
705  return (sc);
706  }
707  sc = sc_normalize(sc);
708 
709  if(sc_empty_p(sc)) { // FI: another normalization step is going to occur here
710  if(is_test_Di)
711  NbrTestProjEqDi++;
712  else
713  NbrTestProjEq++;
714  pips_debug(7, "normalisation infaisable\n");
715 
716  for (pv1 = pv; pv1 != NULL; pv1 = pv1->succ) {
717  v = pv1->var;
719  }
720 
721  vect_rm(pve_to_free);
722 
723  pips_debug(7, "Return 2: empty\n");
724  return (sc);
725 
726  }
727 
728  // The removal is delayed till the end of the function. sc is
729  // still consistent. However, too many variables might be left if an
730  // intermediate return occurs
731  // sc_base_remove_variable(sc, v);
732 
733  ifdebug(7) {
734  fprintf(stderr, "projected normalised system is:\n");
735  sc_syst_debug(sc);
736  }
737 
738  /* remove v from the list of variables to be projected pve */
739  if(prv == NULL) /* it's in head */
740  pve = pv1 = pv1->succ;
741  else {
742  prv->succ = pv1->succ;
743  free(pv1);
744  pv1 = prv->succ;
745  }
746  }
747  }
748  }
749 
750  pips_assert("sc is consistent after the first use of equations",
751  sc_consistent_p(sc));
752  ifdebug(7) {
753  pips_debug(7, "Variables left to project after the first step: ");
754  vect_dump(pv);
755  }
756 
757  /* carry out the non-exact elimination if necessary and possible
758  using other equations */
759  if(pve != NULL && sc->egalites != NULL) {
760  pips_debug(7, "carry out the non integer elimination by equation:\n");
761  pv1 = pve;
762  prv = NULL;
763  while((sc->egalites != 0) && (pv1 != NULL)) {
764  v = pv1->var;
765  eq = contrainte_var_min_coeff(sc->egalites, v, &coeff, true);
766  if(eq == NULL && pv1 != NULL) {
767  prv = pv1;
768  pv1 = pv1->succ;
769  } else {
770  if(eq != NULL) {
771  /* find a variable which appears in the equations, eliminate it*/
772  ifdebug(7) {
773  fprintf(stderr, "eliminate %s by :", entity_local_name((entity)v));
774  egalite_debug(eq);
775  }
776  if(is_test_inexact_eq == false)
777  is_test_inexact_eq = true;
778  if(is_test_exact)
779  is_test_exact = false;
780 
781  sc = sc_variable_substitution_with_eq_ofl_ctrl(sc,
782  eq,
783  v,
784  FWD_OFL_CTRL);
785  if(sc_empty_p(sc)) {
786  if(is_test_Di)
787  NbrTestProjEqDi++;
788  else
789  NbrTestProjEq++;
790  pips_debug(7, "projection-infaisable\n");
791 
792  for (pv1 = pv; pv1 != NULL; pv1 = pv1->succ) {
793  v = pv1->var;
795  }
796  base_rm(base_sc);
797  vect_rm(pve_to_free);
798 
799  pips_debug(7, "Return 3: empty\n");
800  return sc;
801  }
802 
803  sc = sc_normalize(sc);
804 
805  if(sc_empty_p(sc)) { // FI: should be sc_is_empty_p... or
806  // the normalization is repeated...
807  pips_debug(7, "normalization detects a non-feasible constraint system\n");
808  if(is_test_Di)
809  NbrTestProjEqDi++;
810  else
811  NbrTestProjEq++;
812 
813  for (pv1 = pv; pv1 != NULL; pv1 = pv1->succ) {
814  v = pv1->var;
816  }
817 
818  vect_rm(pve_to_free);
819 
820  pips_debug(7, "Return 4: empty\n");
821  return sc;
822  }
823 
824  // FI: the removal is delayed to end of this function, but
825  // sc is nevertheless consistent
826  // sc_base_remove_variable(sc, v);
827  ifdebug(7) {
828  fprintf(stderr, "projected normalised system is:\n");
829  sc_syst_debug(sc);
830  }
831  /*eliminate v in the list of variables pve*/
832  if(prv == NULL) /* it's in head */
833  pve = pv1 = pv1->succ;
834  else
835  prv->succ = pv1 = pv1->succ;
836  }
837  }
838  }
839  }
840 
841  pips_assert("sc is consistent after the second use of equations",
842  sc_consistent_p(sc));
843  ifdebug(7) {
844  pips_debug(7, "Variables left to project with Fourier-Motzkin: ");
845  vect_dump(pve);
846  }
847 
848  /* carry out the elimination using Fourier-Motzkin for the other variables */
849 
850  if(pve != NULL) {
851  pv1 = pve;
852 
853  while(pv1 != NULL) {
854 
855  NbrProjFMTotal++;
856  syst_size_init = nb_elems_list(sc->inegalites);
857  v = pv1->var;
858 
859  ifdebug(7) {
860  fprintf(stderr, "eliminate %s by F-M\n", entity_local_name((entity)v));
861  pips_debug(7, "is_test_exact before: ");
862  if(is_test_exact)
863  fprintf(stderr, "%s\n", "exact");
864  else
865  fprintf(stderr, "%s\n", "not exact");
866  }
867 
868  if(combiner_ofl_with_test(sc, v) == false) {
869  /* detection of non feasability of Psysteme sc */
870  if(is_test_Di)
871  NbrTestProjFMDi++;
872  else
873  NbrTestProjFM++;
874  sc_rm(sc);
875  sc = sc_empty(base_sc);
876  for (pv1 = pv; pv1 != NULL; pv1 = pv1->succ) {
877  v = pv1->var;
879  }
880 
881  vect_rm(pve_to_free);
882 
883  pips_debug(7, "Return 5: empty\n");
884  return sc;
885  }
886 
887  sc = sc_normalize(sc);
888 
889  if(sc_empty_p(sc)) {
890  if(is_test_Di)
891  NbrTestProjFMDi++;
892  else
893  NbrTestProjFM++;
894  pips_debug(7, "normalisation-infaisable\n");
895  for (pv1 = pv; pv1 != NULL; pv1 = pv1->succ) {
896  v = pv1->var;
898  }
899 
900  vect_rm(pve_to_free);
901 
902  pips_debug(7, "Return 6: empty\n");
903  return sc;
904  }
905 
906  /* sc->inegalites = contrainte_sort(sc->inegalites, sc->base, BASE_NULLE, */
907  /* true, false); */
908 
909  /* ifdebug(8) { */
910  /* debug(8, "", "Sorted system :\n"); */
911  /* sc_syst_debug(sc); */
912  /* } */
913 
915 
916  ifdebug(7) {
917  pips_debug(7, "is_test_exact after: ");
918  if(is_test_exact)
919  fprintf(stderr, "%s\n", "exact");
920  else
921  fprintf(stderr, "%s\n", "not exact");
922  fprintf(stderr, "projected normalised system is:\n");
923  sc_syst_debug(sc);
924  }
925  if(nb_elems_list(sc->inegalites) <= syst_size_init)
926  NbrFMSystNonAug++;
927  pv1 = pv1->succ;
928  }
929  }
930 
931  pips_assert("sc is consistent before base update", sc);
932 
933  /* Are we done? This used to be always true, but sc_normalize()
934  may promote inequalities as equations. Since the projection
935  steps may reveal some implicit equations, we are not sure here
936  that all projections have been performed by the three steps
937  (equations, equations, inequalities).
938 
939  See for instance the test dependence in SAC/sgemm for such an example.
940  */
941  Pbase mb = sc_to_minimal_basis(sc);
942  lb = base_intersection(mb, pv);
943  vect_rm(mb);
944 
945  } while(!BASE_NULLE_P(lb)); // No need to free lb since it is empty
946 
947  /* Update the base and the dimension of the constraint system sc */
948 
949  sc->nb_ineq = nb_elems_list(sc->inegalites);
950  for (pv1 = pv; pv1 != NULL; pv1 = pv1->succ) {
951  v = pv1->var;
953  }
954 
955  pips_assert("sc is consistent after base update", sc);
956 
957  /* Clean up auxiliary data structures */
958  vect_rm(pve_to_free);
959  base_rm(base_sc);
960 
961  pips_debug(7, "final return: faisable\n");
962 
963  return sc;
964 }
965 
966 /* void sc_minmax_of_variable_optim(Psysteme ps, Variable var, Value *pmin, *pmax):
967  * examine un systeme pour trouver le minimum et le maximum d'une variable
968  * apparaissant dans ce systeme par projection a la Fourier-Motzkin.
969  * la procedure retourne la valeur false si le systeme est infaisable et
970  * true sinon
971  *
972  * le systeme ps est detruit.
973  *
974  */
975 bool sc_minmax_of_variable_optim(ps, var, pmin, pmax)
976  Psysteme volatile ps;Variable var;Value *pmin, *pmax; {
977  Value val;
978  Pcontrainte pc;
979  Pbase b;
980  Pvecteur pv = NULL;
981 
982  *pmax = VALUE_MAX;
983  *pmin = VALUE_MIN;
984 
985  if(sc_value_of_variable(ps, var, &val) == true) {
986  *pmin = val;
987  *pmax = val;
988  return true;
989  }
990 
991  /* projection sur toutes les variables sauf var */
992  for (b = ps->base; !VECTEUR_NUL_P(b); b = b->succ) {
993  Variable v = vecteur_var(b);
994  if(v != var) {
995  vect_add_elem(&pv, v, 1);
996  }
997  }
998 
1000  debug(6,
1001  "sc_minmax_of_variable_optim",
1002  " overflow error, returning INT_MAX and INT_MIN. \n");
1003  *pmax = INT_MAX;
1004  *pmin = INT_MIN;
1005  } TRY {
1006 
1008  if(sc_empty_p(ps)) {
1009  sc_rm(ps);
1011  return false;
1012  }
1013  if(sc_empty_p(ps = sc_normalize(ps))) {
1014  sc_rm(ps);
1016  return false;
1017  }
1018 
1019  if(sc_value_of_variable(ps, var, &val) == true) {
1020  *pmin = val;
1021  *pmax = val;
1023  return true;
1024  }
1025 
1026  for (pc = ps->inegalites; pc != NULL; pc = pc->succ) {
1027  Value cv = vect_coeff(var, pc->vecteur);
1029 
1030  if(value_pos_p(cv)) {
1031  /* cette contrainte nous donne une borne max */
1032  Value bs = value_pdiv(cc,cv);
1033  if(value_lt(bs,*pmax))
1034  *pmax = bs;
1035  } else if(value_neg_p(cv)) {
1036  /* cette contrainte nous donne une borne min */
1037  Value bi = value_pdiv(cc,cv);
1038  if(value_gt(bi,*pmin))
1039  *pmin = bi;
1040  }
1041  }
1042 
1044  vect_rm(pv);
1045  }
1046 
1047  if(value_lt(*pmax,*pmin))
1048  return false;
1049 
1050  sc_rm(ps);
1051 
1052  return true;
1053 }
1054 
1055 /* Psysteme sc_invers(Psysteme ps):
1056  * calcul un systeme des contraintes qui est l'invers du systeme initial.
1057  * pour chaque element b dans le base initial, remplace b par -b dans
1058  * le systeme initial.
1059  */
1061  Psysteme ps; {
1062  Pbase b;
1063  Pcontrainte eq;
1064  Variable v;
1065 
1066  for (b = ps->base; !VECTEUR_NUL_P(b); b = b->succ) {
1067  v = vecteur_var(b);
1068  for (eq = ps->egalites; eq != NULL; eq = eq->succ)
1070 
1071  for (eq = ps->inegalites; eq != NULL; eq = eq->succ)
1073  }
1074  return (ps);
1075 }
1076 
1077 /* void vect_chg_var_sign(Pvecteur *ppv, Variable var)
1078  * changement de signe de la coordonnee var du vecteur *ppv
1079  */
1080 void vect_chg_var_sign(ppv, var)
1081  Pvecteur *ppv;Variable var; {
1082  Pvecteur pvcour;
1083 
1084  for (pvcour = (*ppv); pvcour != NULL; pvcour = pvcour->succ)
1085  if(pvcour->var == var)
1086  value_oppose(pvcour->val);
1087 
1088  return;
1089 }
1090 
1091 /* Ppoly sc_poly_enveloppe(s1, s2): calcul d'une representation par polyedre
1092  * de l'enveloppe convexe des polyedres definis par les systemes
1093  * lineaires s1 et s2
1094  *
1095  * p = enveloppe(s1, s2);
1096  * return p;
1097  *
1098  * s1 et s2 ne sont pas modifies. Ils doivent tous les deux avoir au moins
1099  * une base.
1100  *
1101  * Il faudrait traiter proprement les cas particuliers SC_RN et SC_EMPTY
1102  */
1103 /*
1104 Ppoly
1105 sc_poly_enveloppe(s1, s2)
1106 Psysteme s1;
1107 Psysteme s2;
1108 {
1109  Pbase b;
1110  Pvecteur coord;
1111  Ppoly p1;
1112  Ppoly p2;
1113  Ppoly p;
1114  Psysteme s = SC_UNDEFINED;
1115 
1116  assert(!SC_UNDEFINED_P(s1) || !SC_UNDEFINED_P(s2));
1117 
1118  if(SC_EMPTY_P(s1)) {
1119  s = s2;
1120  }
1121  else if(SC_EMPTY_P(s2)) {
1122  s = s1;
1123  }
1124 
1125  if (s != SC_UNDEFINED) {
1126  p = sc_to_poly(s);
1127  return (p);
1128  }
1129  else {
1130  s1 = sc_dup(s1);
1131  s2 = sc_dup(s2);
1132 
1133  b = s1->base;
1134  for(coord=s2->base; !VECTEUR_NUL_P(coord); coord = coord->succ) {
1135  b = vect_add_variable(b, vecteur_var(coord));
1136  }
1137  vect_rm(s2->base);
1138  s2->base = vect_dup(b);
1139 
1140  p1 = sc_to_poly(s1);
1141  p2 = sc_to_poly(s2);
1142 
1143  p = env(p1, p2);
1144  return (p);
1145  }
1146 }
1147 */
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
#define value_pos_p(val)
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
#define value_gt(v1, v2)
#define value_oppose(ref)
#define value_pdiv(v1, v2)
#define value_uminus(val)
unary operators on values
#define value_notone_p(val)
#define VALUE_MIN
int Value
#define VALUE_MAX
#define value_product(v, w)
#define value_lt(v1, v2)
#define value_neg_p(val)
Pbase vect_add_variable(Pbase b, Variable v)
package vecteur - routines sur les bases
Definition: base.c:61
Pbase base_intersection(Pbase b1, Pbase b2)
Return variables/dimensions present in bases b1 and b2.
Definition: base.c:473
void prv(Pvecteur pv)
Definition: comp_util.c:246
void vect_debug(Pvecteur v)
constraint.c
Definition: constraint.c:43
void sc_syst_debug(Psysteme s)
constraint_to_text.c
void egalite_debug(Pcontrainte c)
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226
Pcontrainte contrainte_free(Pcontrainte c)
Pcontrainte contrainte_free(Pcontrainte c): liberation de l'espace memoire alloue a la contrainte c a...
Definition: alloc.c:184
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
int nb_elems_list(Pcontrainte)
int nb_elems_list(Pcontrainte list): nombre de contraintes se trouvant dans une liste de contraintes
Definition: listes.c:129
bool contrainte_constante_p(Pcontrainte)
bool contrainte_constante_p(Pcontrainte c): test de contrainte triviale sans variables (ie du type 0<...
Definition: predicats.c:192
bool contrainte_verifiee(Pcontrainte, bool)
bool contrainte_verifiee(Pcontrainte ineg, bool eq_p): test de faisabilite d'inegalite (eq_p == false...
Definition: predicats.c:234
#define action_write_p(x)
Definition: effects.h:314
#define action_read_p(x)
Definition: effects.h:311
void free(void *)
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#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
void vect_dump(Pvecteur v)
void vect_dump(Pvecteur v): print sparse vector v on stderr.
Definition: io.c:304
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define asprintf
Definition: misc-local.h:225
#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
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define MODULE_SEP_STRING
Definition: naming-local.h:30
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define LOOP_COUNTER_MODULE_NAME
moved from ricedg-local.h
#define make_entity(n, t, s, i)
#define DI_VAR_MODULE_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
#define value_undefined
Definition: ri.h:3016
#define LOOP(x)
LOOP.
Definition: ri.h:1606
#define entity_undefined
Definition: ri.h:2761
#define type_undefined
Definition: ri.h:2883
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define storage_undefined
Definition: ri.h:2476
#define MAXDEPTH
maximun number of nested loops
Definition: ricedg-local.h:28
int NbrTestProjFMDi
Definition: ricedg.h:148
#define MAXSV
maximum number of scalar variables
Definition: ricedg-local.h:30
int NbrFMSystNonAug
Definition: ricedg.h:153
int NbrProjFMTotal
Definition: ricedg.h:152
bool is_test_inexact_eq
Definition: ricedg.h:156
bool is_test_inexact_fm
Definition: ricedg.h:157
int FMComp[18]
Definition: ricedg.h:154
int NbrTestProjEq
Definition: ricedg.h:149
bool is_test_exact
or counting the number of F-M complexity less than 16.
Definition: ricedg.h:155
int NbrTestProjEqDi
Definition: ricedg.h:147
int NbrTestProjFM
Definition: ricedg.h:150
bool is_test_Di
Definition: ricedg.h:159
void sc_base_remove_variable(Psysteme sc, Variable v)
Definition: sc.c:239
bool sc_consistent_p(Psysteme sc)
bool sc_consistent_p(Psysteme sc): check that sc is well defined, that the numbers of equalities and ...
Definition: sc.c:282
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Pbase sc_to_minimal_basis(Psysteme ps)
creation d'une base contenant toutes les variables apparaissant avec des coefficients non-nuls dans l...
Definition: sc_alloc.c:76
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
void build_sc_nredund_2pass_ofl_ctrl(Psysteme volatile *psc, int ofl_ctrl)
bool sc_value_of_variable(Psysteme ps, Variable var, Value *pval)
bool sc_value_for_variable(Psysteme ps, Variable var, Value *pval): examine les egalites du systeme p...
Definition: sc_eval.c:70
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
#define ifdebug(n)
Definition: sg.c:47
Pvecteur vecteur
struct Scontrainte * 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
int nb_eq
Definition: sc-local.h:72
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
void ResetLoopCounter()
Definition: testdep_util.c:329
entity MakeDiVar(int l)
This function creates di variables.
Definition: testdep_util.c:63
bool sc_minmax_of_variable_optim(Psysteme volatile ps, Variable var, Value *pmin, Value *pmax)
void sc_minmax_of_variable_optim(Psysteme ps, Variable var, Value *pmin, *pmax): examine un systeme p...
Definition: testdep_util.c:975
void sc_add_dsi(int l, entity e, Psysteme s)
Definition: testdep_util.c:238
Psysteme sc_projection_optim_along_vecteur_ofl(Psysteme sc, Pvecteur pv)
Psysteme sc_projection_optim_along_vecteur_ofl(Psysteme sc, Pvecteur pv)
Definition: testdep_util.c:648
entity DiVars[MAXDEPTH]
here is a collection of function intended to create and manipulate "di" variables and test of depende...
Definition: testdep_util.c:53
entity MakeLiVar(int l)
This function creates li variables(thee ith loop index variable).
Definition: testdep_util.c:103
Pbase MakeDibaseinorder(int n)
Pbase MakeDibaseinorder(int n) make a base of D#1 ...
Definition: testdep_util.c:296
entity LiVars[MAXDEPTH]
Definition: testdep_util.c:54
int sc_proj_optim_on_di_ofl(int cl, Psysteme *psc)
int sc_proj_optim_on_di_ofl(cl, sc)
Definition: testdep_util.c:415
static bool combiner_ofl_with_test(Psysteme sc, Variable v)
bool combiner_ofl_with_test(Psysteme sc, Variable v):
Definition: testdep_util.c:533
void sc_add_di(int l, entity e, Psysteme s, int li)
Definition: testdep_util.c:209
bool sc_faisabilite_optim(Psysteme sc)
bool sc_faisabilite_optim (Psysteme sc) :
Definition: testdep_util.c:484
static int ilc
Definition: testdep_util.c:327
int sc_proj_on_di(int cl, Psysteme s)
Definition: testdep_util.c:267
int dep_type(action ac1, action ac2)
int dep_type(action ac1,action ac2) This function test the type of the dependence.
Definition: testdep_util.c:378
Psysteme sc_invers(Psysteme ps)
Psysteme sc_invers(Psysteme ps): calcul un systeme des contraintes qui est l'invers du systeme initia...
entity DsiVars[MAXSV]
Definition: testdep_util.c:55
int FindMaximumCommonLevel(cons *n1, cons *n2)
Definition: testdep_util.c:307
entity GetLiVar(int l)
Definition: testdep_util.c:121
entity MakeDsiVar(int l)
This function creates dsi variables.
Definition: testdep_util.c:146
entity GetDiVar(int l)
This functions looks up a di variable of nesting level l in table DiVars.
Definition: testdep_util.c:79
int DiVarLevel(entity e)
this function returns the nesting level of a given di variable e.
Definition: testdep_util.c:185
entity GetDsiVar(int l)
Definition: testdep_util.c:164
entity MakeLoopCounter()
Create a new loop counter variable.
Definition: testdep_util.c:334
void vect_chg_var_sign(Pvecteur *ppv, Variable var)
void vect_chg_var_sign(Pvecteur *ppv, Variable var) changement de signe de la coordonnee var du vecte...
#define ILCMAX
Management of loop counters.
Definition: testdep_util.c:325
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define VECTEUR_NUL_P(v)
#define base_rm(b)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define FWD_OFL_CTRL
#define BASE_NULLE
MACROS SUR LES BASES.
#define BASE_NULLE_P(b)
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
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
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