PIPS
conflicts.c
Go to the documentation of this file.
1 /*
2 
3  $Id: conflicts.c 23412 2017-08-09 15:07:09Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25 #include "pips_config.h"
26 #endif
27 
28 #include <stdio.h>
29 
30 #include "linear.h"
31 
32 #include "genC.h"
33 
34 #include "ri.h"
35 #include "effects.h"
36 
37 #include "misc.h"
38 
39 #include "ri-util.h"
40 #include "effects-util.h"
41 
42 /** \addtogroup Effects
43  @{
44  */
45 
46 
47 /*
48  This file contains functions for testing "conflicts" between
49  effects, cells, references and entities which represent memory
50  locations.
51 
52  The effects, cells and references may correspond to different
53  stores, so it cannot be assumed that a[i] and a[i] represent the
54  same memory location.
55 
56  */
57 
58 
59 /* Properties settings for conflict testing functions */
60 /* These settings are done for performance reasons, especially in chains */
61 /* initial values are current default values */
62 static bool constant_path_effects_p = true;
63 static bool trust_constant_path_effects_p = false;
64 static bool user_effects_on_std_files_p = false;
65 static bool aliasing_across_types_p = true;
67 
69 {
70  bool get_bool_property( string );
71  constant_path_effects_p = get_bool_property("CONSTANT_PATH_EFFECTS");
72  trust_constant_path_effects_p = get_bool_property("TRUST_CONSTANT_PATH_EFFECTS_IN_CONFLICTS");
73  aliasing_across_types_p = get_bool_property( "ALIASING_ACROSS_TYPES" );
75  get_bool_property( "ALIASING_ACROSS_FORMAL_PARAMETERS" );
76  user_effects_on_std_files_p = get_bool_property("USER_EFFECTS_ON_STD_FILES");
77 }
78 
79 /* Intersection tests */
80 
81 /**
82  * @brief Check if two effects always conflict.
83  * @descriptionTwo effects will always conflict if their two abstract locations
84  * has a non-empty intersection and if at least one of them is a write.
85  * The approximation must also be "MUST", if one of them is a "MAY" there is no
86  * conflict
87  *
88  * This function is conservative: it is always correct not to declare a
89  * conflict.
90  *
91  * @return true if there is always a conflict between eff1 and eff2
92  */
94  action ac1 = effect_action(eff1);
95  action ac2 = effect_action(eff2);
98  bool conflict_p = false;
99 
100  /* We enforce must approximation for the two effects */
101  if ( approximation_exact_p(ap1) && approximation_exact_p(ap2) ) {
102  /* We enforce that at least one effect is a write */
103  if ( action_write_p(ac1) || action_write_p(ac2) ) {
104  cell cell1 = effect_cell(eff1);
105  cell cell2 = effect_cell(eff2);
106  /* Check that the cells conflicts */
107  if ( cells_must_conflict_p( cell1, cell2 ) ) {
108  conflict_p = true;
109  }
110  }
111  }
112  return conflict_p;
113 }
114 
115 
116 /**
117  * @brief Check if two effect might conflict, even if they are read only
118  * @description Two effects may conflict if their abstract two location sets has
119  * a non-empty intersection
120  *
121  * This function is conservative: it is always correct to declare a conflict.
122  */
124  action ac1 = effect_action(eff1);
125  action ac2 = effect_action(eff2);
126  bool conflict_p = true;
127 
130 
131  if(action_kind_tag(ak1) != action_kind_tag(ak2)) {
132  // A store mutation cannot conflict with an environment or type
133  // declaration mutation
134  conflict_p = false;
135  } else {
136  if(action_kind_store_p(ak1)) {
137  cell cell1 = effect_cell(eff1);
138  cell cell2 = effect_cell(eff2);
139  if(!cells_may_conflict_p(cell1, cell2)) {
140  conflict_p = false;
141  }
142  } else {
143  /* For environment and type declarations, the references are
144  empty and the conflict is only based on the referenced
145  entity */
146  entity v1 = effect_variable(eff1);
147  entity v2 = effect_variable(eff2);
148  conflict_p = v1 == v2;
149  }
150  }
151  return conflict_p;
152 }
153 
154 
155 /**
156  * @brief Check if two effect may conflict
157  * @description Two effects may conflict if their abstract two location sets has
158  * a non-empty intersection and if at least one of them is a write.
159  *
160  * This function is conservative: it is always correct to declare a conflict.
161  */
163  action ac1 = effect_action(eff1);
164  action ac2 = effect_action(eff2);
165  bool conflict_p = true;
166 
167  if ( action_read_p(ac1) && action_read_p(ac2) ) {
168  // Two read won't conflict
169  conflict_p = false;
170  } else {
171  conflict_p = effects_might_conflict_even_read_only_p(eff1,eff2);
172  }
173  return conflict_p;
174 }
175 
176 
177 /**
178  * @brief OBSOLETE, was never used !!
179  */
180 static bool old_effects_conflict_p( effect eff1, effect eff2 ) {
181  action ac1 = effect_action(eff1);
182  action ac2 = effect_action(eff2);
183  bool conflict_p = false;
184 
185  if ( action_write_p(ac1) || action_write_p(ac2) ) {
186  if ( anywhere_effect_p( eff1 ) || anywhere_effect_p( eff2 ) )
187  conflict_p = true;
188  else {
189 
190  reference r1 = effect_any_reference(eff1);
191  entity v1 = reference_variable(r1);
192  reference r2 = effect_any_reference(eff2);
193  entity v2 = reference_variable(r2);
194 
195  /* Do we point to the same area? */
196 
197  if ( entities_may_conflict_p( v1, v2 ) ) {
198  list ind1 = reference_indices(r1);
199  list ind2 = reference_indices(r2);
200  list cind1 = list_undefined;
201  list cind2 = list_undefined;
202 
203  if ( v1 != v2 ) {
204  /* We do not bother with the offset and the array types */
205  conflict_p = true;
206  } else {
207  if ( !ENDP(ind1) && !ENDP(ind2) ) {
208  for ( cind1 = ind1, cind2 = ind2; !ENDP(cind1) && !ENDP(cind2); POP(cind1), POP(cind2) ) {
209  expression e1 = EXPRESSION(CAR(cind1));
210  expression e2 = EXPRESSION(CAR(cind2));
211  if ( unbounded_expression_p( e1 ) || unbounded_expression_p( e2 ) )
212  conflict_p = true;
213  else {
214  intptr_t i1 = -1;
215  intptr_t i2 = -1;
216  bool i1_p = false;
217  bool i2_p = false;
218 
219  i1_p = expression_integer_value( e1, &i1 );
220  i2_p = expression_integer_value( e2, &i2 );
221  if ( i1_p && i2_p )
222  conflict_p = ( i1 == i2 );
223  else
224  conflict_p = true;
225  }
226  }
227  } else
228  conflict_p = true;
229  }
230  }
231 
232  else
233  conflict_p = true;
234  }
235  }
236  return conflict_p;
237 }
238 
239 /**
240  * @brief Synonym for effects_may_conflict_p().
241  *
242  * @description Name preserved to limit rewriting of source code using the old
243  * version. Also checks results of new implementation wrt the old implementation
244  * FIXME : to be removed: was never used until now !
245  */
246 bool effects_conflict_p( effect eff1, effect eff2 ) {
247  bool conflict_p = effects_may_conflict_p( eff1, eff2 );
248  bool old_conflict_p = old_effects_conflict_p( eff1, eff2 );
249 
250  /* In general, there is no reason to have the same results... This
251  is only a first debugging step. */
252  if ( conflict_p != old_conflict_p )
253  pips_internal_error("Inconsistent conflict detection.");
254 
255  return conflict_p;
256 }
257 
258 /**
259  * @brief Check if there may be a conflict between two array references
260  *
261  * @description May the two references to array a using subscript list sl1 and
262  * sl2 access the same memory locations?
263  *
264  * Subscript list sl1 and sl2 can be evaluated in two different stores.
265  *
266  * It is assumed that dim(a)=length(sl1)=length(sl2);
267  *
268  * If the nth subscript expression can be statically evaluated in both sl1
269  * and sl2 and if the subscript values are different, there is not
270  * conflict. For instance a[i][0] does not conflict with a[j][1].
271  * SG: this is only true if you assume no out-of-bound indices
272  * e.g int a[2][2]; a[1][0] conflict with a[0][2] ..
273  *
274  * This is about the old references_conflict_p()
275  */
277  bool conflict_p = true;
278 
279  list cind1 = list_undefined;
280  list cind2 = list_undefined;
281  for ( cind1 = sl1, cind2 = sl2; conflict_p && !ENDP(cind1) && !ENDP(cind2); POP(cind1), POP(cind2) ) {
282  expression e1 = EXPRESSION(CAR(cind1));
283  expression e2 = EXPRESSION(CAR(cind2));
284  if ( unbounded_expression_p( e1 ) || unbounded_expression_p( e2 ) )
285  conflict_p = true;
286  else {
287  intptr_t i1 = -1;
288  intptr_t i2 = -1;
289  bool i1_p = false;
290  bool i2_p = false;
291 
292  i1_p = expression_integer_value( e1, &i1 );
293  i2_p = expression_integer_value( e2, &i2 );
294  if ( i1_p && i2_p )
295  conflict_p = ( i1 == i2 );
296  else
297  conflict_p = true;
298  }
299  }
300  return conflict_p;
301 }
302 
303 /**
304  * @brief FIXME ?
305  *
306  * @description May the two references to v using subscript list sl1 and sl2
307  * access the same memory locations?
308  *
309  * Subscript list sl1 and sl2 can be evaluated in two different stores.
310  *
311  * FI: this code seems to assume that ALIASING_ACROSS_DATA_STRUCTURES
312  * is set to FALSE.
313  */
315 {
316  bool conflict_p = true;
317  type t = entity_type(v);
318  int sl1n = gen_length( sl1 );
319  int sl2n = gen_length( sl2 );
321 
322  if ( sl1n == sl2n && sl1n == nd ) {
323  /* This is equivalent to a simple Fortran-like array reference */
324  conflict_p = array_references_may_conflict_p( sl1, sl2 );
325  } else {
326  if ( !ENDP(sl1) && !ENDP(sl2) ) {
327  list cind1 = list_undefined;
328  list cind2 = list_undefined;
329  /* FI: this is new not really designed (!) code */
330  for ( cind1 = sl1, cind2 = sl2; !ENDP(cind1) && !ENDP(cind2)
331  && conflict_p; POP(cind1), POP(cind2) ) {
332  expression e1 = EXPRESSION(CAR(cind1));
333  expression e2 = EXPRESSION(CAR(cind2));
334  if ( unbounded_expression_p( e1 ) || unbounded_expression_p( e2 ) )
335  conflict_p = true;
336  else if ( expression_reference_p( e1 ) && expression_reference_p( e2 ) ) {
337  /* Because of heap modelization functions can be used as
338  subscript. Because of struct and union modelization,
339  fields can be used as subscripts. */
340  entity s1 = expression_variable( e1 ); // first subscript
341  entity s2 = expression_variable( e2 ); // second subscript
342  type s1t = entity_type(s1);
343  type s2t = entity_type(s2);
344 
345  if ( type_equal_p( s1t, s2t ) ) {
346  if ( type_functional_p(s1t) ) {
347  /* context sensitive heap modelization */
348  conflict_p = same_string_p(entity_name(s1), entity_name(s2));
349  }
350  else if( entity_field_p(s1) && entity_field_p(s2))
351  {
352  if(type_struct_variable_p(t)) conflict_p=same_entity_p(s1,s2);
353  else if(type_union_variable_p(t)) conflict_p=true;
354  }
355  } else {
356  /* assume the code is correct... Assume no floating
357  point index... a[i] vs a[x]... */
358  conflict_p = false;
359  }
360  } else {
361  intptr_t i1 = -1;
362  intptr_t i2 = -1;
363  bool i1_p = false;
364  bool i2_p = false;
365 
366  i1_p = expression_integer_value( e1, &i1 );
367  i2_p = expression_integer_value( e2, &i2 );
368  if ( i1_p && i2_p )
369  conflict_p = ( i1 == i2 );
370  else
371  conflict_p = true;
372  }
373  }
374  } else
375  conflict_p = true;
376  }
377  return conflict_p;
378 }
379 
380 /**
381  * @brief Check if two references may conflict
382  *
383  * @description Can the two references r1 and r2 access the same
384  * memory location when evaluated in two different stores?
385  *
386  * We have to deal with static aliasing for Fortran and with
387  * dynamic aliasing for C and Fortran95.
388  *
389  * We have to deal with abstract locations used to represent sets of
390  * memory locations.
391  *
392  * A PIPS reference is a memory access path rather than a reference as
393  * understood in programming languages:
394  *
395  * - a field of a struct or a union d can be accessed by subscripting
396  * d with a field number or with a field entity
397  *
398  * - a dereferencing is expressed by a zero subscript: *p is p[0]
399  *
400  * - abstract locations such as foo:*HEAP* or foo:*HEAP**MEMORY* or
401  * foo:*HEAP*_v3 can be used
402  *
403  * - heap modelization uses the malloc statement number as a subscript
404  *
405  * - flow-sensitive heap modelization can use indices from the
406  * surrounding loops as subscripts
407  *
408  * - context-sensitive heap modelization can also use function
409  * reference to record the call path
410  *
411  * Three bool properties are involved:
412  *
413  * - ALIASING_ACROSS_TYPES: if false objects of different types cannot
414  * be aliased
415  *
416  * - ALIASING_INSIDE_DATA_STRUCTURE: if false, access paths starting
417  * from the same data structure are assumed disjoint as soon as they
418  * differ. This property holds even after pointer
419  * dereferencement. It is extremely strong and wrong for PIPS source
420  * code, unless persistant is taken into account.
421  *
422  * - ALIASING_ACROSS_FORMAL_PARAMETERS: if false, access paths
423  starting from different parameters cannot conflict.
424 
425  */
427  bool conflict_p = true; // In doubt, conflict is assumed
428  entity e1 = reference_variable(r1);
429  entity e2 = reference_variable(r2);
430  list ind1 = reference_indices(r1);
431  list ind2 = reference_indices(r2);
432  bool get_bool_property( string );
433 
435 
437  {
438  pips_debug(5, "fortran case\n");
439  if (same_entity_p(e1, e2))
440  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
441  else
442  conflict_p = variable_entities_may_conflict_p( e1, e2 );
443  }
444  else if (ENDP(ind1) && ENDP(ind2)) /* calling entities_may_conflict_p is only valid for scalar entities */
445  {
446  pips_debug(5, "scalar case\n");
447  conflict_p = entities_may_conflict_p( e1, e2 );
448  }
449  else
450  {
451  /* here, we have either two concrete locations, one of which at least has indices,
452  or one abstract location and one concrete location with indices. BC
453  */
454  /* I'm not completely sure of that. Are numbered heap locations considered as abstract locations?
455  And they may have indices. Heap locations testing is a mess. BC.
456  */
457 
458  // these are costly function calls; call them only once.
459  bool e1_abstract_location_p = entity_abstract_location_p( e1 );
460  bool e2_abstract_location_p = entity_abstract_location_p( e2 );
461 
462  bool e1_heap_location_p = e1_abstract_location_p
464  bool e2_heap_location_p = e2_abstract_location_p
466 
467  pips_assert("there shouldn't be two abstract locations here.",
468  !( (e1_abstract_location_p && !e1_heap_location_p)
469  && (e2_abstract_location_p && !e2_heap_location_p)));
470 
471 
472  /* FI: Can we have some dynamic aliasing? */
473  /* Do we have aliasing between types? */
474  /* Do we have aliasing within a data structure? This should have
475  been checked above with
476  variable_references_may_conflict_p(v1,ind1,ind2) */
477 
478  /* A patch for effects_package references, which cannot conflict with user variables */
479  /* well, strictly speaking, couldn't they conflict with an anywhere:anywhere effect?
480  but then there should be other conflicts... */
482  {
483  if (!same_entity_p(e1, e2) || (ENDP(ind1) && ENDP(ind2)) )
484  conflict_p = false;
485  else // same entity, with indices
486  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
487  }
488  else
489  {
490 
491  /* string operations are costly - perform them only once */
492  bool e1_null_p = entity_null_locations_p(e1);
493  bool e2_null_p = entity_null_locations_p(e2);
494 
495  if (e1_null_p || e2_null_p)
496  conflict_p = e1_null_p && e2_null_p;
497  else if ((e1_abstract_location_p && !e1_heap_location_p )
498  || (e2_abstract_location_p && !e2_heap_location_p ))
499  {
500  entity abstract_location_e = e1_abstract_location_p? e1: e2;
501  //entity concrete_location_e = e1_abstract_location_p? e2: e1;
502 
503  pips_debug(5, "abstract location vs. concrete location case\n");
504 
505  if (entity_all_locations_p(abstract_location_e))
506  conflict_p = true;
507  else
508  // there should be a reference_to_abstract_location function
509  // as there is a variable_to_abstract_location function
510  // assume conflict, but much more work should be done here. BC.
511  conflict_p = true;
512  }
513  else // two concrete locations
514  {
515  pips_debug(5, "two concrete locations case \n");
516  if (same_entity_p(e1, e2))
517  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
518  else
519  {
520  // there should be no conflict here with constant path effects
521  // however, this is still work in progress :-( and when
522  // CONSTANT_PATH_EFFECTS is set to FALSE, effects may be erroneous.
523  // so we need this to avoid over-optimistic program transformations
524 
526  {
527  conflict_p = false;
528  }
529  else
530  {
531  bool t1_to_be_freed = false, t2_to_be_freed = false;
532  type t1 = cell_reference_to_type( r1, &t1_to_be_freed );
533  type t2 = cell_reference_to_type( r2, &t2_to_be_freed );
534 
535  if ( conflict_p && !aliasing_across_types_p
536  && !type_equal_p(t1, t2) )
537  {
538  pips_debug(5, "no conflict because types are not equal\n");
539  conflict_p = false; /* well type_equal_p does not perform a good job :-( BC*/
540  }
541  if (t1_to_be_freed) free_type(t1);
542  if (t2_to_be_freed) free_type(t2);
543 
544  if ( conflict_p && !aliasing_across_formal_parameters_p
545  && entity_formal_p(e1) && entity_formal_p(e2) )
546  {
547  pips_debug(5, "no conflict because entities are formals\n");
548  conflict_p = false;
549  }
550 
551  if (conflict_p && !user_effects_on_std_files_p
552  && (std_file_entity_p(e1) || std_file_entity_p(e2)))
553  {
554  if (!same_entity_p(e1, e2))
555  conflict_p = false;
556  else
557  conflict_p = variable_references_may_conflict_p( e1, ind1, ind2 );
558  }
559 
560  /* should ALIASING_ACROSS_DATA_STRUCTURES be also tested here? */
561  if ( conflict_p )
562  {
563  /* Do we have some dereferencing in ind1 or ind2? Do we assume
564  that p[0] conflicts with any reference? We might as well use
565  reference_to_abstract_location()... */
566  /* Could be improved with ALIASING_ACROSS_DATA_STRUCTURES? */
567  bool exact;
568  // Check dereferencing in r1
569  conflict_p = effect_reference_dereferencing_p( r1, &exact );
570  if(!conflict_p) {
571  /* We need to evaluate dereferencing in r2 only when a dereferencing
572  * have not been find in r1 */
573  conflict_p = effect_reference_dereferencing_p( r2, &exact );
574  }
575  /* In other words, we assume no conflict as soon as no pointer is
576  * dereferenced... even when aliasing across types is not ignored !
577  *
578  * If aliasing across types is ignored, we know here that the
579  * two memory locations referenced are of the same type. If the
580  * pointer in one reference (let's assume only one pointer to
581  * start with) is not of type pointer to the common type, then
582  * there is no conflict.
583  *
584  * Else, we have to assume a conflict no matter what, because
585  * simple cases should have been simplified via the points-to
586  * analysis.
587  */
588  }
589 
590  }
591  }
592  } // end: two concrete locations
593 
594  }
595  }
596 
597  pips_debug(5, "there is %s may conflict\n", conflict_p? "a": "no");
598  return conflict_p;
599 }
600 
601 /**
602  * @brief Check if two references may conflict
603  *
604  * @description See references_may_conflict_p
605  *
606  */
608  bool conflict_p = false;
609  entity e1 = reference_variable(r1);
610  entity e2 = reference_variable(r2);
611 
613 
614  // Do a simple check for scalar conflicts
615  if ( reference_scalar_p( r1 ) && reference_scalar_p( r2 )
616  && entities_must_conflict_p( e1, e2 ) ) {
617  conflict_p = true;
618  } else {
619  /* pips_user_warning("Not completely implemented yet. "
620  "Conservative under approximation is made\n");*/
621  if(entities_must_conflict_p(e1, e2)) {
622  /* Check for constant subscripts */
623  list sl1 = reference_indices(r1);
624  list sl2 = reference_indices(r2);
625  int n1 = (int) gen_length(sl1);
626  int n2 = (int) gen_length(sl2);
627  if(n1==n2) {
628  list csl2 = sl2;
629  bool diff_p = false;
630  FOREACH(EXPRESSION, se1, sl1) {
631  expression se2 = EXPRESSION(CAR(csl2));
632  if(expression_equal_p(se1, se2)) {
634  ;
635  else if(expression_reference_p(se1)) {
636  reference se1r = expression_reference(se1);
637  entity se1f = reference_variable(se1r);
638  if(!entity_field_p(se1f)) {
639  diff_p = true;
640  break;
641  }
642  }
643  else {
644  diff_p = true;
645  break;
646  }
647  }
648  else {
649  diff_p = true;
650  break;
651  }
652  POP(csl2);
653  }
654  conflict_p = !diff_p;
655  }
656  }
657  }
658  pips_debug(5, "there is %s must conflict\n", conflict_p? "a": "no");
659  return conflict_p;
660 }
661 
662 /**
663  * @brief Check if two cell may or must conflict
664  *
665  * @param must_p if set to true, we enforce a must conflict
666  */
667 static bool cells_maymust_conflict_p( cell c1, cell c2, bool must_p ) {
668  bool conflict_p = false;
671 
672  if ( cell_reference_p(c1) )
673  r1 = cell_reference(c1);
674  else if ( cell_preference_p(c1) )
676 
677  if ( cell_reference_p(c2) )
678  r2 = cell_reference(c2);
679  else if ( cell_preference_p(c2) )
681 
682  if ( reference_undefined_p(r1) || reference_undefined_p(r2) ) {
683  pips_internal_error("either undefined references or gap "
684  "not implemented yet\n");
685  }
686 
687  conflict_p = must_p ? references_must_conflict_p( r1, r2 )
688  : references_may_conflict_p( r1, r2 );
689 
690  return conflict_p;
691 }
692 
693 /**
694  * @brief Check if two cell may conflict
695  */
697  bool conflict_p = cells_maymust_conflict_p( c1, c2, false );
698  return conflict_p;
699 }
700 
701 /* Same as above, but for lists. Lists conflict if there exist at
702 least one element in l1 and one element in l2 that conflict. */
704 {
705  bool conflict_p = false;
706  FOREACH(CELL, c1, l1) {
707  FOREACH(CELL, c2, l2) {
708  if(cells_may_conflict_p(c1, c2)) {
709  conflict_p = true;
710  break;
711  }
712  }
713  if(conflict_p)
714  break;
715  }
716  return conflict_p;
717 }
718 
719 /**
720  * @brief Check if two cell must conflict
721  */
723  bool conflict_p = cells_maymust_conflict_p( c1, c2, true );
724  return conflict_p;
725 }
726 
727 /* Same as above, but for lists. Lists conflict if there exist at
728 least one element in l1 and one element in l2 that must conflict. */
730 {
731  bool conflict_p = false;
732  FOREACH(CELL, c1, l1) {
733  FOREACH(CELL, c2, l2) {
734  if(cells_must_conflict_p(c1, c2)) {
735  conflict_p = true;
736  break;
737  }
738  }
739  if(conflict_p)
740  break;
741  }
742  return conflict_p;
743 }
744 
745 /**
746  * @brief Check if two entities may or must conflict
747  *
748  * FI->MA: we certainly said a lot more during the February 2010
749  * meeting, when abstract locations were added. And now we have store
750  * and type declaration dependencies...
751  *
752  * @param must_p define if we enforce must conflict or only may one
753  *
754  * Be careful because entity_variable_p(e) does not guarantee that e
755  * is a variable defined by the programmer. Maybe another function is
756  * needed to make sure that the conversion to an abstract location
757  * generates a useful result... variable_entity_p() is not necessarily
758  * good either because it uses the entity storage to make a
759  * decision. Formal parameters and return values are not taken into
760  * account.
761  *
762  * There no abstract locations for formal parameters and return
763  * values, which may not be a good idea if C let you pick up the
764  * address of a formal parameter. They have to be handled in a
765  * specific way.
766  *
767  * Beware: this function should only be used for scalar entities.
768  * however, I do not add an assert for this time, because I don't yet know
769  * what damages it may cause...
770  */
771 bool entities_maymust_conflict_p( entity e1, entity e2, bool must_p )
772 {
773  bool conflict_p = !must_p; // safe default value
774 
775  // effects package entities are not usual variables
777  conflict_p = (e1 == e2);
778  // idem with "register" variables which are in a world of their own
779  else if (entity_register_p(e1) || entity_register_p(e2))
780  conflict_p = (e1 == e2);
781  /* Constant strings may be tested because they are used to represent
782  the underlying buffers. The effect should always be a read effect. */
784  conflict_p = (e1 == e2);
785  // With location entities, we may have static aliasing in C
786  else if (!c_module_p(get_current_module_entity())) {
787  pips_debug(5, "fortran case, C case with semantics constant path analysis\n");
788  if (same_entity_p(e1, e2))
789  conflict_p = true;
790  else
791  conflict_p = must_p ? false : variable_entities_may_conflict_p( e1, e2 );
792  }
793  else if(location_entity_p(e1)) {
794  if(location_entity_p(e2)) {
795  // No aliasing between locations
796  conflict_p = e1==e2;
797  }
798  else {
801  // This entity seems to have type area and not type overloaded
802  // as expected from the lattice
803  conflict_p = !must_p;
804  }
805  else {
808  // FI: how about type_overloaded_p(t1)
809  conflict_p = !must_p && (overloaded_type_p(t2) || type_equal_p(t1, t2));
810  }
811  }
812  else {
813  value v1 = entity_initial(e1);
814  reference r1 = value_reference(v1);
815  entity ne1 = reference_variable(r1);
816  conflict_p = entities_maymust_conflict_p(ne1, e2, must_p );
817  }
818  }
819  }
820  else if(location_entity_p(e2)) {
823  // This entity seems to have type area and not type overloaded
824  // as expected from the lattice
825  conflict_p = !must_p;
826  }
827  else {
830  // FI: the type lattice should be used
831  conflict_p = !must_p && (overloaded_type_p(t1) || type_equal_p(t1, t2));
832  }
833  }
834  else {
835  value v2 = entity_initial(e2);
836  reference r2 = value_reference(v2);
837  entity ne2 = reference_variable(r2);
838  conflict_p = entities_maymust_conflict_p(e1, ne2, must_p );
839  }
840  }
841  else {
842  // these are costly function calls; call them only once.
843  bool e1_abstract_location_p = entity_abstract_location_p( e1 );
844  bool e2_abstract_location_p = entity_abstract_location_p( e2 );
845 
846  bool (*abstract_locations_conflict_p)(entity,entity);
847  abstract_locations_conflict_p =
850 
851  if (e1_abstract_location_p && e2_abstract_location_p)
852  {
853  // two abstract locations
854  conflict_p = abstract_locations_conflict_p( e1, e2 );
855  }
856  else if (e1_abstract_location_p || e2_abstract_location_p)
857  {
858  // one abstract location and a concrete one
859  entity abstract_location = e1_abstract_location_p? e1 : e2;
860  entity concrete_location = e1_abstract_location_p? e2 : e1;
861 
862  if (entity_null_locations_p(concrete_location))
863  conflict_p = entity_all_locations_p(abstract_location);
864 
865  else if ( type_variable_p(entity_basic_concrete_type(concrete_location)) )
866  {
867  if ( variable_return_p( concrete_location ) )
868  {
869  conflict_p = false;
870  }
871  else if ( entity_formal_p( concrete_location ) )
872  {
873  /* FI: Either we need an new abstract location for the formal
874  parameters or we need to deal explictly with this case
875  here and declare conflict with *anywhere*. */
876  conflict_p = entity_all_locations_p(abstract_location);
877  if(!conflict_p) {
878  entity concrete_location_al =
879  variable_to_abstract_location(concrete_location);
880  conflict_p = abstract_locations_conflict_p(abstract_location,
881  concrete_location_al);
882  }
883  }
884  else
885  {
886  entity concrete_location_al =
887  variable_to_abstract_location(concrete_location);
888  conflict_p = abstract_locations_conflict_p(abstract_location,
889  concrete_location_al);
890  }
891  }
892  else if(entity_function_p(concrete_location)) {
893  pips_internal_error("Meaningless conflict tested for function \"%s\".",
894  entity_user_name(concrete_location));
895  }
896  else
897  {
898  pips_internal_error("Unexpected case for variable \"%s\".",
899  entity_user_name(concrete_location));
900  }
901  }
902  else
903  {
904  // two concrete locations
905  if ( variable_return_p( e1 ) && variable_return_p( e2 ) )
906  {
907  conflict_p = same_entity_p(e1,e2);
908  }
909  else if ( entity_formal_p( e1 ) && entity_formal_p( e2 ) )
910  {
911  conflict_p = same_entity_p(e1,e2);
912  }
914  {
915  conflict_p = same_entity_p(e1,e2);
916  }
918  {
919  /* FIXME : variable_entity_must_conflict_p does not exist yet */
920  if( !must_p)
921  {
922  conflict_p = variable_entities_may_conflict_p( e1, e2 );
923  }
924  else
925  {
926  /* A must conflict is useful to guarantee a kill, but this
927  shows that it is not related to the definition of the
928  may case: two variables may share exactly the same set
929  of memory locations but a reference to one of them does
930  not necessarily imply that all locations are read or
931  written. More comments (thinking) are needed to
932  distinguish between entity and reference conflicts. */
933  /* We assume that e1 and e2 are program variables. Because
934  we do not have enough comments, we do not know if this
935  only hold for variables and arrays of one element. It is
936  easy to argue that an array cannot must conflict with
937  itself. The test below does not solve the case of
938  struct, and maybe union. */
939  if(entity_scalar_p(e1)) {
940  /* FI: should always be the case here but a struct
941  * variable is a scalar, as well as the location
942  * entities representing its field. They are
943  * aliased as equivalenced Fortran variables. The
944  * case of struct and struct field can be solved
945  * at a higher level by converting effects to
946  * their location entities when it makes sense
947  * instead of relying on the effect base
948  * variable. */
949  conflict_p = same_entity_p(e1,e2);
950  }
951  else
952  conflict_p = false;
953  }
954  }
955  else
956  {
957  /* FI: we end up here if references linked to environment or
958  type declarations are tested for conflicts. Should we
959  perform such tests, basically e1==e2, or assume that they
960  should have been handled at a higher level? */
961  if(!variable_entity_p(e1) || variable_entity_p(e2))
962  {
963  /* There are no conflicts between entities of different
964  kinds */
965  /* Since this implies e1!=e2, this case could be merged
966  with the next one, but the spec would be less clear */
967  conflict_p = false;
968  }
969  else {
970  /* Environment and type declaration conflicts imply that
971  the very same entity is involved. */
972  conflict_p = same_entity_p(e1,e2);
973  }
974  }
975  } // end: two concrete locations
976  }
977  return conflict_p;
978 }
979 
980 /**
981  * @brief Check if two entities may conflict
982  *
983  */
985  return entities_maymust_conflict_p( e1, e2, false);
986 }
987 
988 /**
989  * @brief Check if two entities must conflict
990  *
991  */
993  return entities_maymust_conflict_p( e1, e2, true);
994 }
995 
996 
997 /* Inclusion tests */
998 
999 /* I'm not sure that testing must conflicts makes much sense with sets of memory locations.
1000  We cannot well define a symmetrical semantics.
1001  However, testing the inclusion makes sense! BC.
1002 */
1003 
1004 /**
1005  tests whether first reference certainly includes second one
1006 
1007  @see first_effect_certainly_includes_second_effect_p
1008  */
1009 static
1011 {
1012  bool r1_certainly_includes_r2_p = false; /* safe result */
1013 
1016  r1_certainly_includes_r2_p = true;
1017 
1018  return r1_certainly_includes_r2_p;
1019 }
1020 
1021 /* tests whether first cell certainly includes second one
1022 
1023  @see first_effect_certainly_includes_second_effect_p
1024  */
1025 static
1027 {
1028  bool cell1_certainly_includes_cell2_p = false; /* safe result */
1029 
1030  reference r1 = cell_to_reference(c1);
1031  reference r2 = cell_to_reference(c2);
1032 
1033  cell1_certainly_includes_cell2_p = first_reference_certainly_includes_second_reference_p(r1, r2);
1034  return cell1_certainly_includes_cell2_p;
1035 }
1036 
1037 
1038 /**
1039  tests whether first effect certainly includes second one. The effects
1040  are not necessarily functions of the same store.
1041 
1042  This means that a[i]-exact does not necessarily contains a[i]-exact
1043  because i may not have the same value in the store to which the effects refer.
1044  This is the case for instance in the following code:
1045 
1046  i = 1;
1047  a[i] = ...; // S1
1048  i = 2;
1049  a[i] = ...; // S2
1050 
1051  The assignment in S2 does not kill the assignment in S2;
1052 
1053  This function could be improved for convex effects by eliminating
1054  from Psystems program variables which are not common inclosing loop variants.
1055  this would require much more information than what we currently have.
1056 
1057  So in all cases, the function safely returns false for effects
1058  described with access paths which are not single entities.
1059  */
1061 {
1062  bool eff1_certainly_includes_eff2_p = false; /* safe result */
1063 
1064  if ( effect_exact_p(eff1) && effect_scalar_p(eff1)
1065  && effect_scalar_p(eff2)
1067  {
1068  eff1_certainly_includes_eff2_p = true;
1069  }
1070 
1071  return eff1_certainly_includes_eff2_p;
1072 }
1073 
1075 {
1076  bool eff1_certainly_includes_eff2_p = false; /* safe result */
1077 
1078  if ( effect_scalar_p(eff2)
1080  {
1081  pips_assert("the first effect is an exact and scalar effect",
1082  effect_exact_p(eff1) && effect_scalar_p(eff1));
1083  eff1_certainly_includes_eff2_p = true;
1084  }
1085 
1086  return eff1_certainly_includes_eff2_p;
1087 }
1088 
1089 
1090 /* misc functions */
1091 
1092 /**
1093  tests whether the input effect has a memory path from the input
1094  entity e; this is currently a mere syntactic test.
1095 
1096  other strategies could be implemented, such as building all the
1097  memory locations reachable from "e" using
1098  generic_effect_generate_all_accessible_paths_effects_with_level,
1099  and then testing whether in the resulting effects there is an
1100  effect which may conflict with en effect from the input
1101  list. However, this would be very costly.
1102  */
1104 {
1105  bool read_or_write = false;
1106  if(entity_variable_p(e))
1107  {
1109  if(store_effect_p(ef) && same_entity_p(e, e_used))
1110  {
1111  read_or_write = true;
1112  }
1113  }
1114 
1115  return read_or_write;
1116 }
1117 
1118 
1119 /**
1120  tests whether the input effects list may contain effects
1121  with a memory path from the input entity e; this is currently a mere syntactic test.
1122 
1123  other strategies could be implemented, such as building all the
1124  memory locations reachable from "e" using
1125  generic_effect_generate_all_accessible_paths_effects_with_level,
1126  and then testing whether in the resulting effects there is an
1127  effect which may conflict with en effect from the input
1128  list. However, this would be very costly.
1129  */
1131 {
1132  bool read_or_write = false;
1133  if(entity_variable_p(e))
1134  {
1135  FOREACH(EFFECT, ef, l_eff)
1136  {
1138  if (read_or_write) break;
1139  }
1140  }
1141  return read_or_write;
1142 }
1143 
1144 bool generic_effects_maymust_read_or_write_scalar_entity_p(list fx, entity e, bool must_p, bool concrete_p)
1145 {
1146  bool read_or_write = false;
1147 
1148  if(location_entity_p(e)) {
1150  FOREACH(EFFECT, ef, fx) {
1152  if(must_p)
1154  else
1156  if(read_or_write)
1157  break;
1158  }
1159  }
1160  else if(entity_variable_p(e) && entity_scalar_p(e)) {
1161  FOREACH(EFFECT, ef, fx) {
1163  entity e_used = entity_undefined;
1164  if(ENDP(reference_indices(r)))
1165  e_used = reference_variable(r);
1166  else {
1167  // FI: we are in effects-util and do no know if the semantics
1168  // analysis is using or not location entities...
1169  // is r a constant memory access path ?
1171  if(entity_undefined_p(e_used))
1172  e_used = reference_variable(r);
1173  }
1174  if(!concrete_p || !entity_abstract_location_p(e_used)) {
1175  /* Used to be a simple pointer equality test, but now we have to
1176  cope with abstract locations. */
1177  if(store_effect_p(ef)) {
1178  if(must_p) {
1179  if(entity_scalar_p(e_used) && entities_must_conflict_p(e, e_used)) {
1180  read_or_write = true;
1181  break;
1182  }
1183  }
1184  else {
1185  if(entities_may_conflict_p(e, e_used)) {
1186  read_or_write = true;
1187  break;
1188  }
1189  }
1190  }
1191  }
1192  }
1193  }
1194  return read_or_write;
1195 }
1196 
1198 {
1199  return generic_effects_maymust_read_or_write_scalar_entity_p(fx, e, must_p, false);
1200 }
1201 
1203 {
1204  return generic_effects_maymust_read_or_write_scalar_entity_p(fx, e, must_p, true);
1205 }
1206 
1207 /**
1208  check whether scalar entity e may be read or written by effects
1209  fx or cannot be accessed at all
1210 
1211  In semantics, e can be a functional entity such as constant string
1212  or constant float.
1213 */
1215 {
1217  return read_or_write;
1218 }
1219 
1221 {
1223  return read_or_write;
1224 }
1225 
1226 
1227 
1228 /**
1229  check whether scalar entity e must be read or written by any effect of fx or
1230  if it simply might be accessed.
1231 
1232  In semantics, e can be a functional entity such as constant string
1233  or constant float.
1234 */
1236 {
1238  return read_or_write;
1239 }
1240 
1241 
1242 
1243 /* Returns the list of entities used in effect list fx and
1244  potentially conflicting with e.
1245 
1246  Of course, abstract location entities do conflict with many
1247  entities, possibly of different types.
1248 
1249  if concrete_p==true, ignore abstract location entities.
1250  */
1252  entity e,
1253  bool concrete_p)
1254 {
1255  list lconflict_e = NIL;
1256 
1257  FOREACH(EFFECT, ef, fx)
1258  {
1260  if(!(entity_abstract_location_p(e_used) && concrete_p))
1261  {
1262  if(entities_may_conflict_p(e, e_used))
1263  {
1264  lconflict_e = gen_nconc(lconflict_e,
1265  CONS(ENTITY, e_used, NIL));
1266  }
1267  }
1268  }
1269 
1270  return lconflict_e;
1271 }
1272 
1274 {
1276 }
1277 
1279 {
1281 }
1282 
1283 /** @} */
void free_type(type p)
Definition: ri.c:2658
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
bool entity_flow_or_context_sentitive_heap_location_p(entity e)
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_abstract_location_p(entity al)
bool abstract_locations_must_conflict_p(entity al1 __attribute__((__unused__)), entity al2 __attribute__((__unused__)))
Do these two abstract locations MUST share some real memory locations ? Never ! DO NOT USE THIS FUNCT...
entity variable_to_abstract_location(entity v)
returns the smallest abstract locations containing the location of variable v.
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
bool entity_anywhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool abstract_locations_may_conflict_p(entity al1, entity al2)
Do these two abstract locations MAY share some real memory locations ?
void const char const char const int
static string read_or_write(bool a)
bool constant_string_entity_p(entity e)
Definition: constant.c:356
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_exact_p(eff)
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
action_kind action_to_action_kind(action)
Without the consistency test, this function would certainly be inlined.
Definition: effects.c:1048
bool location_entity_p(entity)
Definition: locations.c:349
bool effect_reference_dereferencing_p(reference, bool *)
Definition: type.c:233
bool store_effect_p(effect)
Definition: effects.c:1062
bool effect_scalar_p(effect)
Definition: effects.c:567
reference cell_to_reference(cell)
FI: probably to be moved elsewhere in ri-util.
Definition: effects.c:1326
type cell_reference_to_type(reference, bool *)
computes the type of a cell reference representing a memory access path.
Definition: type.c:466
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
string effect_reference_to_string(reference)
Definition: prettyprint.c:155
entity constant_memory_access_path_to_location_entity(reference)
A constant memory access path may not be considered.
Definition: locations.c:329
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define cell_reference_p(x)
Definition: effects.h:467
#define action_kind_tag(x)
Definition: effects.h:258
#define action_kind_store_p(x)
Definition: effects.h:259
#define approximation_exact_p(x)
Definition: effects.h:369
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
#define CELL(x)
CELL.
Definition: effects.h:424
#define action_read_p(x)
Definition: effects.h:311
#define cell_preference_p(x)
Definition: effects.h:470
#define effect_approximation(x)
Definition: effects.h:644
#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....
list concrete_effects_entities_which_may_conflict_with_scalar_entity(list fx, entity e)
Definition: conflicts.c:1278
bool first_effect_certainly_includes_second_effect_p(effect eff1, effect eff2)
tests whether first effect certainly includes second one.
Definition: conflicts.c:1060
bool entities_must_conflict_p(entity e1, entity e2)
Check if two entities must conflict.
Definition: conflicts.c:992
static bool first_cell_certainly_includes_second_cell_p(cell c1, cell c2)
tests whether first cell certainly includes second one
Definition: conflicts.c:1026
bool effects_maymust_read_or_write_scalar_entity_p(list fx, entity e, bool must_p)
Definition: conflicts.c:1197
bool points_to_cell_lists_must_conflict_p(list l1, list l2)
Same as above, but for lists.
Definition: conflicts.c:729
bool cells_must_conflict_p(cell c1, cell c2)
Check if two cell must conflict.
Definition: conflicts.c:722
bool concrete_effects_may_read_or_write_scalar_entity_p(list fx, entity e)
Definition: conflicts.c:1220
static bool user_effects_on_std_files_p
Definition: conflicts.c:64
static bool first_reference_certainly_includes_second_reference_p(reference r1, reference r2)
Inclusion tests.
Definition: conflicts.c:1010
static list generic_effects_entities_which_may_conflict_with_scalar_entity(list fx, entity e, bool concrete_p)
Returns the list of entities used in effect list fx and potentially conflicting with e.
Definition: conflicts.c:1251
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
bool first_exact_scalar_effect_certainly_includes_second_effect_p(effect eff1, effect eff2)
Definition: conflicts.c:1074
bool effects_might_conflict_even_read_only_p(effect eff1, effect eff2)
Check if two effect might conflict, even if they are read only @description Two effects may conflict ...
Definition: conflicts.c:123
static bool aliasing_across_formal_parameters_p
Definition: conflicts.c:66
bool references_may_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:426
static bool cells_maymust_conflict_p(cell c1, cell c2, bool must_p)
Check if two cell may or must conflict.
Definition: conflicts.c:667
void set_conflict_testing_properties()
conflicts.c
Definition: conflicts.c:68
bool entities_maymust_conflict_p(entity e1, entity e2, bool must_p)
Check if two entities may or must conflict.
Definition: conflicts.c:771
bool effects_may_read_or_write_scalar_entity_p(list fx, entity e)
check whether scalar entity e may be read or written by effects fx or cannot be accessed at all
Definition: conflicts.c:1214
static bool aliasing_across_types_p
Definition: conflicts.c:65
bool effects_conflict_p(effect eff1, effect eff2)
Synonym for effects_may_conflict_p().
Definition: conflicts.c:246
static bool old_effects_conflict_p(effect eff1, effect eff2)
OBSOLETE, was never used !!
Definition: conflicts.c:180
bool effects_must_read_or_write_scalar_entity_p(list fx, entity e)
check whether scalar entity e must be read or written by any effect of fx or if it simply might be ac...
Definition: conflicts.c:1235
bool generic_effects_maymust_read_or_write_scalar_entity_p(list fx, entity e, bool must_p, bool concrete_p)
Definition: conflicts.c:1144
bool cells_may_conflict_p(cell c1, cell c2)
Check if two cell may conflict.
Definition: conflicts.c:696
bool variable_references_may_conflict_p(entity v, list sl1, list sl2)
FIXME ?
Definition: conflicts.c:314
bool effects_must_conflict_p(effect eff1, effect eff2)
Intersection tests.
Definition: conflicts.c:93
bool concrete_effects_maymust_read_or_write_scalar_entity_p(list fx, entity e, bool must_p)
Definition: conflicts.c:1202
static bool trust_constant_path_effects_p
Definition: conflicts.c:63
static bool constant_path_effects_p
Properties settings for conflict testing functions.
Definition: conflicts.c:62
bool effects_may_read_or_write_memory_paths_from_entity_p(list l_eff, entity e)
tests whether the input effects list may contain effects with a memory path from the input entity e; ...
Definition: conflicts.c:1130
bool points_to_cell_lists_may_conflict_p(list l1, list l2)
Same as above, but for lists.
Definition: conflicts.c:703
list effects_entities_which_may_conflict_with_scalar_entity(list fx, entity e)
Definition: conflicts.c:1273
bool array_references_may_conflict_p(list sl1, list sl2)
Check if there may be a conflict between two array references.
Definition: conflicts.c:276
bool effect_may_read_or_write_memory_paths_from_entity_p(effect ef, entity e)
misc functions
Definition: conflicts.c:1103
bool effects_may_conflict_p(effect eff1, effect eff2)
Check if two effect may conflict @description Two effects may conflict if their abstract two location...
Definition: conflicts.c:162
bool references_must_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:607
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
#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
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define 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 list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define same_string_p(s1, s2)
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
#define false
Definition: newgen_types.h:80
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
bool entity_register_p(entity e)
Definition: entity.c:766
bool entity_formal_p(entity p)
is p a formal parameter?
Definition: entity.c:1935
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool std_file_entity_p(entity e)
Definition: entity.c:1232
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
bool entity_function_p(entity e)
Definition: entity.c:724
bool effects_package_entity_p(entity e)
checks if an entity is an IO_EFFECTS_PACKAGE_NAME, a MALLOC_EFFECTS_NAME or a RAND_EFFECTS_PACKAGE_NA...
Definition: entity.c:1181
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
entity expression_variable(expression e)
Definition: expression.c:532
bool reference_scalar_p(reference r)
This function returns true if Reference r is scalar.
Definition: expression.c:3530
bool extended_expression_constant_p(expression exp)
Returns true if the value of the expression does not depend syntactically on the current store.
Definition: expression.c:2461
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
bool variable_return_p(entity)
True if a variable is the pseudo-variable used to store value returned by a function:
Definition: variable.c:1522
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70
bool variable_entities_may_conflict_p(entity, entity)
Definition: size.c:689
bool type_equal_p(type, type)
Definition: type.c:547
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
bool type_union_variable_p(type)
Definition: type.c:3877
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
bool type_struct_variable_p(type)
Definition: type.c:3867
#define type_functional_p(x)
Definition: ri.h:2950
#define value_reference(x)
Definition: ri.h:3085
#define reference_undefined
Definition: ri.h:2302
#define reference_variable(x)
Definition: ri.h:2326
#define reference_undefined_p(x)
Definition: ri.h:2303
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_variable(x)
Definition: ri.h:2949
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define reference_indices(x)
Definition: ri.h:2328
#define preference_reference(x)
Definition: ri.h:2102
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_initial(x)
Definition: ri.h:2796
s1
Definition: set.c:247
#define intptr_t
Definition: stdint.in.h:294
The structure used to build lists in NewGen.
Definition: newgen_list.h:41