PIPS
old_projection.c
Go to the documentation of this file.
1 /*
2 
3  $Id: old_projection.c 23412 2017-08-09 15:07:09Z irigoin $
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  * package regions : Be'atrice Creusillet, September 1994
29  *
30  * ------------
31  * projection.c
32  * ------------
33  *
34  * This file contains the functions specific to the projection of regions along
35  * individual variables, list of variables or vectors of variables. The
36  * algorithms are described in the report EMP-CRI E/185.
37  *
38  */
39 
40 
41 #include <stdio.h>
42 #include <string.h>
43 #include <setjmp.h>
44 #include "genC.h"
45 #include "linear.h"
46 #include "ri.h"
47 #include "effects.h"
48 #include "database.h"
49 #include "ri-util.h"
50 #include "prettyprint.h" // for debugging
51 #include "effects-util.h"
52 #include "constants.h"
53 #include "misc.h"
54 #include "text-util.h"
55 #include "text.h"
56 #include "sommet.h"
57 #include "ray_dte.h"
58 #include "sg.h"
59 #include "sc.h"
60 #include "polyedre.h"
61 #include "matrix.h"
62 #include "matrice.h"
63 #include "transformer.h"
64 #include "sparse_sc.h"
65 #include "pipsdbm.h"
66 
67 #include "effects-generic.h"
68 #include "effects-convex.h"
69 
70 
71 /*********************************************************************************/
72 /* STATISTICS FOR PROJECTION OPERATORS */
73 /*********************************************************************************/
74 
75 static int nb_proj_param = 0;
76 static int nb_proj_param_pot_must = 0;
77 static int nb_proj_param_must = 0;
78 static int nb_proj_param_ofl = 0;
79 static int nb_proj_param_hermite = 0;
81 
82 static int nb_proj_var = 0;
83 static int nb_proj_var_pot_must = 0;
84 static int nb_proj_var_must = 0;
85 static int nb_proj_var_ofl = 0;
86 
87 
89 {
90  nb_proj_param = 0;
96 
97  nb_proj_var = 0;
99  nb_proj_var_must = 0;
100  nb_proj_var_ofl = 0;
101 }
102 
103 
104 void print_proj_op_statistics(char *mod_name, char *prefix)
105 {
106  FILE *fp;
107  string filename;
108 
109  filename = "proj_param_op_stat";
111  mod_name, ".", prefix, filename, NULL));
112  fp = safe_fopen(filename, "w");
113  fprintf(fp,"%s",mod_name);
114  fprintf(fp," %d %d %d %d %d %d\n", nb_proj_param, nb_proj_param_pot_must,
117  safe_fclose(fp, filename);
118  free(filename);
119 
120  filename = "proj_var_op_stat";
122  mod_name, ".", prefix, filename, NULL));
123  fp = safe_fopen(filename, "w");
124  fprintf(fp,"%s",mod_name);
125  fprintf(fp," %d %d %d %d \n", nb_proj_var, nb_proj_var_pot_must,
127  safe_fclose(fp, filename);
128  free(filename);
129 }
130 
131 
132 /*********************************************************************************/
133 /* FONCTIONS D'INTERFACE */
134 /*********************************************************************************/
135 
136 
137 /* entity
138  * loop_regions_normalize(list l_reg, entity index, range l_range,
139  * bool *normalized_regions_p, bool sc_loop_p,
140  * Psysteme *psc_loop)
141  * input : a list of regions, a loop index, its range, and a pointer on a
142  * bool to know if the loop is normalized, a bool to know
143  * if the loop precondition system sc_loop must be normalized.
144  *
145  * output : an entity representing the new loop index to use; it may be index
146  * if the loop is already normalized.
147  * modifies : l_reg, and *normalized_regions_p.
148  * comment : Loops are not normalized in PIPS, but array region semantic
149  * functions are defined for normalized loops (incr = +/-1).
150  * So we perform here a virtual loop normalization. If the loop is not
151  * already normalized, a new loop index (beta) is introduced,
152  * and the following system is added to each region of l_reg:
153  * { index = lower_bound + beta * incr, 0 <= beta }
154  * Then the old index is eliminated as a parameter, and the beta
155  * variable is returned as the new loop index.
156  * If the loop was already normalized, or has been virtually normalized,
157  * then *normalized_regions_p is set to TRUE.
158  */
159 entity
160 loop_regions_normalize(list l_reg, entity index, range l_range,
161  bool *normalized_regions_p, bool sc_loop_p,
162  Psysteme *psc_loop )
163 {
164  Value incr = VALUE_ZERO;
165  normalized nub, nlb;
166  list l_tmp;
167  entity new_index = index;
168 
170 
171  if (must_regions_p())
172  {
173  expression e_incr = range_increment(l_range);
174  normalized n;
175 
176  /* Is the loop increment numerically known ? */
177  n = NORMALIZE_EXPRESSION(e_incr);
178  if(normalized_linear_p(n))
179  {
180  Pvecteur v_incr = normalized_linear(n);
181  if(vect_constant_p(v_incr))
182  incr = vect_coeff(TCST, v_incr);
183  }
184 
185  nub = NORMALIZE_EXPRESSION(range_upper(l_range));
186  nlb = NORMALIZE_EXPRESSION(range_lower(l_range));
187 
188  *normalized_regions_p =
189  (value_notzero_p(incr) && normalized_linear_p(nub)
190  && normalized_linear_p(nlb));
191  pips_debug(6, "normalized loop? %s.\n",
192  *normalized_regions_p? "yes" : "no");
193 
194  if (*normalized_regions_p)
195  {
196  if (value_notone_p(value_abs(incr)))
197  {
198  /* add to each region predicate the system:
199  * { index = lower_bound + beta * incr, 0 <= beta }
200  */
201  entity beta = make_beta_entity(1);
202  Psysteme beta_sc = sc_new();
203  Pvecteur v_lb = normalized_linear(nlb);
204  Pvecteur beta_v;
205 
206  new_index = beta;
207  beta_v = vect_new((Variable) index , VALUE_ONE);
208  vect_add_elem(&beta_v, (Variable) beta, value_uminus(incr));
209  beta_v = vect_cl_ofl_ctrl(beta_v,
210  VALUE_MONE, v_lb, NO_OFL_CTRL);
211  sc_add_egalite(beta_sc,contrainte_make(beta_v));
212 
213  beta_v = vect_new((Variable) beta, VALUE_MONE);
214  sc_add_inegalite(beta_sc,contrainte_make(beta_v));
215  sc_creer_base(beta_sc);
216 
217  ifdebug(6)
218  {
219  pips_debug(6, "index system:\n"); sc_syst_debug(beta_sc);
220  }
221 
222  /* eliminate the old index (which is no more a variable,
223  * but a parameter) */
224  l_tmp = CONS(ENTITY, index, NIL);
225  FOREACH(EFFECT, reg, l_reg)
226  {
227  if(store_effect_p(reg)) {
228  if (!region_rn_p(reg) && !region_empty_p(reg))
229  {
230  region_sc_append_and_normalize(reg,beta_sc,1);
232  }
233  }
234  }
235  gen_free_list(l_tmp);
236 
237  /* update the loop preconditions */
238  if (sc_loop_p)
239  {
240  Psysteme sc_tmp;
241  sc_tmp = sc_safe_append(*psc_loop, beta_sc);
242  sc_projection_along_variable_ofl_ctrl(&sc_tmp,(Variable) index,
243  FWD_OFL_CTRL);
244  sc_base_remove_variable(sc_tmp, (Variable) index);
245  *psc_loop = sc_tmp;
246  }
247  sc_rm(beta_sc);
248  }
249  }
250  }
251 
253 
254  return new_index;
255 }
256 
257 /* void project_regions_along_loop_index(list l_reg, entity index, l_range)
258  * input : a list l_reg of regions, a variable which is a loop index.
259  * output : nothing.
260  * modifies : l_reg and the regions it contains.
261  * comment : project each region in l_reg along the variable index.
262  */
264 {
265  bool projection_of_index_safe = false;
266  Psysteme sc_tmp = SC_UNDEFINED;
267 
268  debug_on("REGIONS_OPERATORS_DEBUG_LEVEL");
270 
271 
272  /* Take care of loops with non-unit increment when must regions
273  are required */
274  index = loop_regions_normalize(l_reg, index, l_range,
275  &projection_of_index_safe,false,&sc_tmp);
276 
277  if (must_regions_p() && projection_of_index_safe)
278  {
279 
280  FOREACH(EFFECT, reg, l_reg) {
281  if(store_effect_p(reg))
283  }
284  }
285  else
286  {
287  list l = CONS(ENTITY, index, NIL);
288  FOREACH(EFFECT, reg, l_reg) {
289  if(store_effect_p(reg))
291  }
292  gen_free_list(l);
293  }
295  debug_off();
296 
297 }
298 
299 
300 /* void project_regions_along_variables(list l_reg, list l_param)
301  * input : a list of regions to project, and the list of variables
302  * along which the projection will be performed.
303  * output : nothing.
304  * modifies : l_reg and the regions it contains.
305  * comment : project each region in l_reg along the variables in l_var
306  */
308 {
309 
310  debug_on("REGIONS_OPERATORS_DEBUG_LEVEL");
312 
313  if (must_regions_p())
314  {
315  MAP(EFFECT, reg, {
317  }, l_reg);
318  }
319  else
320  {
321  MAP(EFFECT, reg, {
323  },l_reg);
324  }
326  debug_off();
327 }
328 
329 
330 /* void project_regions_along_parameters(list l_reg, list l_param)
331  * input : a list of regions to project, and the list of variables
332  * along which the projection will be performed.
333  * output : nothing.
334  * modifies : l_reg and the regions it contains.
335  * comment : project each region in l_reg along the variables in l_param
336  */
338 {
339 
340  debug_on("REGIONS_OPERATORS_DEBUG_LEVEL");
342 
343  if (must_regions_p())
344  {
345  FOREACH(EFFECT, reg, l_reg) {
346  if(store_effect_p(reg))
348  }
349  }
350  else
351  {
352  FOREACH(EFFECT, reg, l_reg) {
353  if(store_effect_p(reg))
355  }
356  }
358  debug_off();
359 }
360 
361 
362 
363 void
365  list l_var_not_proj)
366 {
367  regions_transformer_apply(l_reg, trans, l_var_not_proj, false);
368 }
369 
371  list l_var_not_proj)
372 {
373  regions_transformer_apply(l_reg, trans, l_var_not_proj, true);
374 }
375 
376 /* void regions_transformer_apply(l_reg, trans, l_var_not_proj)
377  * input : a list of regions, the transformer corresponding
378  * to the current statement, and a list of variables along which
379  * the regions must not be projected (typically a loop index).
380  * output : nothing.
381  * modifies : l_reg and the regions it contains
382  * comment : project each region in l_reg along the variables in the arguments
383  * of trans which are not in l_var_not_proj, using the algorithm
384  * described in document E/185/CRI.
385  */
387  list l_var_not_proj, bool backward_p)
388 {
389  list l_var = arguments_difference(transformer_arguments(trans), l_var_not_proj);
390 
391  if (ENDP(l_var) || ENDP(l_reg))
392  return;
393 
394  debug_on("REGIONS_OPERATORS_DEBUG_LEVEL");
396 
397  ifdebug(3)
398  {
399  pips_debug_effects(3, "regions before transformation:\n", l_reg);
400  pips_debug(3, "elimination of variables: \n");
401  print_entities(l_var);
402  }
403 
404  if (!must_regions_p())
405  {
406  project_regions_along_parameters(l_reg, l_var);
407  }
408  else
409  {
410  list l_int, l_old;
412 
413  ifdebug(8)
414  {
415  fprintf(stderr,"transformer:\n");
417  }
418 
419  /* addition of the predicate of the transformer to the predicate of
420  * the regions and elimination of redundances; then, projection of
421  * regions along initial variables, and renaming of old variables
422  * corresponding to the eliminated variables into new variables. */
423 
424  /* first we store the names of the old and int variables */
425  l_old = variables_to_old_variables(l_var);
426  l_int = variables_to_int_variables(l_var);
427 
428  if(backward_p)
429  {
430  sc_list_variables_rename(sc_trans, l_var, l_int);
431  sc_list_variables_rename(sc_trans, l_old, l_var);
432  }
433  else
434  {
435  sc_list_variables_rename(sc_trans, l_old, l_int);
436  }
437 
438  FOREACH(EFFECT, reg, l_reg)
439  {
440  if(store_effect_p(reg))
441  {
442  Psysteme sc_reg = region_system(reg);
443 
444  if (!SC_UNDEFINED_P(sc_reg) && !sc_empty_p(sc_reg) && !sc_rn_p(sc_reg))
445  {
447 
448  pips_debug_effect(8, "region before transformation: \n", reg);
449 
450  sc_list_variables_rename(sc_reg, l_var, l_int);
451  pips_debug_effect(8, "region after renaming: \n", reg);
452 
453  /* addition of the predicate of the transformer,
454  and elimination of redundances */
455  region_sc_append_and_normalize(reg, sc_trans, 1);
456 
458 
459  pips_debug_effect(8, "region after addition of the transformer: ", reg);
460 
461  /* projection along intermediate variables */
464  pips_debug_effect(8, "region after projection along parameters: \n", reg );
465 
466  /* remove potential old values that may be found in transformer */
467  list l_old_values = NIL;
468  sc_reg = region_system(reg);
469  for(Pbase b = sc_base(sc_reg); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
470  entity e = (entity) vecteur_var(b);
471  if(local_old_value_entity_p(e)) {
472  l_old_values = CONS(ENTITY, e, l_old_values);
473  }
474  }
475  region_exact_projection_along_parameters(reg, l_old_values);
476  gen_free_list(l_old_values);
478  pips_debug_effect(8, "region after transformation: \n", reg );
479  }
480  }
481  }
482 
483  /* no memory leaks */
484  gen_free_list(l_int);
485  gen_free_list(l_old);
486  sc_rm(sc_trans);
487  }
488 
489  pips_debug_effects(3, "regions after transformation:\n", l_reg);
490 
491  gen_free_list(l_var);
493  debug_off();
494 }
495 
496 
497 /* void regions_remove_phi_variables(list l_reg)
498  * input : a list of regions, and an integer, which is the highest rank
499  * of phi variables that will be kept.
500  * output : nothing.
501  * modifies : project regions in l_reg along the phi variables which rank
502  * are higher (>) than phi_max.
503  * comment : An assumption is made : the projection is exact and the
504  * approximation are thus preserved, except if an overflow error occurs.
505  * This function is only used in the case of a forward interprocedural
506  * propagation : the assumption is then always true.
507  */
509 {
510  debug_on("REGIONS_OPERATORS_DEBUG_LEVEL");
512 
513  FOREACH(EFFECT, reg, l_reg)
515 
517 
518  debug_off();
519 }
520 
521 
522 /* list regions_dynamic_elim(list l_reg)
523  * input : a list of regions.
524  * output : a list of regions in which regions of dynamic variables are
525  * removed, and in which dynamic integer scalar variables are
526  * eliminated from the predicate.
527  * modifies : nothing; the regions l_reg initially contains are copied
528  * if necessary.
529  * comment :
530  */
532 {
533  list l_res = NIL;
534 
535  debug_on("REGIONS_OPERATORS_DEBUG_LEVEL");
537 
538  FOREACH(EFFECT, reg, l_reg)
539  {
540  if(store_effect_p(reg)) {
541  entity reg_ent = region_entity(reg);
542  storage reg_s = entity_storage(reg_ent);
543  bool ignore_this_region = false;
544 
545  ifdebug(4)
546  {
547  pips_debug_effect(4, "current region: \n", reg);
548  }
549 
550  /* If the reference is a common variable (ie. with storage ram but
551  * not dynamic) or a formal parameter, the region is not ignored.
552  */
553  if(!anywhere_effect_p(reg)) {
554  switch (storage_tag(reg_s))
555  {
556  case is_storage_return:
557  pips_debug(5, "return var ignored (%s)\n", entity_name(reg_ent));
558  ignore_this_region = true;
559  break;
560  case is_storage_ram:
561  {
562  ram r = storage_ram(reg_s);
563  // FI: why ignore regions that are likely to be accessible
564  // via pointers?
565  if (dynamic_area_p(ram_section(r)) /*|| heap_area_p(ram_section(r))*/
566  || stack_area_p(ram_section(r)))
567  {
568  pips_debug(5, "dynamic or pointed var ignored (%s)\n", entity_name(reg_ent));
569  ignore_this_region = true;
570  }
571  break;
572  }
573  case is_storage_formal:
574  break;
575  case is_storage_rom:
576  if(!entity_special_area_p(reg_ent) && !anywhere_effect_p(reg))
577  ignore_this_region = true;
578  break;
579  /* pips_internal_error("bad tag for %s (rom)", entity_name(reg_ent)); */
580  default:
581  pips_internal_error("case default reached");
582  }
583  }
584 
585  if (! ignore_this_region) /* Eliminate dynamic variables. */
586  {
587  region r_res = region_dup(reg);
589  ifdebug(4)
590  {
591  pips_debug_effect(4, "region kept : \n", r_res);
592  }
593  l_res = region_add_to_regions(r_res,l_res);
594  }
595  else
596  ifdebug(4)
597  {
598  pips_debug_effect(4, "region removed : \n", reg);
599  }
600  }
601  }
603  debug_off();
604 
605  return(l_res);
606 }
607 
608 
609 /*********************************************************************************/
610 /* OPE'RATEURS CONCERNANT LES RE'GIONS INDIVIDUELLES. */
611 /*********************************************************************************/
612 
614  Pvecteur pv_param,
615  bool *p_exact);
617  bool *p_exact);
618 
619 
620 /* void region_remove_phi_variables(effect reg, int phi_max)
621  * input : a PSI region in which phi variables must be eliminated.
622  * output : nothing.
623  * modifies : reg
624  * comment : if an overflow error occurs, the region becomes a MAY region..
625  */
627 {
628  list
629  l_phi = NIL,
630  l_reg = CONS(EFFECT,reg,NIL);
631 
632  ifdebug(8)
633  {
634  pips_debug(8, "region : \n ");
635  print_region(reg);
636  }
637 
639  project_regions_along_variables(l_reg, l_phi);
640  gen_free_list(l_reg);
641  gen_free_list(l_phi);
642 
643  ifdebug(8)
644  {
645  pips_debug(8, "final region : \n ");
646  print_region(reg);
647  }
648 }
649 
650 
652 {
653  list volatile l_psi = psi_entities_list(1,NB_MAX_ARRAY_DIM);
654  *exact_p = true;
655 
656  for(; !ENDP(l_psi) && *exact_p; l_psi = CDR(l_psi))
657  {
658  entity e = ENTITY(CAR(l_psi));
659  bool exact_projection;
660  sc = cell_reference_sc_exact_projection_along_variable(ref, sc, e, &exact_projection);
661  *exact_p = *exact_p && exact_projection;
662  }
663  Psysteme volatile ps = sc;
664  if (!ENDP(l_psi) && !SC_UNDEFINED_P(ps))
665  {
667  {
668  sc_rm(ps);
669  ps = SC_UNDEFINED;
670  }
671  TRY
672  {
675  }
676  }
677  return ps;
678 }
679 
680 /* void region_remove_psi_variables(effect reg, int phi_max)
681  * input : a PHI region in which psi variables must be eliminated.
682  * output : nothing.
683  * modifies : reg
684  * comment : if an overflow error occurs, the region becomes a MAY region..
685  */
687 {
688  list
689  l_psi = NIL,
690  l_reg = CONS(EFFECT,reg,NIL);
691 
692  ifdebug(8)
693  {
694  pips_debug(8, "region : \n ");
695  print_region(reg);
696  }
697 
699  project_regions_along_variables(l_reg, l_psi);
700  gen_free_list(l_reg);
701 
702  ifdebug(8)
703  {
704  pips_debug(8, "final region : \n ");
705  print_region(reg);
706  }
707 }
708 
710 {
711  list volatile l_rho = rho_entities_list(1,NB_MAX_ARRAY_DIM);
712  *exact_p = true;
713 
714  for(; !ENDP(l_rho) && *exact_p; l_rho = CDR(l_rho))
715  {
716  entity e = ENTITY(CAR(l_rho));
717  bool exact_projection;
718  sc = cell_reference_sc_exact_projection_along_variable(ref, sc, e, &exact_projection);
719  *exact_p = *exact_p && exact_projection;
720  }
721  Psysteme volatile ps = sc;
722  if (!ENDP(l_rho) && !SC_UNDEFINED_P(ps))
723  {
725  {
726  sc_rm(ps);
727  ps = SC_UNDEFINED;
728  }
729  TRY
730  {
733  }
734  }
735  return ps;
736 }
737 
738 
739 /* void region_remove_rho_variables(effect reg, int phi_max)
740  * input : a PHI region in which rho variables must be eliminated.
741  * output : nothing.
742  * modifies : reg
743  * comment : if an overflow error occurs, the region becomes a MAY region..
744  */
746 {
747  list
748  l_rho = NIL,
749  l_reg = CONS(EFFECT,reg,NIL);
750 
751  ifdebug(8)
752  {
753  pips_debug(8, "region : \n ");
754  print_region(reg);
755  }
756 
758  project_regions_along_variables(l_reg, l_rho);
759  gen_free_list(l_reg);
760 
761  ifdebug(8)
762  {
763  pips_debug(8, "final region : \n ");
764  print_region(reg);
765  }
766 }
767 
768 
769 /* void region_remove_variables(effect reg, int beta_max)
770  * input : a PSI region in which beta variables must be eliminated.
771  * output : nothing.
772  * modifies : reg
773  * comment : if an overflow error occurs, the region becomes a MAY region..
774  */
776 {
777  list
778  l_beta = NIL,
779  l_reg = CONS(EFFECT,reg,NIL);
780 
781  ifdebug(8)
782  {
783  pips_debug(8, "region : \n ");
784  print_region(reg);
785  }
786 
787  l_beta = beta_entities_list(1,2);
788  project_regions_along_variables(l_reg, l_beta);
789  gen_free_list(l_reg);
790  gen_free_list(l_beta);
791 
792  ifdebug(8)
793  {
794  pips_debug(8, "final region : \n ");
795  print_region(reg);
796  }
797 }
798 
799 
800 /* void region_non_exact_projection_along_parameters(effect reg, list l_param)
801  * input : a region and a list of variables.
802  * output : nothing.
803  * modifies : the initial region is projected along the variables in l_param.
804  * its approximation is systematically set to may.
805  * comment : overflow errors are trapped here. if it occurs, an empty region
806  * replaces the initial region.
807  */
809 {
810  /* Automatic variables read in a CATCH block need to be declared volatile as
811  * specified by the documentation*/
812  Psysteme volatile ps;
813  ps = region_system(reg);
814 
815  if (!sc_empty_p(ps) && !sc_rn_p(ps))
816  {
818 
819  ifdebug(6)
820  {
821  pips_debug(6, "initial region :\n");
822  print_region(reg);
823  debug(6, "", "parameters along which the projection must be performed:\n");
824  print_entities(l_param);
825  }
826 
827  /* if there is an overflow error, reg becomes a whole array may region */
829  {
831  region_action(reg));
832  cell c_tmp = region_cell(reg_tmp);
833 
834  region_system_(reg) = region_system_(reg_tmp);
835  pips_assert("region cell must be a reference\n",
836  cell_reference_p(c_tmp));
837 
838  region_system_(reg_tmp) = newgen_Psysteme(SC_UNDEFINED);
839  free_effect(reg_tmp);
840  sc_rm(ps);
842  }
843  TRY
844  {
846  region_system_(reg) = newgen_Psysteme(ps);
849  }
850  }
851 }
852 
853 
854 /* void region_exact_projection_along_parameters(effect reg, list l_param)
855  * input : a regions reg and a list of parameters l_param.
856  * output : nothing.
857  * modifies : the initial region is successively projected along each variable
858  * in l_param. its approximaiton becomes may if the projection is not
859  * "exact" in the sense given in report E/185.
860  * comment : overflow errors are trapped here. if it occurs, an empty region
861  * replaces the initial region.
862  */
864 {
865  volatile tag app = region_approximation_tag(reg);
866  /* Automatic variables read in a CATCH block need to be declared volatile as
867  * specified by the documentation*/
868  Psysteme volatile ps;
869 
870 
871  ps = region_system(reg);
872 
873  if (!sc_empty_p(ps) && !sc_rn_p(ps))
874  {
875  ifdebug(6)
876  {
877  pips_debug(6, "initial region :\n");
878  print_region(reg);
879  debug(6, "", "parameters along which the projection must be performed:\n");
880  print_entities(l_param);
881  }
882 
884 
885  /* if there is an overflow error, reg becomes a whole array may region */
888  region_action(reg));
889  cell c_tmp = region_cell(reg_tmp);
890 
891  pips_assert("region cell must be a reference\n",
892  cell_reference_p(c_tmp));
893  region_system_(reg) = region_system_(reg_tmp);
894  region_system_(reg_tmp) = newgen_Psysteme(SC_UNDEFINED);
895  free_effect(reg_tmp);
896  sc_rm(ps);
898  }
899  TRY {
900  /* if the initial region is a may region, the resulting region is
901  * also a may region, even if the projection happens to be exact.
902  * so we do not need to know whether it is exact or not
903  */
904  if (app == is_approximation_may)
905  {
907  }
908 
909  /* if the initial region is a must region, much more work is
910  * necessary to preserve the must approximation
911  */
912  else
913  {
914  list l_phi_param =
916  list l_not_phi_param = arguments_difference(l_param, l_phi_param);
917 
918  /* first, the projection along parameters that are not linked to PHI
919  * variables (l_not_phi_param) is exact */
920  if (!ENDP(l_not_phi_param))
921  {
923  (ps, l_not_phi_param);
924  }
925 
926  /* then, we must perform the projection along parameters that
927  * are linked to PHI variables (l_phi_param). */
928  if(!ENDP(l_phi_param))
929  {
930  bool exact = true;
931  Pvecteur pv_phi_param = NULL;
932 
934 
935  /* projection functions only work on vector of parameters,
936  not on lists */
937  MAP(ENTITY, e,
938  {
939  if (base_contains_variable_p(ps->base, (Variable) e) )
940  vect_add_elem(&pv_phi_param, (Variable) e, VALUE_ONE);
941  }, l_phi_param);
942 
943  ps =
945  &exact);
946  vect_rm(pv_phi_param);
947  if(!exact)
948  app = is_approximation_may;
949  else
951  }
952  gen_free_list(l_phi_param);
953  gen_free_list(l_not_phi_param);
954  }
955  region_system_(reg) = newgen_Psysteme(ps);
956  region_approximation_tag(reg) = app;
958  }
959 
960  ifdebug(6)
961  {
962  pips_debug(6, "final region:\n");
963  print_region(reg);
964  }
965  }
966 }
967 
968 
969 /* void region_non_exact_projection_along_variables(effect reg, list l_var)
970  * input : a region and a list of variables.
971  * output : nothing.
972  * modifies : the initial region is projected along the variables in l_param.
973  * its approximation is systematically set to may.
974  * comment : overflow errors are trapped here. if it occurs, a whole array region
975  * replaces the initial region.
976  */
978 {
979  /* Automatic variables read in a CATCH block need to be declared volatile as
980  * specified by the documentation*/
981  Psysteme volatile ps;
982 
983  ps = region_system(reg);
984 
985  if (!sc_empty_p(ps) && !sc_rn_p(ps))
986  {
987  if (op_statistics_p()) nb_proj_var++;
988 
989  ifdebug(6)
990  {
991  pips_debug(6, "initial region :\n");
992  print_region(reg);
993  pips_debug(6, "variables along which the projection must be performed:\n");
994  print_entities(l_var);
995  }
996 
997  /* if there is an overflow error, reg becomes a whole array may region */
999  {
1001  region_action(reg));
1002  cell c_tmp = region_cell(reg_tmp);
1003  pips_assert("region cell must be a reference\n",
1004  cell_reference_p(c_tmp));
1005 
1006  region_system_(reg) = region_system_(reg_tmp);
1007 
1008  region_system_(reg_tmp) = newgen_Psysteme(SC_UNDEFINED);
1009  free_effect(reg_tmp);
1010  sc_rm(ps);
1012 
1013  }
1014  TRY
1015  {
1017  region_system_(reg) = newgen_Psysteme(ps);
1020  }
1021  }
1022 }
1023 
1024 /* void region_exact_projection_along_variables(effect reg, list l_var)
1025  * input : a region and a list of variables.
1026  * output : nothing.
1027  * modifies : the initial region is projected along the variables in l_param.
1028  * its approximation is set to may if the projection is not exact.
1029  * comment : overflow errors are trapped here. if it occurs, an empty region
1030  * replaces the initial region.
1031  */
1033 {
1034  /* Automatic variables read in a CATCH block need to be declared volatile as
1035  * specified by the documentation */
1036  Psysteme volatile ps;
1037  ps = region_system(reg);
1038 
1039  if (!sc_empty_p(ps) && !sc_rn_p(ps))
1040  {
1041  ifdebug(6)
1042  {
1043  pips_debug(6, "initial region :\n");
1044  print_region(reg);
1045  debug(6, "", "variables along which the projection must be performed:\n");
1046  print_entities(l_var);
1047  }
1048 
1049  // if there is an overflow error, reg becomes a whole array may region
1051  {
1053  region_action(reg));
1054  cell c_tmp = region_cell(reg_tmp);
1055  pips_assert("region call must be a reference\n",
1056  cell_reference_p(c_tmp));
1057 
1058  region_system_(reg) = region_system_(reg_tmp);
1059  region_system_(reg_tmp) = newgen_Psysteme(SC_UNDEFINED);
1060  free_effect(reg_tmp);
1061  sc_rm(ps);
1063  }
1064  TRY {
1065  volatile list ll_var = l_var;
1066 
1067  for(; !ENDP(ll_var) &&
1069  ll_var = CDR(ll_var))
1070  {
1072  ENTITY(CAR(ll_var)));
1073  }
1074 
1075  if (!ENDP(ll_var))
1076  {
1078  }
1080  }
1081  }
1082 }
1083 
1085 {
1086  Psysteme volatile ps = sc;
1087  *exact_p = true;
1088  if (!sc_empty_p(ps) && !sc_rn_p(ps))
1089  {
1090  if (base_contains_variable_p(ps->base, (Variable) var))
1091  {
1093  {
1094  sc_rm(ps);
1095  *exact_p = false;
1096  return SC_UNDEFINED;
1097  }
1098  TRY {
1099  list l_phi_var = cell_reference_phi_cfc_variables(ref, ps);
1100 
1101  if (gen_find_eq(var, l_phi_var) == chunk_undefined)
1102  {
1103  Psysteme volatile * psc = &ps;
1104  sc_projection_along_variable_ofl_ctrl(psc,(Variable) var,
1105  FWD_OFL_CTRL);
1106  sc_base_remove_variable(ps, (Variable) var);
1107  ps = region_sc_normalize(ps,2);
1108  *exact_p = true;
1109  }
1110  else
1111  {
1112  Pvecteur pv_var = NULL;
1113 
1114  vect_add_elem(&pv_var, (Variable) var, VALUE_ONE);
1115  ps = sc_projection_ofl_along_variables_with_test
1116  (ps, pv_var, exact_p);
1117  vect_rm(pv_var);
1118  ps = region_sc_normalize(ps,2);
1119  }
1120  gen_free_list(l_phi_var);
1122  }
1123  }
1124  }
1125  return ps;
1126 }
1127 
1128 /* void region_exact_projection_along_variable(effect reg, entity var)
1129  * input : a region and a variable (a loop index for instance).
1130  * output : nothing.
1131  * modifies : the initial region, which is projected along var.
1132  * the approximation is not modified.
1133  * comment : overflow errors are trapped here. if it occurs, an empty region
1134  * replaces the initial region.
1135  *
1136  * FI: it seems that a value rather than a variable is projected.
1137  */
1139 {
1140  if(store_effect_p(reg)) {
1141  /* Automatic variables read in a CATCH block need to be declared volatile as
1142  * specified by the documentation*/
1143  Psysteme volatile sc;
1144 
1145  sc = region_system(reg);
1146 
1147  if (!SC_UNDEFINED_P(sc) && !sc_empty_p(sc) && !sc_rn_p(sc))
1148  {
1149  if (op_statistics_p())
1150  {
1151  nb_proj_var++;
1154  }
1155 
1156  ifdebug(3)
1157  {
1158  pips_debug(3, "variable: %s, and initial region :\n", entity_name(var));
1159  print_region(reg);
1160  }
1161 
1162  if (base_contains_variable_p(sc->base, (Variable) var))
1163  {
1165  {
1166  region reg_tmp =
1168  region_action(reg));
1169  cell c_tmp = region_cell(reg_tmp);
1170 
1171  region_system_(reg) = region_system_(reg_tmp);
1172  if(cell_preference_p(c_tmp))
1174  else
1176  region_system_(reg_tmp) = newgen_Psysteme(SC_UNDEFINED);
1177  free_effect(reg_tmp);
1178  sc_rm(sc);
1180  }
1181  TRY {
1182  list l_phi_var = region_phi_cfc_variables(reg);
1183 
1184  if (gen_find_eq(var, l_phi_var) == chunk_undefined)
1185  {
1186  ifdebug(8) {
1187  pips_debug(8, "system before projection (1): \n");
1188  sc_syst_debug(sc);
1189  }
1190 
1191  Psysteme volatile * psc = &sc;
1192  sc_projection_along_variable_ofl_ctrl(psc,(Variable) var,
1193  FWD_OFL_CTRL);
1194  sc_base_remove_variable(sc, (Variable) var);
1195  // sometimes produces erroneous systems - BC 11/8/2011
1196  // sc = region_sc_normalize(sc,2);
1197  ifdebug(8) {
1198  pips_debug(8, "system before normalization: \n");
1199  sc_syst_debug(sc);
1200  }
1201  sc = region_sc_normalize(sc,1);
1202  ifdebug(8) {
1203  pips_debug(8, "system after normalization: \n");
1204  sc_syst_debug(sc);
1205  }
1206  region_system_(reg) = newgen_Psysteme(sc);
1207 
1208  if (op_statistics_p() &&
1210  nb_proj_var_must++;
1211  }
1212  else
1213  {
1214  Pvecteur pv_var = NULL;
1215  bool is_proj_exact = true;
1216 
1217  vect_add_elem(&pv_var, (Variable) var, VALUE_ONE);
1218 
1219  ifdebug(8) {
1220  pips_debug(8, "system before projection (2): \n");
1221  sc_syst_debug(sc);
1222  }
1223 
1224  sc = sc_projection_ofl_along_variables_with_test
1225  (sc, pv_var, &is_proj_exact);
1226  vect_rm(pv_var);
1227  // sometimes produces erroneous systems - BC 11/8/2011
1228  // sc = region_sc_normalize(sc,2);
1229  ifdebug(8) {
1230  pips_debug(8, "system before normalization: \n");
1231  sc_syst_debug(sc);
1232  }
1233  sc = region_sc_normalize(sc,1);
1234  ifdebug(8) {
1235  pips_debug(8, "system after normalization: \n");
1236  sc_syst_debug(sc);
1237  }
1238  region_system_(reg)= newgen_Psysteme(sc);
1239 
1241  {
1242  if (!is_proj_exact)
1244  else
1246  }
1247  }
1248  gen_free_list(l_phi_var);
1250  }
1251  }
1252 
1253  ifdebug(3)
1254  {
1255  pips_debug(3, "final region :\n");
1256  print_region(reg);
1257  }
1258  }
1259  }
1260 }
1261 
1262 
1263 /*********************************************************************************/
1264 /* Ope'rateurs concernant les syste`mes de contraintes, mais propres au */
1265 /* des re'gions. */
1266 /*********************************************************************************/
1267 
1268 
1269 static Pcontrainte eq_var_nophi_min_coeff(Pcontrainte contraintes, Variable var);
1270 static Pcontrainte eq_var_phi(Pcontrainte contraintes, Variable var);
1271 static Psysteme region_sc_minimal(Psysteme sc, bool *p_sc_changed_p);
1272 
1273 
1274 /* Psysteme region_sc_projection_ofl_along_parameters(Psysteme sc,
1275  * Pvecteur pv_param,
1276  * bool *p_exact)
1277  * input : a convex polyhedron sc to project along the parameters contained
1278  * in the vector pv_param, which are linked to the PHI variables;
1279  * p_exact is a pointer to a bool indicating whether the
1280  * projection is exact or not.
1281  * output : the polyhedron resulting of the projection.
1282  * modifies : sc, *p_exact.
1283  * comment :
1284  */
1286  Pvecteur pv_param,
1287  bool *p_exact)
1288 {
1289  *p_exact = true;
1290 
1291  for(; (*p_exact == true) && !VECTEUR_NUL_P(pv_param); pv_param = pv_param->succ)
1292  {
1293  Variable param = vecteur_var(pv_param);
1296  sc = region_sc_normalize(sc,2);
1297  }
1298 
1299  if (!(*p_exact) && !VECTEUR_NUL_P(pv_param))
1300  {
1302  /*sc = sc_projection_ofl_along_variables(sc,pv_param);*/
1303  }
1304  return sc;
1305 }
1306 
1307 
1308 
1309 /* Psysteme region_sc_projection_ofl_along_parameter(Psysteme sc,
1310  * Variable param,
1311  * bool *p_exact)
1312  * input : a convex polyhedron sc to project along the variable param
1313  * which is linked to the PHI variables;
1314  * p_exact is a pointer to a bool indicating whether the
1315  * projection is exact or not.
1316  * output : the polyhedron resulting of the projection.
1317  * modifies : sc, *p_exact.
1318  * comment : first, we must search for an equation
1319  * containing this variable, but no phi variables;
1320  * if such an equation does not explicitly exists, it may be implicit,
1321  * and we must find it using an hermitte form.
1322  * if such an equation does not exist, we must search for the
1323  * inequations containing this variable and one ore more phi variables.
1324  * If it does not exist then the projection is exact,
1325  * otherwise, it is not exact.
1326  *
1327  * WARNING : the base and dimension of sc are not updated.
1328  */
1330  bool *p_exact)
1331 {
1332  Pcontrainte eq;
1333  Pbase base_sc;
1334  bool hermite_sc_p;
1335 
1336  pips_debug(8, "begin\n");
1337 
1338 
1339  /* fisrt, we search for an explicit equation containing param,
1340  * but no phi variables
1341  */
1343 
1344  if (!CONTRAINTE_UNDEFINED_P(eq))
1345  {
1346  sc = sc_projection_ofl_with_eq(sc, eq, param);
1347  *p_exact = true;
1348  debug(8, "region_sc_projection_ofl_along_parameter",
1349  "explicit equation found.\n");
1350  return(sc);
1351  }
1352 
1353  /* if the last equation is not explicit, it may be implicit
1354  */
1355  (void)region_sc_minimal(sc, &hermite_sc_p);
1356 
1357  if (hermite_sc_p)
1358  {
1360 
1362 
1363  if (!CONTRAINTE_UNDEFINED_P(eq))
1364  {
1365  sc = sc_projection_ofl_with_eq(sc, eq, param);
1366  *p_exact = true;
1367  pips_debug(8, "implicit equation found.\n");
1369 
1370  return(sc);
1371  }
1372  }
1373 
1374  /* we then search if there exist an equation linking param to the
1375  * PHI variables.
1376  */
1377  eq = eq_var_phi(sc->egalites,param);
1378 
1379  if (!CONTRAINTE_UNDEFINED_P(eq))
1380  {
1381  sc = sc_projection_ofl_with_eq(sc, eq, param);
1382  *p_exact = false;
1383  pips_debug(8, "equation with PHI and param found -> projection not exact.\n");
1384 
1385  return(sc);
1386  }
1387 
1388 
1389  /* if such an equation does not exist, we search for an
1390  * inequation containing param and a phi variable
1391  */
1392  eq = eq_var_phi(sc->inegalites, param);
1394  *p_exact = true;
1395  else
1396  *p_exact = false;
1397 
1398  base_sc = base_dup(sc->base);
1399  if (!combiner_ofl(sc, param))
1400  {
1401  sc_rm(sc);
1402  return(sc_empty(base_sc));
1403  }
1404 
1405  base_rm(base_sc);
1406 
1407  pips_debug(8, "other cases.\n");
1408  return(sc);
1409 }
1410 
1411 
1412 /* Pcontrainte eq_var_nophi_min_coeff(Pcontrainte contraintes, Variable var)
1413  * input :
1414  * output : la contrainte (egalite ou inegalite) de "contraintes" qui contient
1415  * var, mais pas de variable de variables phis et ou` var a le
1416  * coeff non nul le plus petit;
1417  * modifies : nothing
1418  * comment : la contrainte renvoye'e n'est pas enleve'e de la liste.
1419  */
1420 static Pcontrainte
1422 {
1423  Value c, c_var = VALUE_ZERO;
1424  Pcontrainte eq_res, eq;
1425 
1426  if ( CONTRAINTE_UNDEFINED_P(contraintes) )
1427  return(CONTRAINTE_UNDEFINED);
1428 
1429  eq_res = CONTRAINTE_UNDEFINED;
1430 
1431  for (eq = contraintes; eq != NULL; eq = eq->succ)
1432  {
1433  /* are there phi variables in this equation ? */
1434  if (!vect_contains_phi_p(eq->vecteur)) {
1435  /* if not, we search if the coeff of var is minimum */
1436  c = vect_coeff(var, eq->vecteur);
1437  value_absolute(c);
1438  if (value_notzero_p(c) &&
1439  (value_lt(c,c_var) || value_zero_p(c_var)))
1440  {
1441  c_var = c;
1442  eq_res = eq;
1443  }
1444  }
1445  }
1446  return(eq_res);
1447 }
1448 
1449 /* Pcontrainte eq_var_nophi_min_coeff(Pcontrainte contraintes, Variable var)
1450  * input :
1451  * output : la contrainte (egalite ou inegalite) de "contraintes" qui contient
1452  * var, mais pas de variable de variables phis et ou` var a le
1453  * coeff non nul le plus petit;
1454  * modifies : nothing
1455  * comment : la contrainte renvoye'e n'est pas enleve'e de la liste.
1456  */
1457 static Pcontrainte eq_var_phi(Pcontrainte contraintes, Variable var)
1458 {
1459  Pcontrainte eq_res, eq;
1460 
1461  if ( CONTRAINTE_UNDEFINED_P(contraintes) )
1462  return(CONTRAINTE_UNDEFINED);
1463 
1464  eq_res = CONTRAINTE_UNDEFINED;
1465  eq = contraintes;
1466 
1467  while (CONTRAINTE_UNDEFINED_P(eq_res) && !CONTRAINTE_UNDEFINED_P(eq))
1468  {
1469  if (vect_contains_phi_p(eq->vecteur) &&
1471  eq_res = eq;
1472  eq = eq->succ;
1473  }
1474  return(eq_res);
1475 }
1476 
1477 
1478 static int constraints_nb_phi_eq(Pcontrainte eqs);
1479 
1480 /* Psysteme region_sc_minimal(Psysteme sc, bool p_sc_changed_p)
1481  * input : a polyhedron
1482  * output : an equivalent polyhedron, in which the number of equations
1483  * containing phi variables is minimal (see report E/185).
1484  * modifies : sc and p_sc_changed_p. The pointed bool is set to true, if
1485  * a new sc is calculated (with the hermite stuff).
1486  * comment :
1487  */
1488 static Psysteme region_sc_minimal(Psysteme sc, bool *p_sc_changed_p)
1489 {
1490  Pcontrainte eq = sc->egalites;
1491  int m = nb_elems_list(eq),
1492  n = base_dimension(sc->base),
1493  n_phi = base_nb_phi(sc->base);
1494  Pmatrix A, C, A_phi, A_phi_t, H, P, Q, Q_t, A_min, C_min;
1495  Value det_P, det_Q;
1496  Pbase sorted_base = base_dup(sc->base);
1497 
1498  *p_sc_changed_p = false;
1499 
1500  /* the number of equations containing phi variables must be greater than one,
1501  * otherwise, the system is already minimal. Moreover, the number of phi
1502  * variables must be greater than 0.
1503  */
1504  if (!(n_phi > 0 && (constraints_nb_phi_eq(eq) > 1)))
1505  return(sc);
1506 
1507  *p_sc_changed_p = true;
1508 
1509  ifdebug(8)
1510  {
1511  pips_debug(8, "initial sc :\n");
1512  sc_syst_debug(sc);
1513  }
1514 
1515  phi_first_sort_base(&sorted_base);
1516 
1517  A = matrix_new(m,n);
1518  C = matrix_new(m,1);
1519  A_phi = matrix_new(m,n_phi);
1520  A_phi_t = matrix_new(n_phi,m);
1521  H = matrix_new(n_phi,m);
1522  P = matrix_new(n_phi,n_phi);
1523  Q = matrix_new(m,m);
1524  Q_t = matrix_new(m,m);
1525  A_min = matrix_new(m,n);
1526  C_min = matrix_new(m,1);
1527 
1528  /* We first transform the equations of the initial system into
1529  * a matrices equation.
1530  */
1531  constraints_to_matrices(eq, sorted_base, A, C);
1532 
1533  /* We then compute the corresponding hermite form of the transpose
1534  * of the A_phi matrice
1535  */
1536  ordinary_sub_matrix(A, A_phi, 1, m, 1, n_phi);
1537  matrix_transpose(A_phi, A_phi_t);
1538  matrix_free(A_phi);
1539 
1540  matrix_hermite(A_phi_t, P, H, Q, &det_P, &det_Q);
1541  matrix_transpose(Q,Q_t);
1542  matrix_free(P);
1543  matrix_free(H);
1544  matrix_free(Q);
1545 
1546  /* and we deduce the minimal systeme */
1547  matrix_multiply(Q_t, A, A_min);
1548  matrix_multiply(Q_t, C, C_min);
1549  matrix_free(A);
1550  matrix_free(C);
1551 
1553  matrices_to_constraints(&(sc->egalites), sorted_base, A_min, C_min);
1554  matrix_free(A_min);
1555  matrix_free(C_min);
1556 
1557  ifdebug(8)
1558  {
1559  pips_debug(8, "final sc :\n");
1560  sc_syst_debug(sc);
1561  }
1562 
1563  return sc;
1564 }
1565 
1566 
1567 /* static int constraints_nb_phi_eq(Pcontrainte eqs)
1568  * input : a list of contraints.
1569  * output : the number of contraints containing phi variables.
1570  * modifies : nothing.
1571  * comment :
1572  */
1574 {
1575  int nb_phi_eq = 0;
1576 
1577  for(; !CONTRAINTE_UNDEFINED_P(eqs); eqs = eqs->succ)
1578  if (vect_contains_phi_p(eqs->vecteur))
1579  nb_phi_eq++;
1580 
1581  return(nb_phi_eq);
1582 }
1583 
1584 
1585 
1586 /* bool region_projection_along_index_safe_p(entity index, range l_range)
1587  * input : an loop index and its range
1588  * output : true if its projection of regions along index is safe (see
1589  * conditions in report E/185).
1590  * modifies : nothing
1591  * comment :
1592  */
1594  range l_range)
1595 {
1596  bool projection_of_index_safe = false;
1597  normalized n, nub, nlb;
1598  expression e_incr = range_increment(l_range);
1599  Value incr = VALUE_ZERO;
1600 
1601  /* Is the loop increment numerically known ? */
1602  n = NORMALIZE_EXPRESSION(e_incr);
1603  if(normalized_linear_p(n))
1604  {
1605  Pvecteur v_incr = normalized_linear(n);
1606  pips_assert("project_regions_along_index_safe_p",
1607  !VECTEUR_NUL_P(v_incr));
1608  if(vect_constant_p(v_incr))
1609  incr = vect_coeff(TCST, v_incr);
1610  }
1611 
1612  nub = NORMALIZE_EXPRESSION(range_upper(l_range));
1613  nlb = NORMALIZE_EXPRESSION(range_lower(l_range));
1614 
1615  projection_of_index_safe =
1616  (value_one_p(value_abs(incr)) && normalized_linear_p(nub)
1617  && normalized_linear_p(nlb));
1618  return(projection_of_index_safe);
1619 }
1620 
1621 
1622 /* void region_dynamic_var_elim(effect reg)
1623  * input : a region .
1624  * output : nothing
1625  * modifies :
1626  * comment : eliminates all dynamic variables contained in the system of
1627  * constraints of the region.
1628  *
1629  * First, it makes a list of all the dynamic variables present.
1630  * And then, it projects the region along the hyperplane
1631  * defined by the dynamic entities
1632  *
1633  */
1635 {
1636  list l_var_dyn = NIL;
1637  Psysteme ps_reg;
1638  Pbase ps_base;
1639 
1640  ps_reg = region_system(reg);
1641  ps_base = ps_reg->base;
1642 
1643  pips_assert("region_dynamic_var_elim", ! SC_UNDEFINED_P(ps_reg));
1644 
1645  for (; ! VECTEUR_NUL_P(ps_base); ps_base = ps_base->succ)
1646  {
1647  entity e = (entity) ps_base->var;
1648 
1649  /* TCST is not dynamic */
1650  if (e != NULL)
1651  {
1652  storage s = entity_storage(e);
1653 
1654  debug(5, "region_dynamic_var_elim", "Test upon var : %s\n",
1655  entity_local_name(e));
1656 
1657  /* An entity in a system that has an undefined storage is
1658  necesseraly a PHI entity, not dynamic !! */
1659  if (s != storage_undefined)
1660  {
1661  if (storage_tag(s) == is_storage_ram)
1662  {
1663  ram r = storage_ram(s);
1664  if (dynamic_area_p(ram_section(r)))
1665  {
1666  debug(5, "region_dynamic_var_elim",
1667  "dynamic variable found : %s\n", entity_local_name(e));
1668  l_var_dyn = CONS(ENTITY, e, l_var_dyn);
1669  }
1670  }
1671  }
1672  }
1673  }
1674  ifdebug(3)
1675  {
1676  pips_debug(3, "variables to eliminate: \n");
1677  print_entities(l_var_dyn);
1678  }
1679 
1680  if (must_regions_p())
1682  else
1684  gen_free_list(l_var_dyn);
1685 }
1686 
1687 
1688 /*********************************************************************************/
1689 /* MISC */
1690 /*********************************************************************************/
1691 
1692 
1694 {
1695 
1696  Pvecteur pv_var = NULL;
1697  /* converts the list into a Pvecteur */
1698  MAP(ENTITY, e,
1699  {
1700  if (base_contains_variable_p(ps->base, (Variable) e) )
1701  vect_add_elem(&pv_var, (Variable) e, VALUE_ONE);
1702  }, l_var);
1704  /* ps = sc_projection_ofl_along_variables(ps, pv_var); */
1705  vect_rm(pv_var);
1706  return(ps);
1707 }
1708 
1709 
1710 
1711 /* void region_sc_projection_ofl_along_variables(Psysteme *psc, Pvecteur pv)
1712  * input : a system of constraints, and a vector of variables.
1713  * output : a system of contraints, resulting of the successive projection
1714  * of the initial system along each variable of pv.
1715  * modifies : *psc.
1716  * comment : it is very different from
1717  * sc_projection_with_test_along_variables_ofl_ctrl.
1718  * sc_empty is returned if the system is not feasible (BC).
1719  * The base of *psc is updated. assert if one of the variable
1720  * does not belong to the base.
1721  * The case ofl_ctrl == OFL_CTRL is not handled, because
1722  * the user may want an SC_UNDEFINED, or an sc_empty(sc->base)
1723  * or an sc_rn(sc->base) as a result. It is not homogeneous.
1724  * special implementation for regions: special choice for
1725  * redudancy elimination. bc.
1726  */
1728 Psysteme *psc;
1729 Pvecteur pv;
1730 int ofl_ctrl;
1731 {
1732  Pvecteur pv1;
1733  Pbase scbase = base_copy((*psc)->base);
1734 
1735  if (!VECTEUR_NUL_P(pv)) {
1736  for (pv1 = pv;!VECTEUR_NUL_P(pv1) && !SC_UNDEFINED_P(*psc); pv1=pv1->succ) {
1737 
1738  sc_projection_along_variable_ofl_ctrl(psc,vecteur_var(pv1), ofl_ctrl);
1739 
1740  /* In case of big sc, we might consider a better order for the projection.
1741  * Example: 2 phases of elimination (must-projection):
1742  * - first: elimination of PHI variables: PHI3, PHI2, PHI1
1743  * - then: elimination of PSI variables: PSI3, PSI2, PSI1
1744  * Ex: PHI3 (297 inequations), then PHI2 => explosion (21000) = PSI1 (1034)
1745  *But PHI3(297 inequations), then PSI1 (191), then PHI2 => ok (1034) DN 21/1/03
1746  *
1747  * The non_exact projection:
1748  * if the projection excat fails, then return the modified sc, without variable in base.
1749  */
1750 
1751  if (!SC_UNDEFINED_P(*psc)) {
1753  /* *psc = region_sc_normalize(*psc,2); */
1754  }
1755  }
1756  }
1757 
1758  if (SC_UNDEFINED_P(*psc)){ /* ne devrait plus arriver ! */
1759  *psc = sc_empty(scbase);
1760  for (pv1 = pv;!VECTEUR_NUL_P(pv1); pv1=pv1->succ) {
1762  }
1763  }
1764  else {
1765  base_rm(scbase);
1766  }
1767 
1768 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
void free_effect(effect p)
Definition: effects.c:451
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
cons * arguments_difference(cons *a1, cons *a2)
set difference: a1 - a2 ; similar to set intersection
Definition: arguments.c:233
list arguments_intersection(list a1, list a2)
Build a new list with all entities occuring in both a1 and a2.
Definition: arguments.c:158
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
#define VALUE_ZERO
#define value_absolute(ref)
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_notone_p(val)
#define value_one_p(val)
#define VALUE_MONE
#define value_zero_p(val)
int Value
#define VALUE_ONE
#define value_abs(val)
#define value_lt(v1, v2)
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
#define A(i, j)
comp_matrice.c
Definition: comp_matrice.c:63
void sc_syst_debug(Psysteme s)
constraint_to_text.c
#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_free(Pcontrainte c)
Pcontrainte contrainte_free(Pcontrainte c): liberation de l'espace memoire alloue a la contrainte c a...
Definition: alloc.c:184
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 vect_constant_p(Pvecteur)
bool vect_constant_p(Pvecteur v): v contains only a constant term, may be zero
Definition: predicats.c:211
#define NB_MAX_ARRAY_DIM
#define region_any_reference(reg)
To be avoided.
#define region_rn_p(reg)
#define region_action(reg)
#define debug_regions_consistency(l_reg)
consistency checking
#define debug_region_consistency(reg)
#define region_system_(reg)
#define region_entity(reg)
#define region_system(reg)
#define region_empty_p(reg)
#define region_cell(reg)
#define region_approximation_tag(reg)
#define region
simulation of the type region
list region_add_to_regions(effect, list)
Psysteme sc_list_variables_rename(Psysteme, list, list)
bool must_regions_p(void)
list rho_entities_list(int, int)
list variables_to_int_variables(list)
list phi_entities_list(int, int)
void region_sc_append_and_normalize(effect, Psysteme, int)
list region_phi_cfc_variables(effect)
void phi_first_sort_base(Pbase *)
int base_nb_phi(Pbase)
list beta_entities_list(int, int)
effect reference_whole_region(reference, action)
list cell_reference_phi_cfc_variables(reference, Psysteme)
list psi_entities_list(int, int)
Psysteme region_sc_normalize(Psysteme, int)
entity make_beta_entity(int)
utils.c
effect region_dup(effect)
bool op_statistics_p(void)
list variables_to_old_variables(list)
#define pips_debug_effects(level, message, l_eff)
#define pips_debug_effect(level, message, eff)
for debug
bool store_effect_p(effect)
Definition: effects.c:1062
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
bool vect_contains_phi_p(Pvecteur)
bool vect_contains_phi_p(Pvecteur v) input : a vector output : true if v contains a PHI variable,...
Definition: effects.c:1427
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define cell_reference_p(x)
Definition: effects.h:467
#define cell_preference_p(x)
Definition: effects.h:470
@ is_approximation_may
Definition: effects.h:341
@ is_approximation_exact
Definition: effects.h:343
#define newgen_Psysteme(p)
Definition: effects.h:47
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
#define chunk_undefined
obsolete
Definition: genC.h:79
if(!(yy_init))
Definition: genread_lex.c:1029
void free(void *)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
#define matrix_free(m)
Allocation et desallocation d'une matrice.
Definition: matrix-local.h:73
Pmatrix matrix_new(int m, int n)
package matrix
Definition: alloc.c:41
void matrix_hermite(Pmatrix MAT, Pmatrix P, Pmatrix H, Pmatrix Q, Value *det_p, Value *det_q)
package matrix
Definition: hermite.c:78
void matrix_multiply(const Pmatrix a, const Pmatrix b, Pmatrix c)
void matrix_multiply(Pmatrix a, Pmatrix b, Pmatrix c): multiply rational matrix a by rational matrix ...
Definition: matrix.c:95
void matrix_transpose(const Pmatrix A, Pmatrix At)
void matrix_transpose(Pmatrix a, Pmatrix a_t): transpose an (nxm) rational matrix a into a (mxn) rati...
Definition: matrix.c:64
void ordinary_sub_matrix(Pmatrix, Pmatrix, int, int, int, int)
void ordinary_sub_matrix(Pmatrix A, A_sub, int i1, i2, j1, j2) input : a initialized matrix A,...
Definition: sub-matrix.c:469
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
int tag
TAG.
Definition: newgen_types.h:92
static Psysteme region_sc_projection_ofl_along_parameters(Psysteme sc, Pvecteur pv_param, bool *p_exact)
OPE'RATEURS CONCERNANT LES RE'GIONS INDIVIDUELLES.
list regions_dynamic_elim(list l_reg)
list regions_dynamic_elim(list l_reg) input : a list of regions.
void region_remove_psi_variables(region reg)
void region_remove_psi_variables(effect reg, int phi_max) input : a PHI region in which psi variables...
void region_exact_projection_along_parameters(region reg, list l_param)
void region_exact_projection_along_parameters(effect reg, list l_param) input : a regions reg and a l...
void region_remove_rho_variables(region reg)
void region_remove_rho_variables(effect reg, int phi_max) input : a PHI region in which rho variables...
Psysteme cell_reference_system_remove_psi_variables(reference ref, Psysteme sc, bool *exact_p)
void project_regions_with_transformer_inverse(list l_reg, transformer trans, list l_var_not_proj)
static int nb_proj_param_hermite
void region_sc_projection_along_variables_ofl_ctrl(Psysteme *psc, Pvecteur pv, int ofl_ctrl)
void region_sc_projection_ofl_along_variables(Psysteme *psc, Pvecteur pv) input : a system of constra...
static int nb_proj_var_ofl
void project_regions_along_parameters(list l_reg, list l_param)
void project_regions_along_parameters(list l_reg, list l_param) input : a list of regions to project,...
bool region_projection_along_index_safe_p(entity __attribute__((unused)) index, range l_range)
bool region_projection_along_index_safe_p(entity index, range l_range) input : an loop index and its ...
static Psysteme region_sc_projection_ofl_along_parameter(Psysteme sc, Variable param, bool *p_exact)
Psysteme region_sc_projection_ofl_along_parameter(Psysteme sc, Variable param, bool *p_exact) input :...
static Pcontrainte eq_var_nophi_min_coeff(Pcontrainte contraintes, Variable var)
Ope'rateurs concernant les syste`mes de contraintes, mais propres au
void regions_transformer_apply(list l_reg, transformer trans, list l_var_not_proj, bool backward_p)
void regions_transformer_apply(l_reg, trans, l_var_not_proj) input : a list of regions,...
void project_regions_along_variables(list l_reg, list l_var)
void project_regions_along_variables(list l_reg, list l_param) input : a list of regions to project,...
entity loop_regions_normalize(list l_reg, entity index, range l_range, bool *normalized_regions_p, bool sc_loop_p, Psysteme *psc_loop)
FONCTIONS D'INTERFACE
void region_non_exact_projection_along_parameters(region reg, list l_param)
void region_non_exact_projection_along_parameters(effect reg, list l_param) input : a region and a li...
void region_dynamic_var_elim(region reg)
void region_dynamic_var_elim(effect reg) input : a region .
Psysteme cell_reference_sc_exact_projection_along_variable(reference ref, Psysteme sc, entity var, bool *exact_p)
static int nb_proj_var
static int nb_proj_var_pot_must
Psysteme sc_projection_ofl_along_list_of_variables(Psysteme ps, list l_var)
MISC
static int nb_proj_param_ofl
void region_remove_phi_variables(region reg)
void region_remove_phi_variables(effect reg, int phi_max) input : a PSI region in which phi variables...
void region_remove_beta_variables(region reg)
void region_remove_variables(effect reg, int beta_max) input : a PSI region in which beta variables m...
static int nb_proj_param_hermite_success
static int nb_proj_var_must
void print_proj_op_statistics(char *mod_name, char *prefix)
void region_non_exact_projection_along_variables(region reg, list l_var)
void region_non_exact_projection_along_variables(effect reg, list l_var) input : a region and a list ...
static Psysteme region_sc_minimal(Psysteme sc, bool *p_sc_changed_p)
Psysteme region_sc_minimal(Psysteme sc, bool p_sc_changed_p) input : a polyhedron output : an equival...
void reset_proj_op_statistics()
old_projection.c
static int constraints_nb_phi_eq(Pcontrainte eqs)
static int constraints_nb_phi_eq(Pcontrainte eqs) input : a list of contraints.
void regions_remove_phi_variables(list l_reg)
void regions_remove_phi_variables(list l_reg) input : a list of regions, and an integer,...
static int nb_proj_param_must
void project_regions_along_loop_index(list l_reg, entity index, range l_range)
void project_regions_along_loop_index(list l_reg, entity index, l_range) input : a list l_reg of regi...
static int nb_proj_param_pot_must
void region_exact_projection_along_variables(effect reg, list l_var)
void region_exact_projection_along_variables(effect reg, list l_var) input : a region and a list of v...
static Pcontrainte eq_var_phi(Pcontrainte contraintes, Variable var)
Pcontrainte eq_var_nophi_min_coeff(Pcontrainte contraintes, Variable var) input : output : la contrai...
void project_regions_with_transformer(list l_reg, transformer trans, list l_var_not_proj)
void region_exact_projection_along_variable(region reg, entity var)
void region_exact_projection_along_variable(effect reg, entity var) input : a region and a variable (...
Psysteme cell_reference_system_remove_rho_variables(reference ref, Psysteme sc, bool *exact_p)
static int nb_proj_param
STATISTICS FOR PROJECTION OPERATORS
#define Q
Definition: pip__type.h:39
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
#define print_region(x)
Definition: print.c:343
static const char * prefix
#define NORMALIZE_EXPRESSION(e)
bool dynamic_area_p(entity aire)
Definition: area.c:68
bool stack_area_p(entity aire)
Definition: area.c:104
bool entity_special_area_p(entity e)
Definition: area.c:154
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
void print_entities(list l)
Definition: entity.c:167
#define reference_undefined
Definition: ri.h:2302
#define normalized_linear_p(x)
Definition: ri.h:1779
#define range_upper(x)
Definition: ri.h:2290
#define storage_tag(x)
Definition: ri.h:2515
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
#define range_increment(x)
Definition: ri.h:2292
#define ram_section(x)
Definition: ri.h:2249
@ is_storage_rom
Definition: ri.h:2494
@ is_storage_return
Definition: ri.h:2491
@ is_storage_ram
Definition: ri.h:2492
@ is_storage_formal
Definition: ri.h:2493
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define transformer_arguments(x)
Definition: ri.h:2871
#define preference_reference(x)
Definition: ri.h:2102
#define range_lower(x)
Definition: ri.h:2288
#define storage_ram(x)
Definition: ri.h:2521
#define normalized_linear(x)
Definition: ri.h:1781
#define predicate_system(x)
Definition: ri.h:2069
#define storage_undefined
Definition: ri.h:2476
void sc_base_remove_variable(Psysteme sc, Variable v)
Definition: sc.c:239
bool sc_rn_p(Psysteme sc)
bool sc_rn_p(Psysteme sc): check if the set associated to sc is the whole space, rn
Definition: sc_alloc.c:369
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
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
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
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Psysteme sc_safe_append(Psysteme s1, Psysteme s2)
Psysteme sc_safe_append(Psysteme s1, Psysteme s2) input : output : calcul de l'intersection des polye...
void sc_print(Psysteme ps, get_variable_name_t nom_var)
void sc_print()
Definition: sc_io.c:194
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
void matrices_to_constraints(Pcontrainte *, Pbase, Pmatrix, Pmatrix)
=======================================================================
void constraints_to_matrices(Pcontrainte, Pbase, Pmatrix, Pmatrix)
=======================================================================
Definition: pip__tab.h:25
package matrice
Definition: matrix-local.h:63
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
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: replace.c:135
bool local_old_value_entity_p(entity)
Return true if an entity is a local old value (such as "o#0" for a global value "i#init"....
Definition: value.c:642
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define NO_OFL_CTRL
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
#define vecteur_succ(v)
#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_dimension(b)
#define BASE_NULLE_P(b)
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_cl_ofl_ctrl(Pvecteur v, Value lambda, Pvecteur u, int ofl_ctrl)
Pvecteur vect_cl_ofl_ctrl(Pvecteur v, Value lambda, Pvecteur u, int ofl_ctrl): etape d'acculumulation...
Definition: binaires.c:128
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