PIPS
binary_operators.c
Go to the documentation of this file.
1 /*
2 
3  $Id: binary_operators.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* package generic effects : Be'atrice Creusillet 5/97
28  *
29  * File: binary_operators.c
30  * ~~~~~~~~~~~~~~~~~~~~~~~~
31  *
32  * This File contains generic binary operators for effects and lists of them.
33  *
34  */
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 #include "genC.h"
40 #include "linear.h"
41 #include "ri.h"
42 #include "effects.h"
43 #include "ri-util.h"
44 #include "effects-util.h"
45 #include "misc.h"
46 #include "properties.h"
47 #include "text.h"
48 #include "text-util.h"
49 
50 #include "effects-generic.h"
51 
52 
53 /******************************************** GENERIC BINARY OPERATORS ON EFFECTS */
54 
55 
56 /**
57  @brief returns the contribution of the union of eff1 and eff2 to
58  the result list of the generic binary operator.
59  beware: may modify eff1 and eff2
60 
61  @param[in] eff1_abstract_location_p is true if eff1 is an abstract location
62  ( put as a parameter because testing abstract locations is costly and is
63  better done outside loops when possible)
64  @param[in] eff2_abstract_location_p is true if eff2 is an abstract location
65  @param[out] eff1_still_combinable_p is a pointer to a bool which must be true
66  when entering the function, and stays true if eff1 may still be
67  combinable with other effects in the calling function
68  @param[out] eff2_still_combinable_p is a pointer to a bool which must be true
69  when entering the function, and stays true if eff2 may still be
70  combinable with other effects in the calling function
71  @param[in] concrete_effects_union_op computes the union of two effects on
72  concrete locations.
73  */
74 static list effects_generic_union_op(effect eff1, effect eff2,
75  bool eff1_abstract_location_p,
76  bool eff2_abstract_location_p,
77  bool *eff1_still_combinable_p,
78  bool *eff2_still_combinable_p,
79  list (*concrete_effects_union_op)(effect,effect))
80 {
81  list l_res = NIL;
82 
83  ifdebug(1)
84  pips_assert("eff1 and eff2 must be still combinable",
85  *eff1_still_combinable_p && *eff2_still_combinable_p);
86 
87  pips_debug_effect(8, "eff1: \n", eff1);
88  pips_debug_effect(8, "eff2: \n", eff2);
89 
90  if (eff1_abstract_location_p && eff2_abstract_location_p)
91  {
92  entity al1 = effect_entity(eff1);
93  entity al2 = effect_entity(eff2);
94 
95  if (same_entity_p(al1, al2)) /* currently most common case */
96  {
97  *eff1_still_combinable_p = false;
98  *eff2_still_combinable_p = false;
99  // functions that can be pointed by effect_dup_func:
100  // simple_effect_dup
101  // region_dup
102  // copy_effect
103  l_res = CONS(EFFECT, (*effect_dup_func)(eff1), l_res);
104  }
105  else
106  {
107  // the result is the max of the two abstract locations, which is one
108  // of them; we remove the lowest from it's list, and keep the
109  // highest for potential combination with another effect.
110  // There is no need to add it in the result list, since
111  // it will belong to the remnants of one of the initial list
112  // and as such be appended to the final result list.
113 
114  entity al_max = abstract_locations_max(al1, al2);
115  if (same_entity_p(al1, al_max))
116  {
117  /* *eff1_still_combinable_p = true; (redundant) */
118  *eff2_still_combinable_p = false;
119  }
120  else
121  {
122  ifdebug(1) pips_assert("combinable abstract locations: one of them is the max of both",
123  same_entity_p(al2, al_max));
124  *eff1_still_combinable_p = false;
125  /* *eff2_still_combinable_p = true; (redundant) */
126  }
127  }
128  }
129  else if (eff1_abstract_location_p) /* and eff2 concrete location */
130  {
131  /* *eff1_still_combinable_p = true; (redundant) */
132  *eff2_still_combinable_p = false;
133  }
134  else if (eff2_abstract_location_p) /* and eff1 concrete location */
135  {
136  *eff1_still_combinable_p = false;
137  /* *eff2_still_combinable_p = true; (redundant) */
138  }
139  else /* two concrete locations */
140  {
141  l_res = gen_nconc((*concrete_effects_union_op)(eff1,eff2), l_res);
142  *eff1_still_combinable_p = false;
143  *eff2_still_combinable_p = false;
144  }
145 
146  pips_debug_effects(8, "returning:\n", l_res);
147  return l_res;
148 }
149 
150 /**
151  @brief returns the contribution of the intersection of eff1 and eff2 to
152  the result list of the generic binary operator.
153  beware: may modify eff1 and eff2
154 
155  @param[in] eff1_abstract_location_p is true if eff1 is an abstract location
156  ( put as a parameter because testing abstract locations is costly and is
157  better done outside loops when possible)
158  @param[in] eff2_abstract_location_p is true if eff2 is an abstract location
159  @param[out] eff1_still_combinable_p is a pointer to a bool which must be true
160  when entering the function, and stays true if eff1 may still be
161  combinable with other effects in the calling function
162  @param[out] eff2_still_combinable_p is a pointer to a bool which must be true
163  when entering the function, and stays true if eff2 may still be
164  combinable with other effects in the calling function
165  @param[in] concrete_effects_intersection_op computes the union of two effects on
166  concrete locations.
167  */
168 static list effects_generic_intersection_op(effect eff1, effect eff2,
169  bool eff1_abstract_location_p,
170  bool eff2_abstract_location_p,
171  bool *eff1_still_combinable_p,
172  bool *eff2_still_combinable_p,
173  list (*concrete_effects_intersection_op)(effect,effect))
174 {
175  list l_res = NIL;
176 
177  ifdebug(1)
178  pips_assert("eff1 and eff2 must be still combinable",
179  *eff1_still_combinable_p && *eff2_still_combinable_p);
180 
181  pips_debug_effect(8, "eff1: \n", eff1);
182  pips_debug_effect(8, "eff2: \n", eff2);
183 
184 
185  if (eff1_abstract_location_p && eff2_abstract_location_p)
186  {
187  entity al1 = effect_entity(eff1);
188  entity al2 = effect_entity(eff2);
189 
190  if (same_entity_p(al1, al2)) /* currently most common case */
191  {
192  // functions that can be pointed by effect_dup_func:
193  // simple_effect_dup
194  // region_dup
195  // copy_effect
196  effect r = (*effect_dup_func)(eff1);
197  *eff1_still_combinable_p = false;
198  *eff2_still_combinable_p = false;
199  l_res = CONS(EFFECT, r, l_res);
200  }
201  else
202  {
203  entity al_max = abstract_locations_max(al1, al2);
204 
205  if (same_entity_p(al1, al_max))
206  {
207  // functions that can be pointed by effect_dup_func:
208  // simple_effect_dup
209  // region_dup
210  // copy_effect
211  effect r = (*effect_dup_func)(eff2);
212  /* *eff1_still_combinable_p = true; (redundant) */
213  *eff2_still_combinable_p = false;
214  l_res = CONS(EFFECT, r, l_res);
215  }
216  else
217  {
218  ifdebug(1) pips_assert("combinable abstract locations: one of them is the max of both",
219  same_entity_p(al2, al_max));
220  // functions that can be pointed by effect_dup_func:
221  // simple_effect_dup
222  // region_dup
223  // copy_effect
224  effect r = (*effect_dup_func)(eff1);
225  *eff1_still_combinable_p = false;
226  /* *eff2_still_combinable_p = true; (redundant) */
227  l_res = CONS(EFFECT, r, l_res);
228  }
229  }
230  }
231  else if (eff1_abstract_location_p) /* and r2 concrete location */
232  {
233  // functions that can be pointed by effect_dup_func:
234  // simple_effect_dup
235  // region_dup
236  // copy_effect
237  effect r = (*effect_dup_func)(eff2);
239  /* *eff1_still_combinable_p = true; (redundant) */
240  *eff2_still_combinable_p = false;
241  l_res = CONS(EFFECT, r, l_res);
242  }
243  else if (eff2_abstract_location_p) /* and r1 concrete location */
244  {
245  // functions that can be pointed by effect_dup_func:
246  // simple_effect_dup
247  // region_dup
248  // copy_effect
249  effect r = (*effect_dup_func)(eff1);
251  *eff1_still_combinable_p = false;
252  /* *eff2_still_combinable_p = true; (redundant) */
253  l_res = CONS(EFFECT, r, l_res);
254  }
255  else /* two concrete locations */
256  {
257  l_res = gen_nconc((*concrete_effects_intersection_op)(eff1,eff2), l_res);
258  *eff1_still_combinable_p = false;
259  *eff2_still_combinable_p = false;
260  }
261 
262  pips_debug_effects(8, "returning:\n", l_res);
263  return l_res;
264 }
265 
266 
267 /**
268  @brief returns the contribution of the sup difference of eff1 and eff2 to
269  the result list of the generic binary operator.
270  beware: may modify eff1 and eff2
271 
272  @param[in] eff1_abstract_location_p is true if eff1 is an abstract location
273  ( put as a parameter because testing abstract locations is costly and is
274  better done outside loops when possible)
275  @param[in] eff2_abstract_location_p is true if eff2 is an abstract location
276  @param[out] eff1_still_combinable_p is a pointer to a bool which must be true
277  when entering the function, and stays true if eff1 may still be
278  combinable with other effects in the calling function
279  @param[out] eff2_still_combinable_p is a pointer to a bool which must be true
280  when entering the function, and stays true if eff2 may still be
281  combinable with other effects in the calling function
282  @param[in] concrete_effects_sup_difference_op computes the union of two effects on
283  concrete locations.
284  */
285 static list effects_generic_sup_difference_op(effect eff1, effect eff2,
286  bool eff1_abstract_location_p,
287  bool eff2_abstract_location_p,
288  bool *eff1_still_combinable_p,
289  bool *eff2_still_combinable_p,
290  list (*concrete_effects_sup_difference_op)(effect,effect))
291 {
292  list l_res = NIL;
293 
294  ifdebug(1)
295  pips_assert("eff1 and eff2 must be still combinable",
296  *eff1_still_combinable_p && *eff2_still_combinable_p);
297 
298  pips_debug_effect(8, "eff1: \n", eff1);
299  pips_debug_effect(8, "eff2: \n", eff2);
300 
301  if (eff1_abstract_location_p || eff2_abstract_location_p)
302  {
303  effect_to_may_effect(eff1);
304 
305  if (eff1_abstract_location_p && eff2_abstract_location_p)
306  {
307  entity al1 = effect_entity(eff1);
308  entity al2 = effect_entity(eff2);
309  if (same_entity_p(al1, al2))
310  *eff1_still_combinable_p = *eff2_still_combinable_p = false;
311  else
312  {
313  entity al_max = abstract_locations_max(al1, al2);
314  if (same_entity_p(al1, al_max)) /* r2 is strictly less than r1 */
315  {
316  /* *eff1_still_combinable_p = true; redundant */
317  *eff2_still_combinable_p = false;
318  }
319  else /* r1 is strictly less than r2 */
320  {
321  ifdebug(1) pips_assert("combinable abstract locations: one of them is the max of both",
322  same_entity_p(al2, al_max));
323  *eff1_still_combinable_p = false;
324  /* *eff2_still_combinable_p = true; redundant */
325  }
326  }
327  }
328  else
329  {
330  *eff1_still_combinable_p = eff1_abstract_location_p;
331  *eff2_still_combinable_p = eff2_abstract_location_p;
332  }
333  if (!*eff1_still_combinable_p)
334  {
335  // functions that can be pointed by effect_dup_func:
336  // simple_effect_dup
337  // region_dup
338  // copy_effect
339  l_res = CONS(EFFECT, (*effect_dup_func)(eff1), l_res); /* add it now to the result */
340  }
341  /* else it will be added later, since it is still combinable */
342  }
343  else /* two concrete locations */
344  {
345  l_res = gen_nconc((*concrete_effects_sup_difference_op)(eff1,eff2), l_res);
346  *eff1_still_combinable_p = false;
347  *eff2_still_combinable_p = false;
348  }
349 
350  pips_debug_effects(8, "returning:\n", l_res);
351  return l_res;
352 }
353 
354 /**
355  @brief returns the contribution of the inf difference of eff1 and eff2 to
356  the result list of the generic binary operator.
357  beware: may modify eff1 and eff2
358 
359  @param[in] eff1_abstract_location_p is true if eff1 is an abstract location
360  ( put as a parameter because testing abstract locations is costly and is
361  better done outside loops when possible)
362  @param[in] eff2_abstract_location_p is true if eff2 is an abstract location
363  @param[out] eff1_still_combinable_p is a pointer to a bool which must be true
364  when entering the function, and stays true if eff1 may still be
365  combinable with other effects in the calling function
366  @param[out] eff2_still_combinable_p is a pointer to a bool which must be true
367  when entering the function, and stays true if eff2 may still be
368  combinable with other effects in the calling function
369  @param[in] concrete_effects_sup_difference_op computes the union of two effects on
370  concrete locations.
371  */
372 static list effects_generic_inf_difference_op(effect eff1, effect eff2,
373  bool eff1_abstract_location_p,
374  bool eff2_abstract_location_p,
375  bool *eff1_still_combinable_p,
376  bool *eff2_still_combinable_p,
377  list (*concrete_effects_inf_difference_op)(effect,effect))
378 {
379  list l_res = NIL;
380 
381  ifdebug(1)
382  pips_assert("eff1 and eff2 must be still combinable",
383  *eff1_still_combinable_p && *eff2_still_combinable_p);
384 
385  pips_debug_effect(8, "eff1: \n", eff1);
386  pips_debug_effect(8, "eff2: \n", eff2);
387 
388  if (eff1_abstract_location_p || eff2_abstract_location_p)
389  {
390  /* return a NIL list */
391  /* *eff1 is not combinable anymore, because we have already found out that something
392  * must be removed from it
393  */
394  *eff1_still_combinable_p = false;
395 
396  if (eff1_abstract_location_p && eff2_abstract_location_p)
397  {
398  entity al1 = effect_entity(eff1);
399  entity al2 = effect_entity(eff2);
400  if (same_entity_p(al1, al2))
401  *eff2_still_combinable_p = false;
402  else
403  {
404  entity al_max = abstract_locations_max(al1, al2);
405  if (same_entity_p(al1, al_max)) /* r2 is strictly less than r1 */
406  {
407  /* *eff1_still_combinable_p = true; redundant */
408  *eff2_still_combinable_p = false;
409  }
410  else /* r1 is strictly less than r2 */
411  {
412  ifdebug(1) pips_assert("combinable abstract locations: one of them is the max of both",
413  same_entity_p(al2, al_max));
414  /* *eff1_still_combinable_p = false; redundant */
415  /* *eff2_still_combinable_p = true; redundant */
416  }
417  }
418  }
419  else
420  {
421  /* *eff1_still_combinable_p = eff1_abstract_location_p; redundant */
422  *eff2_still_combinable_p = eff2_abstract_location_p;
423  }
424  }
425  else /* two concrete locations */
426  {
427  l_res = gen_nconc((*concrete_effects_inf_difference_op)(eff1,eff2), l_res);
428  *eff1_still_combinable_p = false;
429  *eff2_still_combinable_p = false;
430  }
431 
432  pips_debug_effects(8, "returning:\n", l_res);
433  return l_res;
434 }
435 
436 /*********************************** GENERIC BINARY OPERATORS ON LISTS OF EFFECTS */
437 
438 /**
439  beware : modifies l1, l2 and their effects
440 
441  @param l1 and l2 are two lists of effects.
442  @param r1_r2_combinable_p is a bool function that takes two
443  individual effects as arguments and renders true when they are
444  considered as combinable ;
445  @param r1_r2_generic_binary_op is a binary operator that combines two
446  individual effects whatever their path may be;
447  @param r1_r2_binary_op is a binary operator that combines two
448  individual effects on concrete paths; it is called by the previous
449  parameter;
450  @param r1_unary_op is a unary operators that deal with the remnants of l1,
451  that is those effects that are not combinable with any effect of l2;
452  @param r2_unary_op is a unary operators that deal with the remnants of l2,
453  that is those effects that are not combinable with any effect of l1;
454 
455  @return a list of effects, combination of l1 and l2.
456 
457  There is a strong assumption on l1 and l2 effects: two effects of l1
458  (resp. l2) are not combinable wrt r1_r2_combinable_p. The algorithm
459  relies on this assumption to avoid unecessary comparisons of effects
460  when possible, for performance reasons (the asymptotic complexity is
461  o(n1*n2), but taking into account this assumption reduces the average
462  complexity).
463 
464  The algorithm takes into account the fact that if an effect of l1 (resp. l2)
465  is an abstract location, it may be combinable with several effects
466  of l2 (resp. l1).
467  We strongly rely on the abstract locations lattice properties and on the
468  list properties to avoid to recursively compute the union of two
469  individual effects with the current resulting list.
470 
471 */
472 list
474  list l1,
475  list l2,
476  bool (*r1_r2_combinable_p)(effect,effect),
477  list (*r1_r2_generic_binary_op)(effect,effect, bool, bool, bool*, bool*, list (*)(effect, effect) ),
478  list (*r1_r2_concrete_binary_op)(effect,effect),
479  list (*r1_unary_op)(effect),
480  list (*r2_unary_op)(effect))
481 {
482  list l_res = NIL;
483  bool fortran_p = fortran_module_p(get_current_module_entity()); // no need to test for abstract locations
484 
485  debug_on("EFFECTS_OPERATORS_DEBUG_LEVEL");
486 
487  pips_debug_effects(1, "Initial effects : \n\t l1 :\n", l1);
488  pips_debug_effects(1, "\t l2 :\n", l2);
489 
490 
491  /* we first deal with the effects of l1 : those that are combinable with
492  * the effects of l2, and the others, which we call the remnants of l1 */
493  FOREACH(EFFECT, r1, l1)
494  {
495  list lr2 = l2;
496  list prec_lr2 = NIL;
497  bool r1_still_combinable_p = true;
498  bool r1_abstract_location_p = fortran_p? false : effect_abstract_location_p(r1);
499 
500  pips_debug_effect(8, "r1: %s\n", r1);
501 
502  while(r1_still_combinable_p && !ENDP(lr2))
503  {
504  effect r2 = EFFECT(CAR(lr2));
505  bool r2_still_combinable_p = true;
506  bool r2_abstract_location_p = fortran_p? false : effect_abstract_location_p(r2);
507 
508  pips_debug_effect(8, "r2: \n", r2);
509 
510  if ( (*r1_r2_combinable_p)(r1,r2) )
511  {
512  pips_debug(8, "combinable\n");
513 
514  list l_tmp = (*r1_r2_generic_binary_op)(r1, r2,
515  r1_abstract_location_p,
516  r2_abstract_location_p,
517  &r1_still_combinable_p,
518  &r2_still_combinable_p,
519  r1_r2_concrete_binary_op);
520  l_res = gen_nconc(l_tmp, l_res);
521  if (!r2_still_combinable_p) /* remove it from l2 */
522  {
523  list new_lr2 = CDR(lr2);
524  /* gen_remove(&l2, EFFECT(CAR(lr2))); */
525  if (prec_lr2 != NIL)
526  CDR(prec_lr2) = CDR(lr2);
527  else
528  l2 = CDR(lr2);
530  CDR(lr2) = NIL;
531  free(lr2);
532  lr2 = new_lr2;
533  }
534  else
535  {
536  prec_lr2 = lr2;
537  lr2 = CDR(lr2);
538  }
539  } /* if (*r1_r2_combinable_p)() */
540  else
541  {
542  pips_debug(8,"not combinable\n");
543  prec_lr2 = lr2;
544  lr2 = CDR(lr2);
545  }
546  } /* while (r1_still_combinable_p && !ENDP(lr2))*/
547 
548  if (r1_still_combinable_p)
549  l_res = gen_nconc((*r1_unary_op)(r1),l_res);
550  else
551  free_effect(r1); /* r1 won't be used anymore */
552  }
553 
554  /* we must finally add the remaining effects of l2 */
555  FOREACH(EFFECT, r2, l2) {
556  l_res = gen_nconc((*r2_unary_op)(r2),l_res);
557  }
558 
559  // necessary to avoid flip-flops in list order
560  // when there are successive invocations, in particular
561  // with proper_effects_combine
562  l_res = gen_nreverse(l_res);
563 
564  pips_debug_effects(1, "final effects:\n", l_res);
565 
566  /* no memory leaks: l1 and l2 won't be used anymore */
567  gen_free_list(l1);
568  gen_free_list(l2);
569 
570  debug_off();
571 
572  return l_res;
573 }
574 
575 /**
576  @brief computes the union of the two input lists of effects.
577  beware : modifies/frees l1, l2 and their effects
578 
579  @param l1 and l2 are two lists of effects.
580  @param r1_r2_combinable_p is a bool function that takes two
581  individual effects as arguments and renders true when they are
582  considered as combinable ;
583  @param r1_r2_union_op is a union operator that combines two
584  individual effects;
585  @param r_unary_op is an operator applied to the effects from one
586  orignal list that are not combinable with the effects of the
587  other list;
588 
589  @return a list of effects, combination of l1 and l2.
590 
591  There is a strong assumption on l1 and l2 effects: two effects of l1
592  (resp. l2) are not combinable wrt r1_r2_combinable_p. The algorithm
593  relies on this assumption to avoid unecessary comparisons of effects
594  when possible, for performance reasons ((the asymptotic complexity is
595  o(n1*n2), but taking into account this assumption reduces the average
596  complexity).
597 
598  The algorithm takes into account the fact that if an effect of l1 (resp. l2)
599  is an abstract location, it may be combinable with several effects
600  of l2 (resp. l1).
601  We strongly rely on the abstract locations lattice properties and on the
602  list properties to avoid to recursively compute the union of two
603  individual effects with the current resulting list.
604 
605 */
606 list
608  list l1,
609  list l2,
610  bool (*r1_r2_combinable_p)(effect,effect),
611  list (*r1_r2_concrete_union_op)(effect,effect),
612  list (*r_unary_op)(effect))
613 {
614  list l_res = list_of_effects_generic_binary_op(l1, l2, r1_r2_combinable_p,
615  effects_generic_union_op,
616  r1_r2_concrete_union_op,
617  r_unary_op, r_unary_op);
618  return l_res;
619 }
620 
621 
622 
623 /**
624  @brief computes the intersection of two lists of effects/regions
625  *beware*: modifies l1, l2 and their effects.
626 
627  @param l1 and l2 are two lists of effects.
628  @param r1_r2_combinable_p is a bool function that takes two
629  individual effects as arguments and renders true when they are
630  considered as combinable;
631  @param r1_r2_intersection_op is a binary operator that combines two
632  individual effects on concrete locations;
633 
634  @return a list of effects, intersection of l1 and l2.
635 
636 
637  There is a strong assumption on l1 and l2 effects: two effects of l1
638  (resp. l2) are not combinable wrt r1_r2_combinable_p. The algorithm
639  relies on this assumption to avoid unecessary comparisons of effects
640  when possible, for performance reasons (the asymptotic complexity is
641  o(n1*n2), but taking into account this assumption reduces the average
642  complexity).
643 
644 */
646  list l1,
647  list l2,
648  bool (*r1_r2_combinable_p)(effect,effect),
649  list (*r1_r2_concrete_intersection_op)(effect,effect))
650 {
651  list l_res = list_of_effects_generic_binary_op(l1, l2, r1_r2_combinable_p,
652  effects_generic_intersection_op,
653  r1_r2_concrete_intersection_op,
656 
657  return l_res;
658 }
659 
660 /**
661  @brief computes the intersection of two lists of effects/regions
662  *beware*: modifies l1, l2 and their effects.
663 
664  @param l1 and l2 are two lists of effects.
665  @param r1_r2_combinable_p is a bool function that takes two
666  individual effects as arguments and renders true when they are
667  considered as combinable;
668  @param r1_r2_intersection_op is a binary operator that combines two
669  individual effects on concrete locations;
670 
671  @return a list of effects, intersection of l1 and l2.
672 
673 
674  There is a strong assumption on l1 and l2 effects: two effects of l1
675  (resp. l2) are not combinable wrt r1_r2_combinable_p. The algorithm
676  relies on this assumption to avoid unecessary comparisons of effects
677  when possible, for performance reasons (the asymptotic complexity is
678  o(n1*n2), but taking into account this assumption reduces the average
679  complexity).
680 
681 */
683  list l1,
684  list l2,
685  bool (*r1_r2_combinable_p)(effect,effect),
686  list (*r1_r2_concrete_cells_intersection_op)(effect,effect))
687 {
688  list l_res = list_of_effects_generic_binary_op(l1, l2, r1_r2_combinable_p,
689  effects_generic_intersection_op,
690  r1_r2_concrete_cells_intersection_op,
693 
694  return l_res;
695 }
696 
697 
698 /**
699  @brief computes an over-approximate of the difference of two lists
700  of effects/regions. *beware*: modifies l1, l2 and their effects.
701 
702  @param l1 and l2 are two lists of effects.
703  @param r1_r2_combinable_p is a bool function that takes two
704  individual effects as arguments and renders true when they are
705  considered as combinable;
706  @param r1_r2_difference_op is a binary operator that combines two
707  individual effects on concrete locations;
708 
709  @return a list of effects, over-approximating the difference of l1 and l2.
710 
711 
712  There is a strong assumption on l1 and l2 effects: two effects of l1
713  (resp. l2) are not combinable wrt r1_r2_combinable_p. The algorithm
714  relies on this assumption to avoid unecessary comparisons of effects
715  when possible, for performance reasons (the asymptotic complexity is
716  o(n^2), but taking into account this assumption reduces the average
717  complexity).
718 
719 */
721  list l1,
722  list l2,
723  bool (*r1_r2_combinable_p)(effect,effect),
724  list (*r1_r2_concrete_sup_difference_op)(effect,effect))
725 {
726 
727  list l_res = list_of_effects_generic_binary_op(l1, l2, r1_r2_combinable_p,
728  effects_generic_sup_difference_op,
729  r1_r2_concrete_sup_difference_op,
732 
733  return l_res;
734 }
735 
736 /**
737  @brief computes an undef-approximate of the difference of two lists
738  of effects/regions. *beware*: modifies l1, l2 and their effects.
739 
740  @param l1 and l2 are two lists of effects.
741  @param r1_r2_combinable_p is a bool function that takes two
742  individual effects as arguments and renders true when they are
743  considered as combinable;
744  @param r1_r2_concrete_inf_difference_op is a binary operator that combines two
745  individual effects on concrete locations;
746 
747  @return a list of effects, over-approximating the difference of l1 and l2.
748 
749 
750  There is a strong assumption on l1 and l2 effects: two effects of l1
751  (resp. l2) are not combinable wrt r1_r2_combinable_p. The algorithm
752  relies on this assumption to avoid unecessary comparisons of effects
753  when possible, for performance reasons (the asymptotic complexity is
754  o(n^2), but taking into account this assumption reduces the average
755  complexity).
756 
757 */
759  list l1,
760  list l2,
761  bool (*r1_r2_combinable_p)(effect,effect),
762  list (*r1_r2_concrete_inf_difference_op)(effect,effect))
763 {
764 
765  list l_res = list_of_effects_generic_binary_op(l1, l2, r1_r2_combinable_p,
766  effects_generic_inf_difference_op,
767  r1_r2_concrete_inf_difference_op,
770 
771  return l_res;
772 }
773 
774 /**
775  @brief computes an undef-approximate of the difference of two lists
776  of effects/regions. *beware*: modifies l1, l2 and their effects.
777 
778  @param l1 and l2 are two lists of effects.
779  @param r1_r2_combinable_p is a bool function that takes two
780  individual effects as arguments and renders true when they are
781  considered as combinable;
782  @param r1_r2_concrete_inf_difference_op is a binary operator that combines two
783  individual effects on concrete locations;
784 
785  @return a list of effects, over-approximating the difference of l1 and l2.
786 
787 
788  There is a strong assumption on l1 and l2 effects: two effects of l1
789  (resp. l2) are not combinable wrt r1_r2_combinable_p. The algorithm
790  relies on this assumption to avoid unecessary comparisons of effects
791  when possible, for performance reasons (the asymptotic complexity is
792  o(n^2), but taking into account this assumption reduces the average
793  complexity).
794 
795 */
797  list l1,
798  list l2,
799  bool (*r1_r2_combinable_p)(effect,effect),
800  list (*r1_r2_concrete_cells_inf_difference_op)(effect,effect))
801 {
802 
803  list l_res = list_of_effects_generic_binary_op(l1, l2, r1_r2_combinable_p,
804  effects_generic_inf_difference_op,
805  r1_r2_concrete_cells_inf_difference_op,
808 
809  return l_res;
810 }
811 
813 {
814  return proper_effects_combine(l_effects, false);
815 }
816 
817 
818 /* list proper_effects_contract(list l_effects)
819  * input : a list of proper effects
820  * output : a list of proper effects in which there is no two identical
821  * scalar effects.
822  * modifies : the input list.
823  * comment : This is used to reduce the number of dependence tests.
824  */
825 
827 {
828  return(proper_effects_combine(l_effects, true));
829 }
830 
831 /**
832  merges the selected elements of the input list
833  @param l_eff is a list of effects, and is modified/freed
834  @param scalars_only_p; when true, only scalar effects are merged
835  @return a new list of effects
836  @see effects_combinable_p
837  @see old_proper_effects_combine
838 
839  Asymptotic complexity is o(n^2/2). Former version was o(n) but did not
840  properly take abstract locations into account.
841  */
842 list proper_effects_combine(list l_eff, bool scalars_only_p)
843 {
844  list l_res = NIL;
845  bool (*effects_comb_p)(effect eff1, effect eff2) =
847 
848  pips_debug_effects(6, "input effects:", l_eff);
849 
850  // merge one effect at a time in the result list using the union
851  // operator.
852  FOREACH(EFFECT, eff, l_eff)
853  {
854  // functions that can be pointed by proper_to_summary_effect_func:
855  // effect_nop
856  // proper_to_summary_simple_effect
857  eff = (*proper_to_summary_effect_func)(eff);
858 
859  // functions that can be pointed by effects_union_op:
860  // ProperEffectsMustUnion
861  // RegionsMustUnion
862  // ReferenceUnion
863  // EffectsMustUnion
864  l_res = (*effects_union_op)(effect_to_list(eff), l_res, *effects_comb_p);
865  }
866  gen_free_list(l_eff);
867  pips_debug_effects(6, "output effects:", l_res);
868  return l_res;
869 }
870 
871 
872 /* OBSOLETE - however, I keep it because it may be adapted to handle
873  abstract locations properly - But it is unclear to me whether
874  it's better to have a o(n^2/2) algorithm or a o(n) with hash
875  table keys generated from strings, as manipulating strings
876  is always costly, and many performance problems in Pips have been
877  solved by avoiding them. BC
878 */
879 /* list proper_effects_combine(list l_effects, bool scalars_only_p)
880  * input : a list of proper effects, and a bool to know on which
881  * elements to perform the combination.
882  * output : a list of effects, in which the selected elements have been
883  * merged.
884  * modifies : the input list.
885  * comment : the algorithm is in O(n) (was in (n^2)/2)
886  *
887  * we need "entity/action" -> consp to check for the
888  * condition in the second loop directly.
889  * or to simplify the hash management, two entity -> consp?
890  * a generic multi key combination hash would help.
891  * the list is modified IN PLACE, storing on the first effect encountered...
892  *
893  * Extensions for C make it more complex as an effect on p and on p[1]
894  * are not related. It would be possible to eliminate syntactically
895  * equal effects by converting them into strings, without information
896  * about the approximation. As a first try, I keep the hash tables
897  * based on names and actions, and I only check compatibility in
898  * reference and addressing mode afterwards. But this is not working
899  * as I do not get enough different entries in the hash table since
900  * entity_name is the key.
901  *
902  * The syntactic elimination is implemented, but the scoping
903  * information is left out because the function is shard with the
904  * effect prettyprinter. Scoping information should be preserved in the key.
905  *
906  * Also, it might be useful to normalize the effects and to convert
907  * the pointer-based effects into an anywhere effect as soon as the
908  * corresponding pointer is written before it is
909  * dereferenced. However, we can delay the conversion till needed, as
910  * long as the concrete semantics of the effect lists is understoof by
911  * the user. This gives us a chance to find later the value of the
912  * written pointer and to substitue it where needed. Else, the effects
913  * to substitute will be gone.
914  */
915 static list __attribute__((unused)) old_proper_effects_combine(list l_effects, bool scalars_only_p) {
916  list cur, pred = NIL;
917  /* entity name -> consp in effect list. */
918  hash_table all_read_effects, all_write_effects;
919  /* FI: at this level, it's pretty dangerous to combine effects with
920  no constant addresses */
921 
922  ifdebug(6) {
923  list refl = NIL;
924  int i = 0;
925  pips_debug(6, "Proper effects to combine: \n");
926  (*effects_prettyprint_func)(l_effects);
927 
928  /* This is a pretty weak assert because it's performed on the
929  addresses */
930  pips_assert("The very same effect does not appear twice",
931  gen_once_p(l_effects));
932 
933  FOREACH(EFFECT, eff, l_effects) {
934  cell c = effect_cell(eff);
935  /* FI: the cell tag is not checked here but later a posteriori! */
937 
938  if(cell_reference_p(c)) {
939  refl = gen_nconc(refl, CONS(REFERENCE, ref, NIL));
940  }
941  i++;
942  fprintf(stderr, "Effect %d: %p\tReference %d: %p (%spersistant)\n",
943  i, eff, i, ref, cell_reference_p(c)? "not ":"");
944  }
945 
946  pips_assert("The very same reference does not appear twice"
947  " unless it is persistant", gen_once_p(refl));
948  }
949 
950  all_read_effects = hash_table_make(hash_string, 10);
951  all_write_effects = hash_table_make(hash_string, 10);
952  //all_read_pre_effects = hash_table_make(hash_string, 10);
953  //all_write_pre_effects = hash_table_make(hash_string, 10);
954  //all_read_post_effects = hash_table_make(hash_string, 10);
955  //all_write_post_effects = hash_table_make(hash_string, 10);
956 
957  cur = l_effects;
958  /* scan the list of effects... the list is modified in place */
959  while(!ENDP(cur))
960  {
961  effect lcurrent = EFFECT(CAR(cur));
963  string n;
964  tag a;
965  action_kind ak;
966  bool may_combine, do_combine = false;
967  list do_combine_item = NIL;
968  list next = CDR(cur); /* now, as 'cur' may be removed... */
969 
970  /* Summarization before combination: let's be as store independent as possible */
971  // functions that can be pointed by proper_to_summary_effect_func:
972  // effect_nop
973  // proper_to_summary_simple_effect
974  current = (*proper_to_summary_effect_func)(lcurrent);
975 
977  // n = entity_name(effect_entity(current));
978  list w;
979  string rn = words_to_string
981  gen_map(free,w);gen_free_list(w);
982  /* Do not combine effects of different kinds: use the kind in the key */
983  asprintf(&n,"%s %s",rn,action_kind_to_string(ak));
984  free(rn);
986 
987  pips_debug(8,"key: \"\%s\"\n", n);
988 
989  /* may/do we have to combine ? */
990  /* ??? FC this should be no big deal... anyway :
991  * in the previous implementation, 'current' was not yet
992  * passed thru proper_to_summary_effect_func when tested...
993  *
994  * FI: effect_scalar_p() should be redefined because the new key
995  * used let us deal with complex effects.
996  */
997  may_combine = (!scalars_only_p || effect_scalar_p(current));
998  //&& !store_effect_p(current);
999 
1000 
1001  /* FI: addressing should be checked below against writing of the
1002  * underlying pointer. No time right now. */
1003 
1004  if (may_combine)
1005  {
1006  /* did we see it at a previous iteration? */
1007  switch (a) {
1008  case is_action_write:
1009  if (hash_defined_p(all_write_effects, n))
1010  {
1011  do_combine = true;
1012  do_combine_item = hash_get(all_write_effects, n);
1013  }
1014  break;
1015  case is_action_read:
1016  if (hash_defined_p(all_read_effects, n))
1017  {
1018  do_combine = true;
1019  do_combine_item = hash_get(all_read_effects, n);
1020  }
1021  break;
1022  default:
1023  pips_internal_error("unexpected action tag %d", a);
1024  return NIL;
1025  }
1026  }
1027 
1028  if (do_combine)
1029  {
1030  /* YES, me must combine */
1031 
1032  effect base = EFFECT(CAR(do_combine_item));
1034  /* compute their union */
1035  // functions that can be pointed by effect_union_op:
1036  // effect_must_union
1037  // regions_must_convex_hull
1038  effect combined = (*effect_union_op)(base, current);
1039 
1040  /* replace the base effect by the new effect */
1041  pips_assert("combined is a consistent effect",
1042  effect_consistent_p(combined));
1043  EFFECT_(CAR(do_combine_item)) = combined;
1044 
1045  /* free the original effects: no memory leak */
1046  free_effect(base);
1047  //free_effect(current); SG: this free triggers a segfault ...
1048 
1049  /* remove the current list element from the global list */
1050  /* pred!=NIL as on the first items hash's are empty */
1051  CDR(pred) = next; /* pred is not changed! */
1052  free(cur);
1053  }
1054  else {
1055  do_combine = false;
1056  }
1057  }
1058  if(!do_combine)
1059  {
1060  /* NO, just store if needed... */
1061  EFFECT_(CAR(cur)) = current;
1062  if (may_combine)
1063  {
1064  /* if we do not combine. ONLY IF we test, we put... */
1065  switch (a) {
1066  case is_action_write:
1067  hash_put(all_write_effects, strdup(n), cur);
1068  break;
1069  case is_action_read:
1070  hash_put(all_read_effects, strdup(n), cur);
1071  break;
1072  default:
1073  pips_internal_error("unexpected action tag %d", a);
1074  return NIL;
1075  }
1076  }
1077  pred = cur;
1078  }
1079 
1080  cur = next;
1081  free(n);
1082  }
1083 
1084  ifdebug(6){
1085  pips_debug(6, "summary effects: \n");
1086  (*effects_prettyprint_func)(l_effects);
1087  }
1088 
1089  /* The keys should be freed as well */
1090  hash_table_free(all_write_effects);
1091  hash_table_free(all_read_effects);
1092 
1093  return l_effects;
1094 }
1095 
1096 
1097 
1098 /******************************************************* BOOL(EAN) FUNCTIONS */
1099 
1100 
1101 /**
1102  @param eff1 and eff2 are two effects
1103  @ return true if their entities are the same, and if their access path
1104  as described by their references are the same, or if one of
1105  the effect is an anywhere effect.
1106  false otherwise.
1107  */
1108 bool effects_combinable_p(effect eff1, effect eff2)
1109 {
1110  bool combinable_p = false;
1111  action_kind ak1 = effect_action_kind(eff1);
1112  action_kind ak2 = effect_action_kind(eff2);
1113 
1114  pips_debug_effect(1,"eff1 = ", eff1);
1115  pips_debug_effect(1,"eff2 = ", eff2);
1116 
1117 
1118  if(action_kind_tag(ak1)==action_kind_tag(ak2))
1119  combinable_p = cells_combinable_p(effect_cell(eff1), effect_cell(eff2));
1120 
1121  pips_debug(1, "-> %s combinable\n", combinable_p? "": "not");
1122 
1123  return combinable_p;
1124 }
1125 
1126 bool cells_combinable_p(cell c1, cell c2)
1127 {
1128  bool combinable_p = true;
1129  pips_assert("cell c1 is not a GAP", !cell_gap_p(c1));
1130  pips_assert("cell c2 is not a GAP", !cell_gap_p(c2));
1131 
1132  reference r1 = cell_any_reference(c1);
1133  reference r2 = cell_any_reference(c2);
1134 
1135  entity e1 = reference_variable(r1);
1136  entity e2 = reference_variable(r2);
1137 
1138  list l1 = reference_indices(r1);
1139  list l2 = reference_indices(r2);
1140 
1141  if (same_entity_p(e1, e2))
1142  {
1143  /* let us check the indices */
1144 
1145  if (gen_length(l1) != gen_length(l2))
1146  combinable_p = false;
1147 
1148  bool finished_p = false;
1149 
1150  while(combinable_p && !finished_p)
1151  {
1152  if (ENDP(l1) && ENDP(l2))
1153  {
1154  finished_p = true;
1155  }
1156  else if (ENDP(l1) || ENDP(l2))
1157  {
1158  combinable_p = false;
1159  finished_p = true;
1160  }
1161  else
1162  {
1163  expression exp1 = EXPRESSION(CAR(l1));
1164  syntax s1 = expression_syntax(exp1);
1165  expression exp2 = EXPRESSION(CAR(l2));
1166  syntax s2 = expression_syntax(exp2);
1167 
1168  /* check if the index expressions are the same for regions
1169  or are comparable for simple effects.
1170  For instance a[1] and a[2] can be merged into a[*] even
1171  if the indices are not the same. The same for a[*] and a[1].
1172  former tests were first based on string comparisons;
1173  then expression_equal_p was used to lessen comparison cost,
1174  especially for regions, where expressions are
1175  references to PHI entities.
1176  However, a[1] and a[2] were then considered as not comparable,
1177  which resulted in long lists of effects, and was not compatible
1178  with the generic binary operators which assume that there is at
1179  most one effect/region per path kind.
1180  */
1181 
1182  if (syntax_reference_p(s1))
1183  {
1185  if (syntax_reference_p(s2))
1186  {
1188  if (es1 != es2)
1189  {
1190  if (variable_phi_p(es1) || variable_phi_p(es2)
1191  || entity_field_p(es1) /* and then necessarily entity_field_p(e2) is true */)
1192  {
1193  combinable_p = false;
1194  finished_p = true;
1195  }
1196  }
1197  }
1198  else
1199  {
1200  // it cannot be a region; it's a simple effect and the current indices are array
1201  // indices or a pointer dimension
1202  pips_assert( "the current index must be an array index or a pointer dimension",
1203  (!variable_phi_p(es1)) && (!entity_field_p(es1)));
1204  combinable_p = true;
1205  finished_p = false;
1206  }
1207  }
1208  if (!finished_p)
1209  {
1210  POP(l1);
1211  POP(l2);
1212  }
1213  }
1214  }
1215 
1216  }
1217  else
1218  {
1219 
1221  /* don't do unecessary and costly things for fortran 77 codes*/
1222  {
1223  bool al1_p = entity_abstract_location_p(e1);
1224  bool al2_p = entity_abstract_location_p(e2);
1225  bool heap1_p = al1_p && entity_heap_location_p(e1);
1226  bool heap2_p = al2_p && entity_heap_location_p(e2);
1227  bool heap1_context_sensitive_p = heap1_p && entity_flow_or_context_sentitive_heap_location_p(e1);
1228  bool heap2_context_sensitive_p = heap2_p && entity_flow_or_context_sentitive_heap_location_p(e2);
1229 
1230  /* if one of them is an abstract location, they may be combinable */
1231  if ( al1_p || al2_p)
1232  {
1233  /* this is only a temporary hack before we avoid generating anywhere effects
1234  each time we lose some information
1235  */
1236  if (al1_p && (malloc_cell_p(c2) || io_cell_p(c2)
1237  || (!get_bool_property("USER_EFFECTS_ON_STD_FILES")
1238  && std_file_cell_p(c2))))
1239  {
1240  pips_debug(8, "eff1 is an effect on an abstract location "
1241  "and eff2 is a malloc or io effect\n");
1242  combinable_p = false;
1243  }
1244  else if (al2_p && (malloc_cell_p(c1) || io_cell_p(c1)
1245  || (!get_bool_property("USER_EFFECTS_ON_STD_FILES")
1246  && std_file_cell_p(c1))))
1247  {
1248  pips_debug(8, "eff2 is an effect on an abstract location "
1249  "and eff1 is a malloc or io effect\n");
1250  combinable_p = false;
1251  }
1252  else if ((al1_p && entity_all_locations_p(e1))
1253  || (al2_p && entity_all_locations_p(e2)))
1254  combinable_p = true;
1255  else if (al1_p && (undefined_pointer_value_entity_p(e1)
1258  if(al2_p && (undefined_pointer_value_entity_p(e2)
1261  combinable_p = true;
1262  else
1263  combinable_p = false;
1264  }
1265  else if (al2_p && (undefined_pointer_value_entity_p(e2)
1268  combinable_p = false;
1269  }
1270  else if (al1_p && entity_null_locations_p(e1)) {
1271  if(al2_p && entity_null_locations_p(e2))
1272  combinable_p = true;
1273  else
1274  combinable_p = false;
1275  }
1276  else if (al2_p && entity_null_locations_p(e2)) {
1277  combinable_p = false;
1278  }
1279  else if ( (al1_p && al2_p)
1280  || (al1_p && ENDP(reference_indices(r2)))
1281  || (al2_p && ENDP(reference_indices(r1))))
1282  /*two abstract locations or one abstract location and a scalar */
1283  combinable_p = entities_may_conflict_p(e1,e2);
1284  else
1285  {
1286  if (heap1_p || heap2_p)
1287  {
1288  if (heap1_context_sensitive_p && heap2_context_sensitive_p)
1289  {
1290  // they conflict only if they are the same. however, this case
1291  // has already been handled before
1292  combinable_p = false;
1293  }
1294  else if (heap1_p && heap2_p)
1295  {
1296  // the two are heap entities but at most one of them is context sensitive
1297  // they are combinable
1298  combinable_p = true;
1299  }
1300  else
1301  {
1302  // only one of them is a heap location
1303  // if the other one is not an abstract location, then they are not
1304  // combinable
1305  if ((heap1_p && !al2_p) || (heap2_p && !al1_p))
1306  {
1307  combinable_p = false;
1308  }
1309  else
1310  {
1311  /* here it is more difficult, to be handled later */
1312  pips_internal_error("case not handled yet (c1 = %s, c2 = %s)\n",
1315  }
1316  }
1317  }
1318  else
1319  {
1320  /* here we should consider the type of the non abstract location reference,
1321  whether there is a dereferencement or not to guess the memory area, ... */
1322  // FI: we end up here with c1 = *ANY_MODULE*:*ANYWHERE*_b0.next, c2 = _ll_1.next
1323  // FI: we also end up here with c1 = array[*], c2 = *ANY_MODULE*:*ANYWHERE*_b0
1324  pips_assert("One of the effect at least is linked to an abstract location", al1_p || al2_p);
1325  if(get_bool_property("ALIASING_ACROSS_TYPES"))
1326  combinable_p = true;
1327  else if(expression_lists_equal_p(l1, l2)) {
1328  reference nr1 = make_reference(e1, NIL);
1329  reference nr2 = make_reference(e2, NIL);
1330  cell nc1 = make_cell_reference(nr1);
1331  cell nc2 = make_cell_reference(nr2);
1332  combinable_p = cells_combinable_p(nc1, nc2);
1333  free_cell(nc1), free_cell(nc2);
1334  }
1335  else {
1336  /* Check the types of the two cells */
1340  combinable_p = true;
1341  else
1342  combinable_p = false;
1343  //pips_internal_error("case not handled yet (c1 = %s, c2 = %s)\n",
1344  // effect_reference_to_string(r1),
1345  // effect_reference_to_string(r2));
1346  }
1347  }
1348  }
1349  }
1350 
1351  else combinable_p = false; /* two concrete location paths beginning from different entities
1352  are not combinable by binary operators.
1353  well this is true for constant path effects/regions...
1354  for pointer regions this is true for union
1355  I still have to check for intersection and difference. BC.
1356  */
1357  }
1358  else combinable_p = false;
1359  }
1360 
1361  return combinable_p;
1362 }
1363 
1364 /* BC: same action, but also same variable and same indexing and
1365  * at least one of them is a scalar (abstract locations and concrete
1366  * are combined even if the concrete location is not a scalar)
1367  *
1368  * Checking the action kind may sometimes be useless or even wrong.
1369  */
1371 {
1372  bool same_p = false;
1373 
1374  if (effect_undefined_p(eff1) || effect_undefined_p(eff2))
1375  same_p = true;
1376  else if (effect_action_tag(eff1)!=effect_action_tag(eff2))
1377  {
1378  same_p = false;
1379  }
1380  else {
1383  if(action_kind_tag(ak1)!=action_kind_tag(ak2))
1384  same_p = false;
1385  else
1386  same_p = (effect_scalar_p(eff1) || effect_scalar_p(eff2)) && effects_combinable_p(eff1, eff2);
1387 #if 0
1388  else {
1389  // FI->BC: s.f and s.f is not recognized as scalar effect
1390  // because they are encoded as s[f], which does not appear scalar
1391  // Also effects_combinable_p() may redo some of the work
1392  // performed above
1393  // same_p = (effect_scalar_p(eff1) || effect_scalar_p(eff2))
1394  // && effects_combinable_p(eff1, eff2);
1395  same_p = (atomic_effect_p(eff1) || atomic_effect_p(eff2))
1396  && effects_combinable_p(eff1, eff2);
1397  //FI : a[*] and a[*] in EffectsWithPointsTo/call10.c
1398  if(!same_p) {
1399  cell c1 = effect_cell(eff1);
1400  cell c2 = effect_cell(eff2);
1401  reference r1 = cell_any_reference(c1);
1402  reference r2 = cell_any_reference(c2);
1403  same_p = reference_equal_p(r1, r2);
1404  }
1405  }
1406 #endif
1407  }
1408 
1409  return same_p;
1410 }
1411 
1412 /* FI: same action, but also same variable and same indexing
1413  *
1414  * Checking the action kind may sometimes be useless or even wrong.
1415  */
1416 bool effects_same_action_p(effect eff1, effect eff2)
1417 {
1418  bool same_p = false;
1419 
1420  if (effect_undefined_p(eff1) || effect_undefined_p(eff2))
1421  same_p = true;
1422  else if (effect_action_tag(eff1)!=effect_action_tag(eff2))
1423  {
1424  same_p = false;
1425  }
1426  else {
1429  if(action_kind_tag(ak1)!=action_kind_tag(ak2))
1430  same_p = false;
1431  else
1432  same_p = effects_combinable_p(eff1, eff2);
1433  }
1434 
1435  return same_p;
1436 }
1437 
1438 bool effects_same_variable_p(effect eff1, effect eff2)
1439 {
1440  bool same_var = (effect_entity(eff1) == effect_entity(eff2));
1441  return(same_var);
1442 }
1443 
1444 
1445 bool r_r_combinable_p(effect eff1, effect eff2)
1446 {
1447  bool combinable_p, act_combinable;
1448 
1449  if (effect_undefined_p(eff1))
1450  return(effect_read_p(eff2));
1451 
1452  if (effect_undefined_p(eff2))
1453  return(effect_read_p(eff1));
1454 
1455  combinable_p = effects_combinable_p(eff1,eff2);
1456  act_combinable = (effect_read_p(eff1) && effect_read_p(eff2));
1457 
1458  return(combinable_p && act_combinable);
1459 }
1460 
1461 bool w_w_combinable_p(effect eff1, effect eff2)
1462 {
1463  bool combinable_p, act_combinable;
1464 
1465  if (effect_undefined_p(eff1))
1466  return(effect_write_p(eff2));
1467 
1468  if (effect_undefined_p(eff2))
1469  return(effect_write_p(eff1));
1470 
1471  combinable_p = effects_combinable_p(eff1,eff2);
1472  act_combinable = (effect_write_p(eff1) && effect_write_p(eff2));
1473 
1474  return(combinable_p && act_combinable);
1475 }
1476 
1477 bool r_w_combinable_p(effect eff1, effect eff2)
1478 {
1479  bool combinable_p, act_combinable;
1480 
1481  if (effect_undefined_p(eff1))
1482  return(effect_write_p(eff2));
1483 
1484  if (effect_undefined_p(eff2))
1485  return(effect_read_p(eff1));
1486 
1487  combinable_p = effects_combinable_p(eff1,eff2);
1488  act_combinable = (effect_read_p(eff1) && effect_write_p(eff2));
1489 
1490  return(combinable_p && act_combinable);
1491 }
1492 
1493 bool w_r_combinable_p(effect eff1, effect eff2)
1494 {
1495  bool combinable_p, act_combinable;
1496 
1497  if (effect_undefined_p(eff1))
1498  return(effect_read_p(eff2));
1499 
1500  if (effect_undefined_p(eff2))
1501  return(effect_write_p(eff1));
1502 
1503  combinable_p = effects_combinable_p(eff1,eff2);
1504  act_combinable = (effect_write_p(eff1) && effect_read_p(eff2));
1505 
1506  return(combinable_p && act_combinable);
1507 }
1508 
1509 /***********************************************************************/
1510 /* UNDEFINED BINARY OPERATOR */
1511 /***********************************************************************/
1512 
1513 list
1516 {
1517  pips_assert("unused arguments", l1==l1 && l2==l2 &&
1519  return list_undefined;
1520 }
1521 
1522 
1523 /***********************************************************************/
1524 /* SOME BINARY OPERATORS which do not depend on the representation */
1525 /***********************************************************************/
1526 
1527 /* list effect_entities_intersection(effect eff1, effect eff2)
1528  * input : two effects
1529  * output : a mere copy of the first effect.
1530  * modifies : nothing.
1531  * comment : We assume that both effects concern the same entity.
1532  */
1533 static list
1534 effect_entities_intersection(effect eff1, effect eff2)
1535 {
1536  pips_assert("unused argument", eff2==eff2);
1537  // functions that can be pointed by effect_dup_func:
1538  // simple_effect_dup
1539  // region_dup
1540  // copy_effect
1541  return CONS(EFFECT, (*effect_dup_func)(eff1), NIL);
1542 }
1543 
1544 /* list effects_entities_intersection(list l1, list l2,
1545  bool (*intersection_combinable_p)(effect, effect))
1546  * input : two lists of effects.
1547  * output : a list of effects containing all the effects of l1 that have
1548  * a corresponding effect (i.e. same entity) in l2.
1549  * modifies : l1 and l2.
1550  * comment :
1551  */
1552 list
1554  bool (*intersection_combinable_p)(effect, effect))
1555 {
1556  list l_res = NIL;
1557 
1558  pips_debug(3, "begin\n");
1560  intersection_combinable_p,
1561  effect_entities_intersection);
1562  pips_debug(3, "end\n");
1563 
1564  return l_res;
1565 }
1566 
1567 
1568 /* list effects_entities_inf_difference(list l1, l2)
1569  * input : two lists of effects
1570  * output : a list of effects, such that: if there is a effect R concerning
1571  * entity A in l1 and in l2, then R is removed from the result;
1572  * if there is a effect R concerning array A in l1, but not in l2,
1573  * then it is kept in l1, and in the result.
1574  * modifies : the effects of l2 may be freed.
1575  * comment : we keep the effects of l1 that are not combinable with those
1576  * of l2, but we don't keep the effects of l2 that are not
1577  * combinable with those of l_reg1.
1578  */
1579 list
1581  list l1,
1582  list l2,
1583  bool (*difference_combinable_p)(effect, effect))
1584 {
1585  list l_res = NIL;
1586 
1587  pips_debug(3, "begin\n");
1589  difference_combinable_p,
1591  pips_debug(3, "end\n");
1592 
1593  return l_res;
1594 }
1595 
1596 /* that is all
1597  */
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
cell make_cell_reference(reference _field_)
Definition: effects.c:293
void free_effect(effect p)
Definition: effects.c:451
bool effect_consistent_p(effect p)
Definition: effects.c:457
void free_cell(cell p)
Definition: effects.c:249
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
bool entity_flow_or_context_sentitive_heap_location_p(entity e)
bool entity_heap_location_p(entity b)
package abstract location.
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_abstract_location_p(entity al)
entity abstract_locations_max(entity al1, entity al2)
eturns the smallest abstract location set greater than or equalt to al1 and al2.
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
bool entity_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bdt base
Current expression.
Definition: bdt_read_paf.c:100
#define max(a, b)
#define pips_debug_effects(level, message, l_eff)
#define pips_debug_effect(level, message, eff)
for debug
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))
list list_of_effects_generic_binary_op(list, list, bool(*)(effect, effect), list(*)(effect, effect, bool, bool, bool *, bool *, list(*)(effect, effect)), list(*)(effect, effect), list(*)(effect), list(*)(effect))
binary_operators.c
list proper_to_summary_effects(list)
list proper_effects_contract(list)
list list_of_effects_generic_cells_inf_difference_op(list, list, bool(*)(effect, effect), list(*)(effect, effect))
bool w_r_combinable_p(effect, effect)
list proper_effects_combine(list, bool)
list effects_entities_inf_difference(list, list, bool(*)(effect, effect))
list effect_to_nil_list_and_free(effect)
bool effects_combinable_p(effect, effect)
bool effects_scalars_and_same_action_p(effect, effect)
void effect_to_may_effect(effect)
bool w_w_combinable_p(effect, effect)
list effects_entities_intersection(list, list, bool(*)(effect, effect))
list effects_undefined_binary_operator(list, list, bool(*)(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))
bool r_r_combinable_p(effect, effect)
effect(* effect_dup_func)(effect eff)
bool r_w_combinable_p(effect, effect)
list list_of_effects_generic_cells_intersection_op(list, list, bool(*)(effect, effect), list(*)(effect, effect))
list effect_to_list(effect)
list effects_to_nil_list(effect, effect)
bool cells_combinable_p(cell, cell)
bool effects_same_action_p(effect, effect)
bool effects_same_variable_p(effect, effect)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
#define effect_action_tag(eff)
#define variable_phi_p(e)
true if e is a phi variable PHI entities have a name like: REGIONS:PHI#, where # is a number.
bool io_cell_p(cell)
Definition: effects.c:506
action_kind action_to_action_kind(action)
Without the consistency test, this function would certainly be inlined.
Definition: effects.c:1048
bool effect_abstract_location_p(effect)
Definition: effects.c:280
list effect_words_reference(reference)
prettyprint.c
Definition: prettyprint.c:68
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
bool atomic_effect_p(effect)
Definition: effects.c:1668
bool undefined_pointer_value_entity_p(entity)
action_kind effect_action_kind(effect)
Definition: effects.c:1055
bool std_file_cell_p(cell)
Definition: effects.c:524
bool effect_scalar_p(effect)
Definition: effects.c:567
bool malloc_cell_p(cell)
Definition: effects.c:483
string effect_reference_to_string(reference)
Definition: prettyprint.c:155
bool effect_comparable_p(effect, effect)
Can we merge these two effects because they are equal or because they only differ by their approximat...
Definition: effects.c:587
string action_kind_to_string(action_kind)
Definition: effects.c:995
#define cell_reference(x)
Definition: effects.h:469
#define effect_undefined_p(x)
Definition: effects.h:615
#define cell_reference_p(x)
Definition: effects.h:467
#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 cell_gap_p(x)
Definition: effects.h:473
@ is_action_write
Definition: effects.h:293
@ is_action_read
Definition: effects.h:292
#define EFFECT_(x)
Definition: effects.h:611
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define effect_cell(x)
Definition: effects.h:640
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
if(!(yy_init))
Definition: genread_lex.c:1029
void free(void *)
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_map(gen_iter_func_t fp, const list l)
Definition: list.c:172
size_t gen_length(const list l)
Definition: list.c:150
bool gen_once_p(list l)
FC: ARGH...O(n^2)!
Definition: list.c:758
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
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
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
#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 asprintf
Definition: misc-local.h:225
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
@ hash_string
Definition: newgen_hash.h:32
int bool
we cannot use an enum or stdbool because we need to be compatible with newgen, thus boolean need to h...
Definition: newgen_types.h:78
int tag
TAG.
Definition: newgen_types.h:92
#define false
Definition: newgen_types.h:80
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
bool expression_lists_equal_p(list l1, list l2)
Definition: expression.c:1405
bool array_pointer_string_type_equal_p(type, type)
Assume that a pointer to type x is equal to a 1-D array of x.
Definition: type.c:658
#define syntax_reference_p(x)
Definition: ri.h:2728
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
#define expression_syntax(x)
Definition: ri.h:1247
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
else
Definition: set.c:239
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
static size_t current
Definition: string.c:115
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
string words_to_string(cons *lw)
Definition: print.c:211