PIPS
binary_operators.c
Go to the documentation of this file.
1 /*
2 
3  $Id: binary_operators.c 23372 2017-05-05 15:35:30Z lossing $
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 : Beatrice Creusillet, September 1994
29  *
30  * This File contains the functions that deal with the comparison and
31  * combinations of regions.
32  */
33 
34 
35 #include <stdio.h>
36 #include <string.h>
37 
38 #include "genC.h"
39 #include "linear.h"
40 #include "ri.h"
41 #include "effects.h"
42 #include "database.h"
43 
44 #include "boolean.h"
45 #include "vecteur.h"
46 #include "contrainte.h"
47 #include "sc.h"
48 #include "sommet.h"
49 #include "ray_dte.h"
50 #include "sg.h"
51 #include "polyedre.h"
52 #include "union.h"
53 
54 #include "constants.h"
55 #include "ri-util.h"
56 #include "prettyprint.h" // for sc_syst_debug()
57 #include "effects-util.h"
58 #include "pipsdbm.h"
59 #include "misc.h"
60 #include "text.h"
61 
62 #include "effects-generic.h"
63 #include "effects-convex.h"
64 
65 #define COMBINE 1
66 #define UNUSED 2
67 
68 #define SUPER true
69 #define SUB false
70 
71 /****************************************** STATISTICS FOR BINARY OPERATORS */
72 
73 static int nb_umust = 0;
74 static int nb_umust_must_must = 0;
75 static int nb_umust_must_must_must = 0;
76 static int nb_umust_must_may = 0;
77 static int nb_umust_must_may_must = 0;
78 static int nb_umust_sc_rn = 0;
79 
80 static int nb_umay = 0;
81 static int nb_umay_must_must = 0;
82 static int nb_umay_must = 0;
83 
84 static int nb_dsup = 0;
85 static int nb_dsup_pot_must = 0;
86 static int nb_dsup_must = 0;
87 
88 static int nb_dinf = 0;
89 static int nb_dinf_pot_must = 0;
90 static int nb_dinf_must = 0;
91 
92 
94 {
95  nb_umust = 0;
100  nb_umust_sc_rn = 0;
101 
102  nb_umay = 0;
103  nb_umay_must_must = 0;
104  nb_umay_must = 0;
105 
106  nb_dsup = 0;
107  nb_dsup_pot_must = 0;
108  nb_dsup_must = 0;
109 
110  nb_dinf = 0;
111  nb_dinf_pot_must = 0;
112  nb_dinf_must = 0;
113 }
114 
115 
116 
117 
118 void print_umust_statistics(char *mod_name, char *prefix)
119 {
120  FILE *fp;
121  string filename;
122 
123  filename = "umust_op_stat";
125  mod_name, ".", prefix, filename, NULL));
126 
127  fp = safe_fopen(filename, "w");
128  fprintf(fp,"%s",mod_name);
129 
130  fprintf(fp," %d %d %d %d %d %d\n", nb_umust, nb_umust_must_must,
133 
134  safe_fclose(fp, filename);
135  free(filename);
136 }
137 
138 
139 void print_umay_statistics(char *mod_name, char *prefix)
140 {
141  FILE *fp;
142  string filename;
143 
144  filename = "umay_op_stat";
146  mod_name, ".", prefix, filename, NULL));
147 
148  fp = safe_fopen(filename, "w");
149  fprintf(fp,"%s",mod_name);
150 
151  fprintf(fp," %d %d %d \n", nb_umay, nb_umay_must_must, nb_umay_must);
152 
153  safe_fclose(fp, filename);
154  free(filename);
155 }
156 
157 
158 void print_dsup_statistics(char *mod_name, char *prefix)
159 {
160  FILE *fp;
161  string filename;
162 
163  filename = "dsup_op_stat";
165  mod_name, ".", prefix, filename, NULL));
166 
167  fp = safe_fopen(filename, "w");
168  fprintf(fp,"%s",mod_name);
169 
170  fprintf(fp," %d %d %d \n", nb_dsup, nb_dsup_pot_must, nb_dsup_must);
171 
172  safe_fclose(fp, filename);
173  free(filename);
174 }
175 
176 
177 void print_dinf_statistics(char *mod_name, char *prefix)
178 {
179  FILE *fp;
180  string filename;
181 
182  filename = "dinf_op_stat";
184  mod_name, ".", prefix, filename, NULL));
185 
186  fp = safe_fopen(filename, "w");
187  fprintf(fp,"%s",mod_name);
188 
189  fprintf(fp," %d %d %d \n", nb_dinf, nb_dinf_pot_must, nb_dinf_must);
190 
191  safe_fclose(fp, filename);
192  free(filename);
193 }
194 
195 
196 
197 /*********************************************************** INTERFACES */
198 
199 
200 /* list RegionsMayUnion(list l1, list l2, union_combinable_p)
201  * input : two lists of regions
202  * output : a list of regions, may union of the two initial lists
203  * modifies : l1 and l2 and their regions. Regions that are not reused in
204  * the output list of regions are freed.nothing
205  * (no sharing introduced).
206  */
208  bool (*union_combinable_p)(effect, effect))
209 {
210  list lr;
211 
212  debug(3, "RegionsMayUnion", "begin\n");
214  union_combinable_p,
217  debug(3, "RegionsMayUnion", "end\n");
218  return(lr);
219 }
220 
221 
222 /* list RegionsMustUnion(list l1, list l2, union_combinable_p)
223  * input : two lists of regions
224  * output : a list of regions, must union of the two initial lists
225  * modifies : l1 and l2 and their regions. Regions that are not reused in
226  * the output list of regions are freed.
227  */
229  bool (*union_combinable_p)(effect, effect))
230 {
231  list lr;
232 
233  debug(3, "RegionsMustUnion", "begin\n");
235  union_combinable_p,
238  debug(3, "RegionsMustUnion", "end\n");
239  return(lr);
240 }
241 
242 
243 /* list RegionsIntersection(list l1,l2,
244  bool (*intersection_combinable_p)(effect, effect))
245  * input :
246  * output :
247  * modifies :
248  * comment :
249  */
251  bool (*intersection_combinable_p)(effect, effect))
252 {
253  list l_res = NIL;
254 
255  debug(3, "RegionsIntersection", "begin\n");
257  intersection_combinable_p,
259 
260 
261  debug(3, "RegionsIntersection", "end\n");
262 
263  return l_res;
264 }
265 
266 
267 /* list RegionsEntitiesIntersection(list l1,l2,
268  bool (*intersection_combinable_p)(effect, effect))
269  * input : two lists of regions
270  * output : a list of regions containing all the regions of l1 that have
271  * a corresponding region (i.e. same entity) in l2.
272  * modifies : l1 and l2.
273  * comment :
274  */
276  bool (*intersection_combinable_p)(effect, effect))
277 {
278  list l_res = NIL;
279 
280  pips_debug(3, "begin\n");
281  /* l_res = list_of_effects_generic_binary_op(l1, l2,
282  intersection_combinable_p,
283  region_entities_intersection,
284  region_to_nil_list,
285  region_to_nil_list); */
286 
288  intersection_combinable_p,
290  pips_debug(3, "end\n");
291 
292  return l_res;
293 }
294 
295 
296 /* list RegionsSupDifference(list l1, l2)
297  * input : two lists of regions
298  * output : a list of region, representing the sup_difference of the
299  * initial regions.
300  * modifies : the regions of l2 may be freed.
301  * comment : we keep the regions of l1 that are not combinable with those
302  * of l2, but we don't keep the regions of l2 that are not
303  * combinable with those of l_reg1.
304  */
306  bool (*difference_combinable_p)(effect, effect))
307 {
308  list l_res = NIL;
309 
310  debug(3, "RegionsSupDifference", "begin\n");
311  /* l_res = list_of_effects_generic_binary_op(l1, l2,
312  difference_combinable_p,
313  region_sup_difference,
314  region_to_list,
315  region_to_nil_list); */
317  difference_combinable_p,
319 
320  debug(3, "RegionsSupDifference", "end\n");
321 
322  return l_res;
323 }
324 
325 /* list RegionsInfDifference(list l1, l2)
326  * input : two lists of regions
327  * output : a list of region, representing the inf_difference of the
328  * initial regions.
329  * modifies : the regions of l2 may be freed.
330  * comment : we keep the regions of l1 that are not combinable with those
331  * of l2, but we don't keep the regions of l2 that are not
332  * combinable with those of l_reg1.
333  */
335  bool (*difference_combinable_p)(effect, effect))
336 {
337  list l_res = NIL;
338 
339  debug(3, "RegionsInfDifference", "begin\n");
340  /* l_res = list_of_effects_generic_binary_op(l1, l2,
341  difference_combinable_p,
342  region_inf_difference,
343  region_to_list,
344  region_to_nil_list); */
346  difference_combinable_p,
348  debug(3, "RegionsInfDifference", "end\n");
349 
350  return l_res;
351 }
352 
353 
354 
355 /* list RegionsEntitiesInfDifference(list l1, l2)
356  * input : two lists of regions
357  * output : a list of regions, such that: if there is a region R concerning
358  * entity A in l1 and in l2, then R is removed from the result;
359  * if there is a region R concerning array A in l1, but not in l2,
360  * then it is kept in l1, and in the result.
361  * modifies : the regions of l2 may be freed.
362  * comment : we keep the regions of l1 that are not combinable with those
363  * of l2, but we don't keep the regions of l2 that are not
364  * combinable with those of l_reg1.
365  */
367  list l1, list l2,
368  bool (*difference_combinable_p)(effect, effect))
369 {
370  list l_res = NIL;
371 
372  debug(3, "RegionsEntitiesInfDifference", "begin\n");
373  /* l_res = list_of_effects_generic_binary_op(l1, l2,
374  difference_combinable_p,
375  regions_to_nil_list,
376  region_to_list,
377  region_to_nil_list);*/
379  difference_combinable_p,
381  debug(3, "RegionsEntitiesInfDifference", "end\n");
382 
383  return l_res;
384 }
385 
386 
387 /***************************************** INDIVIDUAL REGIONS COMBINATION */
388 
389 
390 /* 1- Union :
391  */
392 
395 
396 /**
397  @brief computes the must union of two combinable array regions
398  @param[in] r1 input array region
399  @param[in] r2 input array region
400  @see effects_combinable_p
401  @return a new region with no sharing with the input regions
402  */
404 {
405  return region_union(r1, r2, true);
406 }
407 
408 /**
409  @brief computes the may union of two combinable array regions
410  @param[in] r1 input array region
411  @param[in] r2 input array region
412  @see effects_combinable_p
413  @return a new region with no sharing with the input regions
414  */
416 {
417  return region_union(r1, r2, false);
418 }
419 
420 /**
421  @brief computes the must or may union of two combinable array regions depending
422  on the value of must_p
423  @param[in] r1 input array region
424  @param[in] r2 input array region
425  @param[in] must_p bool to control the must/may behavior of the function
426  @see effects_combinable_p
427  @return a new region with no sharing with the input regions
428  */
429 list region_union(region r1, region r2, bool must_p)
430 {
431  list l_res = NIL;
432  effect r_res;
433  tag app1 = effect_approximation_tag(r1);
434  tag app2 = effect_approximation_tag(r2);
435 
436  if(store_effect_p(r1))
437  {
438  pips_assert("r2 is a store effect", store_effect_p(r2));
439  bool al1_p = effect_abstract_location_p(r1);
440  bool al2_p = effect_abstract_location_p(r2);
441 
442  /* Abstract locations cases */
443  /* In fact, we could have :
444  if (al1_p || al_2_p)
445  {
446  entity e1 = effect_entity(e1);
447  entity e2 = effect_entity(e2);
448  new_ent = entity_locations_max(e1, e2);
449 
450  eff = make_simple_effect(make_reference(new_ent, NIL),
451  copy_action(effect_action(eff1)),
452  make_approximation(approximation_and(app1,app2), UU));
453  }
454 
455  but entity_locations_max involves string manipulations, which are always costly.
456  So we treat apart the cases where (al1_p and ! al2_p) and (al2_p and ! al1_p) because
457  we already know that the abstract location is the max of both locations
458  (because they are combinable (see effects_combinable_p))
459 
460  */
461  if (al1_p && al2_p)
462  {
463  entity e1 = effect_entity(r1);
464  entity e2 = effect_entity(r2);
465 
466  entity new_ent = entity_locations_max(e1, e2);
467 
468  r_res = make_simple_effect(make_reference(new_ent, NIL),
470  make_approximation(must_p?approximation_and(app1,app2):
471  approximation_or(app1,app2), UU));
472  }
473  else if (al1_p) {
474  // functions that can be pointed by effect_dup_func:
475  // simple_effect_dup
476  // region_dup
477  // copy_effect
478  r_res = (*effect_dup_func)(r1);
479  }
480  else if (al2_p) {
481  // functions that can be pointed by effect_dup_func:
482  // simple_effect_dup
483  // region_dup
484  // copy_effect
485  r_res = (*effect_dup_func)(r2);
486  }
487 
488  /* concrete locations cases */
489  else
490  {
491  r_res = must_p ? regions_must_convex_hull(r1, r2)
492  : regions_may_convex_hull(r1,r2);
493  if(region_empty_p(r_res))
494  {
495  region_free(r_res);
496  r_res = effect_undefined;
497  }
498  }
499  }
500  else
501  {
502  pips_assert("r2 is not a store effect", !store_effect_p(r2));
503  r_res = copy_effect(r1);
504  }
505 
506  if (!effect_undefined_p(r_res))
507  {
509  l_res = region_to_list(r_res);
510  }
511 
512  return(l_res);
513 }
514 
515 
517 
518 /* static effect regions_must_convex_hull(r1,r2)
519  * input : two "effect" representing two regions.
520  * output : an effect, which predicate is the convex hull of the predicates
521  * of the initial regions, and which approximation is function of
522  * of the approximations of the original regions
523  * and, in some cases, of the relations between the two initial
524  * predicates.
525  * modifies : the basis of the predicates of r1 and r2
526  * comment : always computes the convex hull, even if it leads to a may
527  * approximation.
528  *
529  * FI: extension to support non-store effects without predicates
530  */
532 {
533  region reg = r1; /* result */
534 
535  if(!store_effect_p(r1)) {
536  /* proper_effects_combine() free the arguments of
537  region_sc_convex_hull() */
538  reg = copy_effect(r1);
539  } else {
540  /* Automatic variables read in a CATCH block need to be declared volatile as
541  * specified by the documentation*/
542  Psysteme volatile s1 = region_system(r1);
543  Psysteme s2 = region_system(r2);
544  Psysteme sr;
545  tag app1 = region_approximation_tag(r1);
546  tag app2 = region_approximation_tag(r2);
547  tag appr = is_approximation_may;
548 
551 
552  pips_assert("systems not undefined\n",
553  !(SC_UNDEFINED_P(s1) || SC_UNDEFINED_P(s2)));
554 
555  ifdebug(8)
556  {
557  pips_debug(8, "syste`mes initiaux\n");
558  sc_syst_debug(s1);
559  sc_syst_debug(s2);
560  }
561 
562  /* sc_empty : no part of the array is accessed */
563  if (sc_empty_p(s1) && sc_empty_p(s2))
564  {
565  pips_debug(8, "s1 and s2 sc_empty\n");
566  reg = region_dup(r1);
567  region_approximation_tag(reg) = approximation_or(app1,app2);
568  return(reg);
569  }
570 
571  if (sc_empty_p(s1))
572  {
573  pips_debug(8, "s1 sc_empty\n");
574  reg = region_dup(r1);
575  sc_rm(region_system(reg));
577  return(reg);
578  }
579 
580  if (sc_empty_p(s2))
581  {
582  pips_debug(8, "s2 sc_empty\n");
583  reg = region_dup(r1);
584  return(reg);
585  }
586 
587 
588  /* sc_rn : the entire array is accessed */
589  if (sc_rn_p(s1) && sc_rn_p(s2))
590  {
591  pips_debug(8, "s1 and s2 sc_rn\n");
592  reg = region_dup(r1);
593  region_approximation_tag(reg) = approximation_or(app1,app2);
594  return(reg);
595  }
596 
597  if (sc_rn_p(s1))
598  {
599  pips_debug(8, "s1 sc_rn\n");
600  reg = region_dup(r1);
602  return(reg);
603  }
604 
605  if (sc_rn_p(s2))
606  {
607  pips_debug(8, "s2 sc_rn\n");
608  reg = region_dup(r1);
610  region_approximation_tag(reg) = app2;
611  return(reg);
612  }
613 
614 
615  /* otherwise, we have to compute the convex-hull of the two predicates */
616  if (op_statistics_p()) nb_umust++;
617 
618 
619  Pbase b1 = s1->base;
620  Pbase b2 = s2->base;
621  Pbase volatile b = base_union(b1, b2);
622  s1->base = b;
623  sc_dimension(s1) = base_dimension(b);
624  s2->base = base_copy(b);
625  sc_dimension(s2) = sc_dimension(s1);
626  base_rm(b1);
627  base_rm(b2);
628 
629 
631  {
632  pips_debug(1, "overflow error\n");
633  sr = sc_rn(base_dup(b));
634  }
635  TRY
636  {
637  pips_debug(8, "compute the convex hull...\n");
638  sr = region_sc_convex_hull(s1, s2);
639  ifdebug(8)
640  {
641  pips_debug(8, "cute convex hull:\n");
642  sc_syst_debug(sr);
643  }
644 
645  pips_debug(8, "eliminate redudances...\n");
646  sc_nredund(&sr);
647  ifdebug(8)
648  {
649  pips_debug(8, "after redundancy elimination:\n");
650  sc_syst_debug(sr);
651  }
652 
654  }
655 
656  /* to avoid problems in case of overflow error */
657  appr = is_approximation_may;
658 
659  /* if we want to preserve must approximations, then we must find the
660  * approximation of the resulting region ;
661  * it may depend on the approximations of the initial regions, and on
662  * the relations between the two initial systems of constraints */
663 
664  if(sc_rn_p(sr))
665  {
666  pips_debug(1, "sr sc_rn (maybe due to an overflow error)\n");
667 
668  if (op_statistics_p())
669  {
670  if ((app1 == is_approximation_exact) &&
671  (app2 == is_approximation_exact))
673  else
674  if (!((app1 == is_approximation_may)
675  && (app2 == is_approximation_may)))
677  nb_umust_sc_rn++;
678  }
679 
680  /* we return a whole array region */
681  appr = is_approximation_may;
682  reg = region_dup(r1);
683  sc_rm(region_system(reg));
684  region_system_(reg) = newgen_Psysteme(sr);
685  region_approximation_tag(reg) = appr;
687  ifdebug(8)
688  {
689  pips_debug(8, "final region : \n");
690  print_region(reg);
691  }
692  return(reg);
693  }
694  else
695  {
696  if(!must_regions_p())
697  {
698  pips_debug(8, "may regions\n");
699  appr = is_approximation_may;
700  }
701  else
702  {
703  switch (app1)
704  {
706 
707  switch (app2)
708  {
709  case is_approximation_exact: /* U_must(must, must) */
710  /* si enveloppe convexe (s1, s2) exacte must sinon may */
712  {
713  pips_debug(8,"exact convex hull\n");
714  appr = is_approximation_exact;
715  }
716  else
717  {
718  pips_debug(8,"non exact convex hull\n");
719  appr = is_approximation_may;
720  }
721  if (op_statistics_p())
722  {
724  if (appr == is_approximation_exact)
726  }
727  break;
728 
729  case is_approximation_may: /* U_must(must,may) */
730  if(sc_inclusion_p_ofl(s2,s1))
731  appr = is_approximation_exact;
732  else
733  appr = is_approximation_may;
734  if (op_statistics_p())
735  {
737  if (appr == is_approximation_exact)
739  }
740  break;
741  }
742  break;
744 
745  switch (app2)
746  {
747  case is_approximation_exact: /* U_must(may,must) */
748  if(sc_inclusion_p_ofl(s1,s2))
749  appr = is_approximation_exact;
750  else
751  appr = is_approximation_may;
752  if (op_statistics_p())
753  {
755  if (appr == is_approximation_exact)
757  }
758  break;
760  appr = is_approximation_may;
761  break;
762  }
763  break;
764  }
765  }
766  }
767  reg = copy_effect(r1);
768  sc_rm(region_system(reg));
769  region_system_(reg) = newgen_Psysteme(sr);
770  region_approximation_tag(reg) = appr;
771  }
772 
773  ifdebug(8)
774  {
775  pips_debug(8, "final region : \n");
776  print_region(reg);
777  pips_assert("reg is consistent", effect_consistent_p(reg));
778  }
779 
780  return(reg);
781 
782 }
783 
784 
785 /* static effect regions_may_convex_hull(region r1,r2)
786  * input : two "effect" representing two regions.
787  * output : an effect, which predicate is the convex hull of the predicates
788  * of the initial regions, and which approximation is function of
789  * the approximations of the original regions
790  * and, in some cases, of the relations between the two initial
791  * predicates.
792  * modifies : the basis of the predicates of r1 and r2
793  * comment : always computes the convex hull, even if it leads to a may
794  * approximation.
795  */
797 {
798  /* region is a renaming of effect */
799  region reg = r1; /* result */
800 
801  if(!store_effect_p(r1) || !store_effect_p(r2)) {
802  ifdebug(1) {
803  /* Consistency check on regions for action kinds environment
804  and type declaration which should be put in a specific
805  function to enlarge region consistency checks. */
806  action a1 = effect_action(r1);
808  action a2 = effect_action(r2);
810  descriptor d1 = effect_descriptor(r1);
811  descriptor d2 = effect_descriptor(r2);
812  entity e1 = effect_variable(r1);
813  entity e2 = effect_variable(r2);
814 
815  pips_assert("r1 and r2 have the same action",
816  action_tag(a1)==action_tag(a2));
817  pips_assert("r1 and r2 have the same action kind",
818  action_kind_tag(ak1)==action_kind_tag(ak2));
819  pips_assert("r1 and r2 refers to the same variable",
820  e1==e2);
821  pips_assert("r1 and r2 have no descriptor",
823  }
824 
825  reg = copy_effect(r1);
826  } else {
827  Psysteme s1 = region_system(r1);
828  Psysteme s2 = region_system(r2);
829  Psysteme sr;
830  tag app1 = region_approximation_tag(r1);
831  tag app2 = region_approximation_tag(r2);
832  tag appr = is_approximation_may;
833 
834  pips_assert("systems not undefined\n",
835  !(SC_UNDEFINED_P(s1) || SC_UNDEFINED_P(s2)));
836 
837  ifdebug(8)
838  {
839  pips_debug(8, "initial systems\n");
840  sc_syst_debug(s1);
841  sc_syst_debug(s2);
842  }
843 
844  /* sc_empty : no part of the array is accessed */
845  if (sc_empty_p(s1) && sc_empty_p(s2))
846  {
847  pips_debug(8, "s1 and s2 sc_empty\n");
848  reg = region_dup(r1);
850  return(reg);
851  }
852 
853  if (sc_empty_p(s1)) {
854  pips_debug(8, "s1 sc_empty\n");
855  reg = region_dup(r1);
856  sc_rm(region_system(reg));
859  return(reg);
860  }
861 
862  if (sc_empty_p(s2))
863  {
864  pips_debug(8, "s2 sc_empty\n");
865  reg = region_dup(r1);
867  return(reg);
868  }
869 
870  /* sc_rn : the entire array is accessed */
871  if (sc_rn_p(s1) && sc_rn_p(s2))
872  {
873  pips_debug(8, "s1 and s2 sc_rn\n");
874  reg = region_dup(r1);
876  return(reg);
877  }
878 
879  if (sc_rn_p(s1))
880  {
881  pips_debug(8, "s1 sc_rn\n");
882  reg = region_dup(r1);
884  return(reg);
885  }
886 
887  if (sc_rn_p(s2))
888  {
889  pips_debug(8, "s2 sc_rn\n");
890  reg = region_dup(r1);
893  return(reg);
894  }
895 
896  /* otherwise, we have to compute the convex-hull of the two predicates */
897  if (op_statistics_p()) nb_umay++;
898 
899  sr = region_sc_convex_hull(s1, s2);
900  sc_nredund(&sr);
901 
902  /* if we want to preserve must approximations, then we must find the
903  * approximation of the resulting region ;
904  * it may depend on the approximations of the initial regions, on the
905  * precision
906  * (must union or may union), and on the relations between the two initial
907  * systems of constraints */
908 
909  if(sc_rn_p(sr))
910  {
912  action acr = region_action(r1);
913 
914  pips_debug(1,"sr sc_rn (maybe due to an overflow error)\n");
915 
916  if (op_statistics_p())
917  {
918  if (approximation_and(app1,app2) == is_approximation_exact)
920  }
921 
922  /* we return a whole array region */
923  appr = is_approximation_may;
924  reg = reference_whole_region(refr, acr);
926  ifdebug(8)
927  {
928  pips_debug(8, "final region : \n");
929  print_region(reg);
930  }
931  sc_rm(sr);
932  sr = NULL;
933  return(reg);
934  }
935  else
936  {
937  if(!must_regions_p())
938  {
939  pips_debug(8,"may regions\n");
940  appr = is_approximation_may;
941  }
942  else
943  {
944  if ((app1 == is_approximation_exact) &&
945  (app2 == is_approximation_exact))
946  {
947  /* U_may(must,must) */
948  /* si s1 == s2 (ie repre'sentent le me^me ensemble)
949  * alors must sinon may */
950  if (sc_equal_p_ofl(s1,s2))
951  appr = is_approximation_exact;
952  else
953  appr = is_approximation_may;
954  }
955  else
956  appr = is_approximation_may;
957  }
958  }
959  reg = region_dup(r1);
960  sc_rm(region_system(reg));
961  region_system_(reg) = newgen_Psysteme(sr);
962  region_approximation_tag(reg) = appr;
963 
964  if (op_statistics_p())
965  {
966  if (approximation_and(app1,app2) == is_approximation_exact)
967  {
969  if (appr == is_approximation_exact) nb_umay_must++;
970  }
971  }
972  }
973 
974  ifdebug(8)
975  {
976  pips_debug(8, "final region : \n");
977  print_region(reg);
978  }
979 
980  return(reg);
981 }
982 
983 /*static Psysteme region_sc_convex_hull(Psysteme ps1, ps2)
984  * input : two systems of constraints
985  * output : another system of constraints representing their convex
986  * hull.
987  * modifies : the bases of ps1 and ps2 : they are changed to their union,
988  * and reordered.
989  * comment : same as transformer_convex_hulls, except for the type of the
990  * arguments, and the reordering of the bases.
991  */
993 {
994  /* FI->BC: beware of callers that do not perform
995  simplifications. Observed on Regions/chopped_square24.c where two
996  equalities are encoded as four inequalities because a constant is
997  divided by two. Maybe a function similar to
998  expression_to_transformer should be used to analyze subscript
999  expressions, if it is not already the case. */
1000  return cute_convex_union(ps1, ps2);
1001 }
1002 
1003 /* Inclusion test :
1004  */
1005 
1006 /**
1007  returns true if c1 is included into c2, false otherwise.
1008  returns false if c1 may only be included into c2.
1009 
1010  @param exact_p target is set to true if the result is exact, false otherwise.
1011 
1012  In fact, this parameter would be useful only if there are overflows during
1013  the systems inclusion test. But it is not currently used.
1014  */
1016  cell c2, descriptor d2,
1017  bool * exact_p)
1018 {
1019  bool res = true; /* default result */
1020  *exact_p = true;
1021 
1022  bool concrete_locations_p = true;
1023 
1024  if (cells_combinable_p(c1, c2))
1025  {
1026  bool c1_abstract_location_p = cell_abstract_location_p(c1);
1027  bool c2_abstract_location_p = cell_abstract_location_p(c2);
1028 
1029  if (c1_abstract_location_p || c2_abstract_location_p)
1030  {
1031  entity e1 = cell_entity(c1);
1032  entity e2 = cell_entity(c2);
1033  bool heap1_context_sensitive_p = c1_abstract_location_p && entity_flow_or_context_sentitive_heap_location_p(e1);
1034  bool heap2_context_sensitive_p = c2_abstract_location_p && entity_flow_or_context_sentitive_heap_location_p(e2);
1035 
1036  if (heap1_context_sensitive_p && heap2_context_sensitive_p)
1037  {
1038  concrete_locations_p = true;
1039  }
1040  else
1041  {
1042  entity al_max = abstract_locations_max(e1, e2);
1043  res = same_entity_p(e2, al_max);
1044  concrete_locations_p = false;
1045  }
1046  }
1047 
1048  if (concrete_locations_p)
1049  {
1050  /* we have combinable concrete locations or assimilated (context sensitive heap locations) */
1051  /* they intersect if their descriptors intersection is not empty */
1052 
1053  Psysteme sc1 = descriptor_convex(d1);
1054  Psysteme sc2 = descriptor_convex(d2);
1055 
1056  /* if one of the systems is unfeasible, the result is false and exact */
1057  if (sc_empty_p(sc1) || sc_empty_p(sc2))
1058  {
1059  res = false;
1060  }
1061  /* if one of the systems is not constrained, the result is true and exact */
1062  else if (sc_rn_p(sc2))
1063  {
1064  res = true;
1065  }
1066  else if (sc_rn_p(sc1))
1067  {
1068  res = true;
1069  }
1070  else
1071  {
1072  res = sc_inclusion_p(sc1, sc2);
1073  }
1074  }
1075  }
1076  else
1077  {
1078  res = false;
1079  }
1080  return res;
1081 }
1082 
1083 
1084 /* Intersection :
1085  */
1086 
1087 /* list region_intersection(region reg1, reg2)
1088  * input : two regions
1089  * output : a list of regions containing their difference.
1090  * the action of the resulting regions is the action
1091  * of the first region (reg1).
1092  * modifies : nothing.
1093  * comment : not debugged, because not yet used. (funny, FC;-) (still up_to-date ? BC)
1094  */
1095 list /* of region */
1097 {
1098  list l_res = NIL;
1099 
1100  if(store_effect_p(reg1) && store_effect_p(reg2)) {
1101  /* FI: Standard procedure for memory/store regions */
1102  Psysteme sc1 = region_system(reg1);
1103  Psysteme sc2 = region_system(reg2);
1104  tag app1 = region_approximation_tag(reg1);
1105  tag app2 = region_approximation_tag(reg2);
1106  tag app_res = approximation_and(app1,app2);
1107 
1108  ifdebug(3){
1109  pips_debug(3,"initial regions :\n");
1110  print_region(reg1);
1111  print_region(reg2);
1112  }
1113 
1114  if (anywhere_effect_p(reg1))
1115  {
1116  // functions that can be pointed by effect_dup_func:
1117  // simple_effect_dup
1118  // region_dup
1119  // copy_effect
1120  region reg = (*effect_dup_func)(reg2);
1121  /* memory leak? */
1123  region_approximation_tag(reg)= app_res;
1124  l_res = region_to_list(reg);
1125  }
1126  else if (anywhere_effect_p(reg2))
1127  {
1128  // functions that can be pointed by effect_dup_func:
1129  // simple_effect_dup
1130  // region_dup
1131  // copy_effect
1132  region reg = (*effect_dup_func)(reg1);
1133  region_approximation_tag(reg)= app_res;
1134  l_res = region_to_list(reg);
1135  }
1136  else
1137  {
1138 
1139  /* Automatic variables read in a CATCH block need to be declared volatile as
1140  * specified by the documentation*/
1141  region volatile reg;
1142  bool feasible = true;
1143 
1144 
1145  /* if one of the regions is unfeasible, return an empty list */
1146  if (sc_empty_p(sc1) || sc_empty_p(sc2))
1147  {
1148  pips_debug(8, "reg1 or reg 2 sc_empty");
1149  return(l_res);
1150  }
1151 
1152 
1153  /* else return a list containing a region which predicate is the
1154  * intersection of the two initial predicates, and which approximation
1155  * is the "logical" and of the initial approximations.
1156  */
1157  reg = region_dup(reg1);
1158  region_sc_append_and_normalize(reg,sc2,2); /* could be some other level? */
1159 
1161  {
1162  pips_debug(3, "overflow error \n");
1163  feasible = true;
1165  }
1166  TRY
1167  {
1169  FWD_OFL_CTRL, true);
1171  }
1172 
1173  if (feasible)
1174  {
1175  region_approximation_tag(reg)= app_res;
1176  l_res = region_to_list(reg);
1177  }
1178  else
1179  {
1180  region_free(reg);
1181  l_res = NIL;
1182  }
1183  }
1184  } else {
1185  /* FI: extensions for the new action kinds on environment and
1186  * store. Since they are combinable, reg1==reg2 and hence their
1187  * intersection is equal to reg1 */
1188  effect reg = copy_effect(reg1);
1189  l_res = CONS(EFFECT, reg, NIL);
1190  }
1191 
1192  ifdebug(3)
1193  {
1194  pips_debug(3,"final region :\n");
1195  print_regions(l_res);
1196  }
1197  return(l_res);
1198 }
1199 
1200 
1202  cell c2, descriptor d2,
1203  bool * exact_p)
1204 {
1205  bool res = true;
1206 
1207  /* default safe result */
1208  bool concrete_locations_p = true;
1209 
1210  if (cells_combinable_p(c1, c2))
1211  {
1212  bool c1_abstract_location_p = cell_abstract_location_p(c1);
1213  bool c2_abstract_location_p = cell_abstract_location_p(c2);
1214 
1215  if (c1_abstract_location_p || c2_abstract_location_p)
1216  {
1217  entity e1 = cell_entity(c1);
1218  entity e2 = cell_entity(c2);
1219  bool heap1_context_sensitive_p = c1_abstract_location_p && entity_flow_or_context_sentitive_heap_location_p(e1);
1220  bool heap2_context_sensitive_p = c2_abstract_location_p && entity_flow_or_context_sentitive_heap_location_p(e2);
1221 
1222  if (heap1_context_sensitive_p && heap2_context_sensitive_p)
1223  {
1224  concrete_locations_p = true;
1225  }
1226  else
1227  {
1228  concrete_locations_p = false;
1229  res = true;
1230  *exact_p = false; /* can it be true if we have two null locations ?*/
1231  }
1232  }
1233 
1234  if (concrete_locations_p)
1235  {
1236  /* we have combinable concrete locations or assimilated (context sensitive heap locations) */
1237  /* they intersect if their descriptors intersection is not empty */
1238 
1239  Psysteme sc1 = descriptor_convex(d1);
1240  Psysteme sc2 = descriptor_convex(d2);
1241 
1242 
1243  /* if one of the systems is unfeasible, the result is false and exact */
1244  if (sc_empty_p(sc1) || sc_empty_p(sc2))
1245  {
1246  pips_debug(8, "d1 or d2 sc_empty");
1247  res = false;
1248  *exact_p = true;
1249  }
1250 
1251  /* if one of the systems is not constrained, the result is true and exact */
1252  else if (sc_rn_p(sc1) || sc_rn_p(sc2))
1253  {
1254  pips_debug(8, "d1 or d2 sc_rn\n");
1255  res = true;
1256  *exact_p = true;
1257  }
1258  else
1259  {
1260  /* else test the feasibility of the systems intersection */
1261  Psysteme sc = cell_system_sc_append_and_normalize(sc_dup(sc1),sc2,2); /* could be some other level? */
1262 
1264  {
1265  pips_debug(3, "overflow error \n");
1266  res = true;
1267  *exact_p = false;
1268  }
1269  TRY
1270  {
1272  *exact_p = true;
1274  sc_rm(sc);
1275  }
1276  }
1277  }
1278  }
1279  else
1280  {
1281  res = false;
1282  *exact_p = true;
1283  }
1284  return res;
1285 }
1286 
1287 /* list region_entities_intersection(region reg1, reg2)
1288  * input : two regions
1289  * output : a mere copy of the first region.
1290  * modifies : nothing.
1291  * comment : We assume that both regions concern the same entity or that
1292  one of them is an anywhere effect.
1293  */
1295 {
1296  region reg;
1297 
1298  if (anywhere_effect_p(r1))
1299  {
1300  // functions that can be pointed by effect_dup_func:
1301  // simple_effect_dup
1302  // region_dup
1303  // copy_effect
1304  reg = (*effect_dup_func)(r2);
1306  }
1307  else
1308  reg = region_dup(r1);
1309 
1310  return(CONS(EFFECT, reg, NIL));
1311 }
1312 
1313 
1314 /* 3- Difference :
1315  */
1316 
1318  tag app, bool super_or_sub);
1319 
1320 /* list region_sup_difference(effect reg1, reg2)
1321  * input : two regions
1322  * output : a list of regions containing their sup_difference.
1323  * the action of the resulting regions is the action
1324  * of the first region (reg1).
1325  * modifies :
1326  * comment :
1327  */
1329 {
1330  list l_reg = NIL;
1331  if(store_effect_p(reg1) && store_effect_p(reg2)) {
1332  /* This is the traditional case, limited to store/memory regions */
1333  Psysteme sc1, sc2;
1334  /* Automatic variables read in a CATCH block need to be declared volatile as
1335  * specified by the documentation*/
1336  volatile tag app1 = region_approximation_tag(reg1);
1337  volatile tag app2 = region_approximation_tag(reg2);
1338 
1339  /* approximation of the resulting regions if the difference is exact */
1340  volatile tag app = -1;
1341  region reg;
1342 
1343 
1344  /* At this point, we are sure that we have array regions */
1345 
1346  ifdebug(6)
1347  {
1348  pips_debug(6, "Initial regions : \n");
1349  fprintf(stderr,"\t reg1 :\n");
1350  print_region(reg1);
1351  fprintf(stderr,"\t reg2 :\n");
1352  print_region(reg2);
1353  }
1354 
1355  if (anywhere_effect_p(reg1))
1356  {
1358  l_reg = region_to_list(reg);
1359  }
1360  else if (anywhere_effect_p(reg2))
1361  {
1362  // functions that can be pointed by effect_dup_func:
1363  // simple_effect_dup
1364  // region_dup
1365  // copy_effect
1366  reg = (*effect_dup_func)(reg1);
1367  l_reg = region_to_may_region_list(reg);
1368  }
1369  else
1370  {
1371 
1372  /* particular cases first */
1373  sc1 = region_system(reg1);
1374  sc2 = region_system(reg2);
1375 
1376  /* nothing minus (something or nothing) = nothing */
1377  if (sc_empty_p(sc1))
1378  return l_reg;
1379 
1380  /* something minus nothing = something */
1381  if (sc_empty_p(sc2))
1382  {
1383  l_reg = region_to_list(region_dup(reg1));
1384  return l_reg;
1385  }
1386 
1387 
1388  /* everything minus everything
1389  * = everything (may) for an array and if app2 = may,
1390  * = nothing otherwise */
1391  if (sc_rn_p(sc1) && sc_rn_p(sc2))
1392  {
1393  if (app2 == is_approximation_may)
1394  l_reg = region_to_may_region_list(region_dup(reg1));
1395  return l_reg;
1396  }
1397 
1398  /* something minus everything must = nothing */
1399  /* something minus everything may = something may*/
1400  if (sc_rn_p(sc2) )
1401  {
1402  if (app2 == is_approximation_may)
1403  l_reg = region_to_may_region_list(region_dup(reg1));
1404  return l_reg;
1405  }
1406 
1407 
1408  /* general case */
1409  if (op_statistics_p()) nb_dsup++;
1410 
1411  switch (app2)
1412  {
1413  case is_approximation_exact :
1414  if (app1 == is_approximation_exact)
1415  {
1416  app = is_approximation_exact;
1418  }
1419  else
1420  app = is_approximation_may;
1422  {
1423  pips_debug(1, "overflow error\n");
1424  app = app1;
1425  l_reg = region_to_may_region_list(region_dup(reg1));
1426  }
1427  TRY
1428  {
1429  Pdisjunct disjonction;
1430  disjonction = sc_difference(sc1,sc2);
1432  (disjonction, reg1, app, SUPER);
1434  }
1435 
1436  if (op_statistics_p() && app == is_approximation_exact &&
1439  nb_dsup_must++;
1440 
1441  break;
1442 
1443  case is_approximation_may :
1445  {
1446  pips_debug(1, "overflow error\n");
1447  app = is_approximation_may;
1448  }
1449  TRY
1450  {
1451  if (app1 == is_approximation_exact)
1452  {
1454  if (sc_intersection_empty_p_ofl(sc1,sc2))
1455  {
1456  app = is_approximation_exact;
1457  if (op_statistics_p()) nb_dsup_must++;
1458  }
1459  else app = is_approximation_may;
1460  }
1461  else
1462  app = is_approximation_may;
1464  }
1465  reg = region_dup(reg1);
1467  l_reg = CONS(EFFECT, reg, NIL);
1468  break;
1469  }
1470  }
1471  } else {
1472  /* FI: Here we do need to extend the concept to environment and
1473  * type declaration effect. I
1474  * assume that the effect variable is the same, else the
1475  * difference would be meaningless. If the action_kind is the
1476  * same, then the difference must be empty, as I hope is the case
1477  * for scalara variables in the above code. Else r1 is unchanged. */
1478  action a1 = effect_action(reg1);
1479  action a2 = effect_action(reg2);
1482  if(action_kind_tag(ak1)==action_kind_tag(ak2)) {
1483  /* The output list is empty and stays empty */
1484  l_reg = NIL; // redundant, but improves readability
1485  }
1488  pips_internal_error("Unexpected mix of action kinds.");
1489  else {
1490  /* reg1 is not modified by reg2 */
1491  /* This also could be considered an internal error */
1492  effect reg = copy_effect(reg1);
1493  l_reg = CONS(EFFECT, reg, NIL);
1494  }
1495  }
1496 
1497  ifdebug(6)
1498  {
1499  pips_debug(6, "Resulting regions : \n");
1500  fprintf(stderr,"\t l_reg :\n");
1501  print_regions(l_reg);
1502  }
1503 
1504  return l_reg;
1505 }
1506 
1507 
1508 /* list region_inf_difference(region reg1, reg2)
1509  * input : two regions
1510  * output : a list of regions containing their inf_difference.
1511  * the action of the resulting regions is the action
1512  * of the first region (reg1).
1513  * modifies :
1514  * comment : not debugged because not yet used.
1515  */
1517 {
1518  Psysteme sc1, sc2;
1519  /* approximation of the resulting region if the difference is exact */
1520  volatile tag app = region_approximation_tag(reg1);
1521 
1522  list l_res = NIL;
1523 
1524  ifdebug(6)
1525  {
1526  pips_debug(6, "Initial regions : \n");
1527  fprintf(stderr,"\t reg1 :\n");
1528  print_region(reg1);
1529  fprintf(stderr,"\t reg2 :\n");
1530  print_region(reg2);
1531  }
1532 
1533  if (anywhere_effect_p(reg1) || anywhere_effect_p(reg2))
1534  return NIL;
1535 
1536  /* particular cases first */
1537  sc1 = region_system(reg1);
1538  sc2 = region_system(reg2);
1539 
1540  /* nothing minus something (or nothing) = nothing */
1541  if (sc_empty_p(sc1))
1542  return l_res;
1543 
1544  /* something minus nothing = something */
1545  if (sc_empty_p(sc2))
1546  {
1547  l_res = region_to_list(region_dup(reg1));
1548  return l_res;
1549  }
1550 
1551  /* everything minus everything = nothing */
1552  if (sc_rn_p(sc1) && sc_rn_p(sc2))
1553  return l_res;
1554 
1555  /* something minus everything = nothing */
1556  if (sc_rn_p(sc2) )
1557  return l_res;
1558 
1559  /* general case */
1560  if (op_statistics_p())
1561  {
1562  nb_dinf++;
1564  }
1565 
1567  {
1568  /* We cannot compute the under-approximation of the difference:
1569  * we must assume that it is the empty set
1570  */
1571  pips_debug(1, "overflow error\n");
1572  app = is_approximation_may;
1573  l_res = NIL;
1574  }
1575  TRY
1576  {
1577  Pdisjunct disjonction;
1578  disjonction = sc_difference(sc1,sc2);
1579  l_res = disjunction_to_list_of_regions(disjonction, reg1, app, SUPER);
1581  }
1582 
1583  if (op_statistics_p() && !ENDP(l_res))
1584  if (app == is_approximation_exact) nb_dinf_must++;
1585 
1586  ifdebug(6)
1587  {
1588  pips_debug(6, "Resulting regions : \n");
1589  fprintf(stderr,"\t l_res :\n");
1590  print_regions(l_res);
1591  }
1592 
1593  return l_res;
1594 }
1595 
1596 
1597 
1598 
1599 /* static Psysteme disjunction_to_region_sc(Pdisjunct disjonction, bool *b)
1600  * input : a disjunction representing the union of several Psystemes
1601  * output : a Psysteme representing the convex_hull of the disjunction
1602  * of predicates.
1603  * modifies : frees the input disjuntion.
1604  * comment : Exactness is now tested outside the loop.
1605  */
1606 static Psysteme disjunction_to_region_sc(Pdisjunct disjonction, bool *p_exact)
1607 {
1608  Psysteme ps_res = SC_UNDEFINED;
1609 
1610  pips_assert("disjunction not undefined\n", !(disjonction == DJ_UNDEFINED));
1611 
1612  ps_res = disjonction->psys;
1613 
1614  /* no need to compute the hull if there is only one system in the
1615  * disjunction */
1616  if (disjonction->succ != NULL)
1617  {
1618  Ppath chemin;
1619  Pdisjunct disj_tmp;
1620 
1621 
1622  for(disj_tmp = disjonction->succ;
1623  disj_tmp != DJ_UNDEFINED;
1624  disj_tmp = disj_tmp->succ)
1625  {
1626  ps_res = region_sc_convex_hull(ps_res, disj_tmp->psys);
1627  }
1628  /* Exactness test */
1629  chemin = pa_make(ps_res,disjonction);
1630  *p_exact = !(pa_feasibility_ofl_ctrl(chemin, FWD_OFL_CTRL));
1631  disjonction = dj_free(disjonction);
1632  chemin->pcomp = disjonction;
1633  chemin = pa_free1(chemin);
1634  }
1635  else
1636  {
1637  *p_exact = true;
1638  /* do not freee the inner Psysteme: it is the result */
1639  disjonction = dj_free1(disjonction);
1640  }
1641  return ps_res;
1642 }
1643 
1644 
1645 /* static list disjuction_to_list_of_regions(disjonction, reg, app, super_or_sub)
1646  * input : a disjunction and a region
1647  * output : a list of regions which contains a region identical
1648  * with reg, but for the predicate which is given by the
1649  * Psystemes of the disjunction and the approximation which depends
1650  * on the exactness of the representation. The latter is either a sub
1651  * or a super approximation of the disjonction, depending on the value
1652  * of the bool super_or_sub.
1653  * modifies : the disjunction is freed by the call to disjunction_to_region_sc.
1654  * comment : app is the tag if the disjunction is exact;
1655  */
1657  tag app,
1658  bool super_or_sub __attribute__ ((unused)))
1659 {
1660  Psysteme ps;
1661  region reg_ps;
1662  list l_reg = NIL;
1663  bool exact = true;
1664  Psysteme ps_tmp;
1665 
1666  ps_tmp = disjunction_to_region_sc(disjonction, &exact);
1667 
1668  /* computation of a subapproximation */
1669  if (!exact && SUB)
1670  {
1671  sc_rm(ps_tmp);
1672  }
1673  /* computation of the exact representation or of a super approximation */
1674  else
1675  {
1676  /* build_sc_nredund_2pass(&ps_tmp); */
1677  ps = ps_tmp;
1678 
1679  if (!sc_empty_p(ps))
1680  {
1681  reg_ps = region_dup(reg);
1682  sc_rm(region_system(reg_ps));
1683  region_system_(reg_ps) = newgen_Psysteme(ps);
1684  app = (exact && (app == is_approximation_exact))?
1686  region_approximation_tag(reg_ps) = app;
1687  l_reg = CONS(EFFECT, reg_ps, l_reg);
1688  }
1689  else
1690  sc_rm(ps);
1691 
1692  }
1693  return l_reg;
1694 }
1695 
1696 
1697 
1698 
1699 
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
action copy_action(action p)
ACTION.
Definition: effects.c:77
bool effect_consistent_p(effect p)
Definition: effects.c:457
approximation make_approximation(enum approximation_utype tag, void *val)
Definition: effects.c:176
effect copy_effect(effect p)
EFFECT.
Definition: effects.c:448
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
bool entity_flow_or_context_sentitive_heap_location_p(entity e)
entity abstract_locations_max(entity al1, entity al2)
eturns the smallest abstract location set greater than or equalt to al1 and al2.
entity entity_locations_max(entity al1, entity al2)
Here, entity al1 and entity al2 can be program variables.
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
Pbase base_union(Pbase b1, Pbase b2)
Pbase base_union(Pbase b1, Pbase b2): compute a new basis containing all elements of b1 and all eleme...
Definition: base.c:428
void sc_syst_debug(Psysteme s)
constraint_to_text.c
Pdisjunct dj_free(Pdisjunct in_dj)
Pdisjunct dj_free( (Pdisjunct) in_dj ) AL 31/05/94 w - 1 depth free of input disjunction.
Definition: disjunct.c:69
Pdisjunct dj_free1(Pdisjunct in_dj)
Pdisjunct dj_free1( (Pdisjunct) in_dj ) AL 31/05/94 1st depth free of input disjunction.
Definition: disjunct.c:84
#define region_any_reference(reg)
To be avoided.
#define region_action(reg)
#define debug_region_consistency(reg)
#define region_system_(reg)
#define region_system(reg)
#define region_empty_p(reg)
#define region_approximation_tag(reg)
#define region
simulation of the type region
list region_sup_difference(region reg1, region reg2)
list region_sup_difference(effect reg1, reg2) input : two regions output : a list of regions containi...
list region_entities_intersection(region r1, region r2)
list region_entities_intersection(region reg1, reg2) input : two regions output : a mere copy of the ...
static int nb_dinf_must
bool convex_cells_intersection_p(cell c1, descriptor d1, cell c2, descriptor d2, bool *exact_p)
static int nb_umust_must_may
list region_must_union(region r1, region r2)
computes the must union of two combinable array regions
static list disjunction_to_list_of_regions(Pdisjunct disjonction, effect reg, tag app, bool super_or_sub)
3- Difference :
static effect regions_may_convex_hull(region f1, region f2)
static effect regions_may_convex_hull(region r1,r2) input : two "effect" representing two regions.
#define SUPER
static int nb_umust_must_may_must
list RegionsSupDifference(list l1, list l2, bool(*difference_combinable_p)(effect, effect))
list RegionsSupDifference(list l1, l2) input : two lists of regions output : a list of region,...
effect regions_must_convex_hull(region f1, region f2)
1- Union :
void print_dinf_statistics(char *mod_name, char *prefix)
list region_inf_difference(region reg1, region reg2)
list region_inf_difference(region reg1, reg2) input : two regions output : a list of regions containi...
static int nb_dsup
void reset_binary_op_statistics()
binary_operators.c
list RegionsMustUnion(list l1, list l2, bool(*union_combinable_p)(effect, effect))
list RegionsMustUnion(list l1, list l2, union_combinable_p) input : two lists of regions output : a l...
void print_umay_statistics(char *mod_name, char *prefix)
static int nb_dsup_pot_must
static int nb_umust_must_must_must
static int nb_umust_sc_rn
void print_dsup_statistics(char *mod_name, char *prefix)
#define SUB
list region_intersection(region reg1, region reg2)
Intersection :
void print_umust_statistics(char *mod_name, char *prefix)
static Psysteme region_sc_convex_hull(Psysteme ps1, Psysteme ps2)
tatic Psysteme region_sc_convex_hull(Psysteme ps1, ps2) input : two systems of constraints output : a...
list RegionsMayUnion(list l1, list l2, bool(*union_combinable_p)(effect, effect))
list RegionsMayUnion(list l1, list l2, union_combinable_p) input : two lists of regions output : a li...
list region_may_union(region r1, region r2)
computes the may union of two combinable array regions
list RegionsInfDifference(list l1, list l2, bool(*difference_combinable_p)(effect, effect))
list RegionsInfDifference(list l1, l2) input : two lists of regions output : a list of region,...
static int nb_dinf
static int nb_umust_must_must
static int nb_umay_must
list RegionsEntitiesIntersection(list l1, list l2, bool(*intersection_combinable_p)(effect, effect))
list RegionsEntitiesIntersection(list l1,l2, bool (*intersection_combinable_p)(effect,...
list region_union(region r1, region r2, bool must_p)
computes the must or may union of two combinable array regions depending on the value of must_p
list RegionsEntitiesInfDifference(list l1, list l2, bool(*difference_combinable_p)(effect, effect))
list RegionsEntitiesInfDifference(list l1, l2) input : two lists of regions output : a list of region...
static int nb_umay_must_must
bool convex_cells_inclusion_p(cell c1, descriptor d1, cell c2, descriptor d2, bool *exact_p)
Inclusion test :
static Psysteme disjunction_to_region_sc(Pdisjunct disjonction, bool *p_exact)
static Psysteme disjunction_to_region_sc(Pdisjunct disjonction, bool *b) input : a disjunction repres...
static int nb_umust
static int nb_umay
list RegionsIntersection(list l1, list l2, bool(*intersection_combinable_p)(effect, effect))
list RegionsIntersection(list l1,l2, bool (*intersection_combinable_p)(effect, effect)) input : outpu...
static int nb_dsup_must
static int nb_dinf_pot_must
list region_to_may_region_list(effect)
bool must_regions_p(void)
void region_free(effect)
void print_regions(list)
list region_to_list(effect)
void region_sc_append_and_normalize(effect, Psysteme, int)
effect reference_whole_region(reference, action)
effect region_dup(effect)
Psysteme cell_system_sc_append_and_normalize(Psysteme, Psysteme, int)
bool op_statistics_p(void)
list regions_to_nil_list(effect, effect)
list list_of_effects_generic_sup_difference_op(list, list, bool(*)(effect, effect), list(*)(effect, effect))
list list_of_effects_generic_union_op(list, list, bool(*)(effect, effect), list(*)(effect, effect), list(*)(effect))
effect make_anywhere_effect(action)
list list_of_effects_generic_cells_inf_difference_op(list, list, bool(*)(effect, effect), list(*)(effect, effect))
void effect_to_may_effect(effect)
list list_of_effects_generic_intersection_op(list, list, bool(*)(effect, effect), list(*)(effect, effect))
list list_of_effects_generic_inf_difference_op(list, list, bool(*)(effect, effect), list(*)(effect, effect))
list list_of_effects_generic_cells_intersection_op(list, list, bool(*)(effect, effect), list(*)(effect, effect))
bool cells_combinable_p(cell, cell)
#define effect_approximation_tag(eff)
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
#define make_simple_effect(reference, action, approximation)
action_kind action_to_action_kind(action)
Without the consistency test, this function would certainly be inlined.
Definition: effects.c:1048
tag approximation_and(tag, tag)
tag approximation_and(tag t1, tag t2) input : two approximation tags.
Definition: effects.c:1198
bool effect_abstract_location_p(effect)
Definition: effects.c:280
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
bool store_effect_p(effect)
Definition: effects.c:1062
tag approximation_or(tag, tag)
tag approximation_or(tag t1, tag t2) input : two approximation tags.
Definition: effects.c:1213
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
bool cell_abstract_location_p(cell)
Definition: effects.c:273
entity cell_entity(cell)
Definition: effects.c:57
#define effect_undefined_p(x)
Definition: effects.h:615
@ is_action_kind_store
Definition: effects.h:237
#define approximation_tag(x)
Definition: effects.h:362
#define action_kind_tag(x)
Definition: effects.h:258
#define effect_action(x)
Definition: effects.h:642
#define effect_undefined
Definition: effects.h:614
#define action_tag(x)
Definition: effects.h:310
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_convex(x)
Definition: effects.h:601
#define descriptor_none_p(x)
Definition: effects.h:602
@ is_approximation_may
Definition: effects.h:341
@ is_approximation_exact
Definition: effects.h:343
#define effect_approximation(x)
Definition: effects.h:644
#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
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 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
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
#define UU
Definition: newgen_types.h:98
int f2(int off1, int off2, int w, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:1
Ppath pa_make(Psysteme in_ps, Pcomplist in_pcomp)
Package : C3/union Author : Arnauld LESERVOT (leservot(a)limeil.cea.fr) Date : Modified : 04 04 95 ...
Definition: path.c:53
bool pa_feasibility_ofl_ctrl(Ppath in_pa, int ofl_ctrl)
bool pa_feasibility_ofl_ctrl( (Ppath) in_pa, int ofl_ctrl) Returns true if the input path is possib...
Definition: path.c:309
Ppath pa_free1(Ppath in_pa)
Ppath pa_free1(Ppath pa) BA, AL 30/05/94 1 depth free.
Definition: path.c:102
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
#define print_region(x)
Definition: print.c:343
static const char * prefix
Psysteme cute_convex_union(Psysteme s1, Psysteme s2)
debug messages before calling the version in polyedre.
Definition: convex_hull.c:41
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
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_rn(Pbase b)
Psysteme sc_rn(Pbase b): build a Psysteme without constraints to define R^n, where n is b's dimension...
Definition: sc_alloc.c:336
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
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
bool sc_integer_feasibility_ofl_ctrl(Psysteme sc, int ofl_ctrl, bool ofl_res)
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
bool sc_intersection_empty_p_ofl(Psysteme ps1, Psysteme ps2)
bool sc_intersection_empty_p_ofl(ps1, ps2) input : two polyhedra output : true if their intersection ...
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
Pcomplist pcomp
Definition: union-local.h:20
Warning! Do not modify this file that is automatically generated!
Definition: union-local.h:3
Psysteme psys
Definition: union-local.h:4
struct Ssyslist * succ
Definition: union-local.h:5
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
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define sc_inclusion_p_ofl(ps1, ps2)
Definition: union-local.h:81
#define sc_inclusion_p(ps1, ps2)
Definition: union-local.h:80
#define sc_convex_hull_equals_union_p_ofl(conv_hull, ps1, ps2)
Definition: union-local.h:88
#define sc_equal_p_ofl(ps1, ps2)
Definition: union-local.h:84
#define DJ_UNDEFINED
Definition: union-local.h:12
#define sc_difference(ps1, ps2)
FOR BACKWARD COMPATIBILITY.
Definition: union-local.h:79
#define base_rm(b)
#define FWD_OFL_CTRL
#define base_dimension(b)
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300