PIPS
effects.c
Go to the documentation of this file.
1 /*
2 
3  $Id: effects.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 /* Created by B. Apvrille, april 11th, 1994 */
28 /* functions related to types effects and effect, cell, reference and
29  gap */
30 
31 #include <stdio.h>
32 
33 #include "linear.h"
34 
35 #include "genC.h"
36 
37 #include "ri.h"
38 #include "effects.h"
39 
40 /* #include"mapping.h" */
41 #include "misc.h"
42 
43 #include "ri-util.h"
44 #include "prettyprint.h"
45 #include "properties.h"
46 #include "effects-util.h"
47 #include "text.h"
48 #include "text-util.h"
49 
50 ␌
51 /* functions for entity */
53 {
54  return(cell_entity(effect_cell(e)));
55 }
56 
58 {
59  if (cell_gap_p(c)) return entity_undefined;
60 
61  else return(reference_variable(cell_any_reference(c)));
62 }
63 
65 {
66  list l_res = NIL;
67  if (cell_gap_p(c))
68  pips_internal_error("GAPs not implemented yet\n");
69  else
71  return l_res;
72 }
73 
74 
75 /* API for reference */
76 
78 {
79  if (cell_gap_p(c)) return reference_undefined;
80 
81  return (cell_reference_p(c)) ? cell_reference(c) :
83 }
84 
85 /* Does the set of locations referenced by r depend on a pointer
86  * dereferencing?
87  *
88  * Let's hope that all Fortran 77 references will return false...
89  *
90  * See effect_reference_dereferencing_p()
91 */
93 {
94  bool dereferencing_p = false;
96  type vt = entity_type(v);
98  list sl = reference_indices(r); // subscript list
99 
100  // FI: constant string such as "hello world" are used ni reference
101  // although they are 0-ary functions
102  if(! type_functional_p(vt)) {
103 
104  /* Get rid of simple Fortran-like array accesses */
106  /* This is a simple array access */
107  dereferencing_p = false;
108  }
109  else if(!ENDP(sl)) {
110  /* cycle with alias-classes library: import explictly */
113  pips_internal_error("Do we want to subscript abstract locations?");
114  }
115  else if(false /* entity_heap_variable_p(v)*/) {
116  /* Heap modelization is behind*/
117  }
118  else if(entity_variable_p(v)) {
119  /* Let's walk the subscript list and see if the type associated
120  * to the nth subscript is a pointer type and if the (n+1)th
121  * subscript is a zero.
122  */
123  list csl = sl; // current subscript list
124  type ct = uvt; // current type
125  if(pointer_type_p(uvt)) {
126  /* Since it is subscripted, there is dereferencing */
127  dereferencing_p = true;
128  csl = NIL;
129  }
130  else if(array_type_p(uvt)) {
131  variable v = type_variable(uvt);
132  int d = (int) gen_length(variable_dimensions(v));
133  int sn = (int) gen_length(sl);
134  if(sn<=d) {
135  dereferencing_p = false;
136  csl = NIL;
137  }
138  else {
139  ct = array_type_to_element_type(uvt);
140  int i;
141  for(i=1;i<=d;i++)
142  POP(csl);
143  }
144  }
145  else if(struct_type_p(uvt)) {
146  int sn = (int) gen_length(sl);
147  if(sn<=1) {
148  dereferencing_p = false;
149  csl = NIL;
150  }
151  else {
152  expression s = EXPRESSION(CAR(sl));
154  POP(csl);
155  }
156  }
157  else {
158  ; // FI: do nothing but acceleration possible with struct_type_p()
159  }
160  while(!dereferencing_p && !ENDP(csl)) {
161  expression se = EXPRESSION(CAR(csl));
163  if(pointer_type_p(ct) && !ENDP(CDR(csl))) {
164  dereferencing_p = true;
165  }
166  else if(array_type_p(ct)) {
167  int n = (int) array_type_dimension(ct);
168  for(int i = 0; i<n && !ENDP(csl); i++) {
169  POP(csl);
170  if(i>0) {
171  // Update ct
172  expression se = EXPRESSION(CAR(csl));
174  }
175  }
176  }
177  else {
178  POP(csl);
179  }
180  }
181  }
182  else {
183  pips_internal_error("Unexpected entity kind \"%s\"", entity_name(v));
184  }
185  }
186  else {
187  /* No dereferencing */
188  ;
189  }
190  }
191 
192  return dereferencing_p;
193 }
194 
195 
196 /* Future API for GAP, Generic Access Path*/
197 
198 /* ---------------------------------------------------------------------- */
199 /* list-effects conversion functions */
200 /* ---------------------------------------------------------------------- */
201 
203 list l_eff;
204 {
205  effects res = make_effects(l_eff);
206  return res;
207 }
208 
210 effects efs;
211 {
212  list l_res = effects_effects(efs);
213  return l_res;
214 }
215 
217 statement_mapping l_map;
218 {
220 
221  STATEMENT_MAPPING_MAP(s,val,{
222  hash_put((hash_table) efs_map, (char *) s, (char *) list_to_effects((list) val));
223  }, l_map);
224 
225  return efs_map;
226 }
227 
229 statement_mapping efs_map;
230 {
232 
233  STATEMENT_MAPPING_MAP(s,val,{
234  hash_put((hash_table) l_map, (char *) s, (char *) effects_to_list((effects) val));
235  }, efs_map);
236 
237  return l_map;
238 }
239 
240 
241 
242 /* Return true if the statement has a write effect on at least one of
243  the argument (formal parameter) of the module. Note that the return
244  variable of a function is also considered here as a formal
245  parameter. */
246 bool
248  entity module,
249  statement_mapping effects_list_map)
250 {
251  bool write_effect_on_a_module_argument_found = false;
252  list effects_list = (list) GET_STATEMENT_MAPPING(effects_list_map, s);
253 
254  FOREACH(EFFECT, an_effect, effects_list)
255  {
257 
258  if (action_write_p(effect_action(an_effect))
261  module))) {
262  write_effect_on_a_module_argument_found = true;
263  break;
264  }
265  }
266 
267  return write_effect_on_a_module_argument_found;
268 
269 }
270 
271 /*********************** EFFECTS AND ABSTRACT LOCATIONS */
272 
274 {
275  pips_assert("cell is not a GAP", !cell_gap_p(c));
276 
278 }
279 
281 {
283 }
284 
285 /* Returns true if at least one effect of effect list el is related to
286  * an abstract location
287  */
289 {
290  bool abstract_p = false;
291 
292  FOREACH(EFFECT, e, el) {
294  abstract_p = true;
295  break;
296  }
297  }
298  return abstract_p;
299 }
300 
301 
302 
303 ␌
304 /* Anywhere effect: an effect which can be related to any location of any areas */
305 
306 /* Allocate a new anywhere effect, and the anywhere entity on demand
307  which may not be best if we want to express it's aliasing with all
308  module areas. In the later case, the anywhere entity should be
309  generated by bootstrap and be updated each time new areas are
310  declared by the parsers. I do not use a persistant anywhere
311  reference to avoid trouble with convex-effect nypassing of the
312  persistant pointer.
313 
314  Action a is integrated in the new effect (aliasing).
315  NOT GENERIC AT ALL. USE make_anywhere_effect INSTEAD (BC).
316  */
318 {
319  entity anywhere = entity_all_locations();
320  effect any = effect_undefined;
321 
323  ac,
326 
327  return any;
328 }
329 
330 /* Is it an anywhere effect (kind=0)? a typed anywhere effect (kind=1)
331  * ? or any kind of anywhere effect (kind=2)?
332  */
333 static bool generic_anywhere_effect_p(effect e, int kind)
334 {
335  bool anywhere_p;
337  entity v = reference_variable(r);
338 
339  anywhere_p = (entity_all_locations_p(v) && (kind==0||kind==2))
340  || (entity_typed_anywhere_locations_p(v) && (kind==1||kind==2));
341 
342  return anywhere_p;
343 }
344 
345 /* Is it an anywhere effect? *ANYMMODULE*:*ANYWHERE* */
347 {
348  return generic_anywhere_effect_p(e, 0);
349 }
350 
351 /* Is it a typed anywhere effect? *ANYMMODULE*:*ANYWHERE*_b0, 1, 2 */
353 {
354  return generic_anywhere_effect_p(e, 1);
355 }
356 
357 /* Is it a typed or untyped anywhere effect? */
359 {
360  return generic_anywhere_effect_p(e, 2);
361 }
362 
363 /* Is it an anywhere cell?
364  *
365  * Are typed anywhere celles taken into account?
366  */
368 {
369  bool anywhere_p;
371  entity v = reference_variable(r);
372 
373  anywhere_p = entity_all_locations_p(v);
374 
375  return anywhere_p;
376 }
377 
379 {
380  bool anywhere_p;
381  entity v = reference_variable(r);
382 
383  anywhere_p = entity_all_locations_p(v);
384 
385  return anywhere_p;
386 }
387 
388 
389 
390 ␌
392 {
394  effect any = effect_undefined;
395 
396  if(entity_undefined_p(heap)) {
397  pips_internal_error("Heap for module \"%s\" not found", entity_name(m));
398  }
399 
401  ac,
404 
405  return any;
406 }
407 
409 {
410  bool heap_p;
412  entity v = reference_variable(r);
413 
415 
416  return heap_p;
417 }
418 
419 /* Any heap cell, more or less abstract or typed */
421 {
422  bool heap_p;
424  entity v = reference_variable(r);
425 
426  heap_p = (strstr(entity_local_name(v), HEAP_AREA_LOCAL_NAME)
427  ==entity_local_name(v));
428 
429  return heap_p;
430 }
431 
433 {
434  bool heap_p;
436  entity v = reference_variable(r);
437 
438  heap_p = entity_all_heap_locations_p(v);
439 
440  return heap_p;
441 }
442 
443 //bool all_heap_locations_typed_cell_p(cell c)
444 //{
445 // bool heap_p;
446 // reference r = cell_any_reference(c);
447 // entity v = reference_variable(r);
448 //
449 // heap_p = entity_all_heap_locations_typed_p(v);
450 //
451 // return heap_p;
452 //}
453 
454 /* Target of an undefined pointer */
456 {
457  bool nowhere_p;
459  entity v = reference_variable(r);
460 
461  nowhere_p = entity_typed_nowhere_locations_p(v);
462 
463  return nowhere_p;
464 }
465 
467 {
468  bool null_p;
470  entity v = reference_variable(r);
471 
472  null_p = entity_null_locations_p(v);
473 
474  return null_p;
475 }
476 
477 
479 {
481 }
482 
484 {
486 }
487 
489 {
491 }
492 
493 
494 
495 /*************** I/O EFFECTS *****************/
497 {
498  return io_luns_entity_p(e);
499 }
500 
502 {
504 }
505 
507 {
509 }
510 
511 
513 {
514  FOREACH(EFFECT,eff,effects)
515  if(io_effect_p(eff)) return true;
516  return false;
517 }
518 
520 {
521  return(std_file_entity_p(effect_entity(e)));
522 }
523 
525 {
526  return(std_file_entity_p(cell_entity(c)));
527 }
528 
530 {
531  FOREACH(EFFECT,eff,effects)
532  if(std_file_effect_p(eff)) return true;
533  return false;
534 }
535 
537 {
538  bool res = false;
540  pips_debug(8, "begin with type %s\n", string_of_type(t));
541  if (type_variable_p(t))
542  {
544  if (basic_pointer_p(b))
545  {
546  t = basic_pointer(b);
547  if (type_variable_p(t))
548  {
550  if (basic_derived_p(b))
551  {
552  entity te = basic_derived(b);
553  if (same_string_p(entity_user_name(te), "_IO_FILE"))
554  {
555  res = true;
556  }
557  }
558  }
559  }
560  }
561  pips_debug(8, "end with : %s\n", res? "true":"false");
562  return res;
563 }
564 
565 
566 
568 {
569  bool scalar_p = false;
571  list sl = reference_indices(r);
572  if(ENDP(sl)) {
573  entity v = reference_variable(r);
574  type t = entity_type(v); // basic_concrete_type?
575  int d = type_depth(t);
576  if(d==0)
577  scalar_p = true;
578  else {
579  scalar_p = pointer_type_p(t);
580  }
581  }
582  return scalar_p;
583 }
584 
585 /* Can we merge these two effects because they are equal or because
586  they only differ by their approximations and their descriptors? */
588 {
589  bool comparable_p = false;
592  entity v1 = reference_variable(r1);
593  entity v2 = reference_variable(r2);
594 
595  if(v1==v2) {
596  action a1 = effect_action(e1);
597  action a2 = effect_action(e2);
598  if(action_equal_p(a1, a2))
599  {
600 
601  /* Check the subscript lists because p and p[0] do not refer
602  the same memory locations at all */
603  list sl1 = reference_indices(r1);
604  list sl2 = reference_indices(r2);
605  if(gen_length(sl1)==gen_length(sl2))
606  {
607  list csl1 = list_undefined;
608  list csl2 = list_undefined;
609  bool equal_p = true;
610 
611  for(csl1=sl1, csl2=sl2; !ENDP(csl1) && equal_p; POP(csl1), POP(csl2))
612  {
613  expression e1 = EXPRESSION(CAR(csl1));
614  expression e2 = EXPRESSION(CAR(csl2));
615  equal_p = expression_equal_p(e1, e2);
616  }
617  comparable_p = equal_p;
618  }
619 
620  }
621  }
622 
623  return comparable_p;
624 }
625 
626 
627 /* Does this effect define the same set of memory locations
628  * regardless of the current (environment and) memory state?
629  *
630  * This function works only for standard references, not for points-to
631  * references, but is partially extended to cope with one anywhere...
632  *
633  * FI: I do not understand why pointers could be indexed in standard
634  * references.
635  */
637 {
638  bool independent_p = false;
639 
640  ifdebug(1) {
642  pips_assert("Effect eff is consistent", effect_consistent_p(eff));
643  pips_assert("The reference is consistent", reference_consistent_p(r));
644  }
645 
646  if(anywhere_effect_p(eff))
647  independent_p = true;
648  else {
650  entity v = reference_variable(r);
652 
653  if(pointer_type_p(t)) {
654  list inds = reference_indices(r);
655 
656  independent_p = ENDP(inds);
657  }
658  else {
659  pips_assert("The reference is consistent", reference_consistent_p(r));
660 
661  independent_p = reference_with_constant_indices_p(r);
662  }
663  }
664 
665  return independent_p;
666 }
667 
668 /* Test if an effect has a non local effect
669 
670  @param[in] eff is the effect to analyse
671 
672  @return true if the effect is on a non local effect
673 */
675  return !same_string_p(
678  );
679 }
680 
681 /* Test if a list of effects concerns non local variables
682 
683  @param[in] effects is the effect list to scan
684 
685  @return true if there is an effect on a global variable
686 */
688  FOREACH(EFFECT,eff,effects)
690  //char * seffect = effect_to_string(eff);
691  //pips_user_warning("effect on non local variable: %s\n",seffect);
692  //free(seffect);
693  return true;
694  }
695  return false;
696 }
697 
698 
699 ␌
700 /* Two effects interfere if one of them modify the set of locations
701  defined by the other one. For instance, an index or a pointer may
702  be used by one effect and changed by the other one.
703 
704  If a subscript expression is changed, the corresponding subscript
705  must be replaced by an unbounded expression.
706 
707  If a pointer is written, any indirect effect thru this pointer must
708  be changed into a read or write anywhere.
709 
710  This function is conservative: it is always correct to declare an interference.
711 
712  FI: I'm not sure what you can do when you know two effects interfere...
713  */
715 {
716  action ac1 = effect_action(eff1);
717  action ac2 = effect_action(eff2);
718  bool interfere_p = false;
719 
720  if(action_write_p(ac1)||action_write_p(ac2)) {
721  if(anywhere_effect_p(eff1) && action_write_p(ac1)) {
722  interfere_p = !store_independent_effect_p(eff2);
723  }
724  else if(anywhere_effect_p(eff2) && action_write_p(ac2)) {
725  interfere_p = !store_independent_effect_p(eff1);
726  }
727  else { /* dealing with standard effects */
728 
729  /* start with complex cases */
730  /* The write effect is a direct effet, the other effect may be
731  direct or indirect, indexed or not. */
735 
736  list rind = list_undefined;
737 
738  if(action_write_p(ac1)) {
739  wr = effect_any_reference(eff1);
740  rr = effect_any_reference(eff2);
741  }
742  else {
743  wr = effect_any_reference(eff2);
744  rr = effect_any_reference(eff1);
745  }
746 
747  wv = reference_variable(wr);
748  rind = reference_indices(rr);
749 
750  /* Does the write impact the indices of the read? */
751  MAP(EXPRESSION, s, {
752  list rl = NIL;
753 
754  rl = expression_to_reference_list(s, rl);
755  MAP(REFERENCE, r, {
756  entity v = reference_variable(r);
757  if(wv==v) {
758  interfere_p = true;
759  break;
760  }
761  }, rl);
762  if(interfere_p)
763  break;
764  }, rind);
765 
766  //interfere_p = true;
767  }
768  }
769  return interfere_p;
770 }
771 ␌
773 {
775  entity v = reference_variable(r);
777 
778  if(pointer_type_p(t)) {
780  free_effect(eff);
781  eff = n_eff;
782  }
783  else{
784  list ind = reference_indices(r);
785  list cind = list_undefined;
786 
787  for(cind = ind; !ENDP(cind); POP(cind)) {
788  expression e = EXPRESSION(CAR(cind));
789 
790  if(!unbounded_expression_p(e)) {
792  free_expression(e);
794  }
795  }
796  }
797  }
798 
799  return eff;
800 }
801 
802 /* Modify eff so that the set of memory locations decribed after a
803  write to some pointer p is still in the abstract location set of eff.
804 
805  \\n_eff
806  p = ...;
807  \\ eff of stmt s
808  s;
809 
810  If p is undefined, assumed that any pointer may have been updated.
811 
812  As a pointer could be used in indexing, the current implementation
813  is not correct/sufficient
814  */
816 {
818  entity v = reference_variable(r);
819  //type t = ultimate_type(entity_type(v));
820 
821  if(entity_undefined_p(p) || v==p) {
822  if(!ENDP(reference_indices(r))) {
823  /* p[i][j] cannot be preserved */
825  free_effect(eff);
826  eff = n_eff;
827  }
828  else {
829  /* No problem: direct scalar reference */
830  ;
831  }
832  }
833  return eff;
834 }
835 
836 /* Modify eff so that the set of memory locations decribed after a
837  write to some non pointer variable is still in the abstract location set of eff.
838 
839  \\n_eff
840  i = ...;
841  \\ eff of stmt s: p[j], q[i],..
842  s;
843  */
845 {
847  //entity v = reference_variable(r);
848  //type t = ultimate_type(entity_type(v));
849 
851 
852  return eff;
853 }
854 ␌
855  /* Modifies effect eff1 to make sure that any memory state
856  modification abstracted by eff2 preserves the correctness of
857  eff1: all memory locations included in eff1 at input are included
858  in the memory locations abstracted by the new eff1 after the
859  abstract state transition.
860 
861  FI: seems to extend naturally to new kinds of effects...
862  */
864 {
865  //action ac1 = effect_action(eff1);
866  action ac2 = effect_action(eff2);
867  effect n_eff1 = eff1; /* default value */
868 
869  ifdebug(1) {
870  pips_assert("The new effect is consistent", effect_consistent_p(eff1));
871  pips_assert("The new effect is consistent", effect_consistent_p(eff2));
872  }
873 
874  if(store_independent_effect_p(eff1)) {
875  /* nothing to worry about */
876  ;
877  }
878  else if(action_write_p(ac2)) {
879  if(anywhere_effect_p(eff2)) {
880  // free_effect(eff1);
881  n_eff1 = effect_to_store_independent(eff1);
882  }
883  else {
884  reference r2 = effect_any_reference(eff2);
885  entity v2 = reference_variable(r2);
886  type t2 = ultimate_type(entity_type(v2));
887 
888  if(pointer_type_p(t2)) {
889  /* pointer-dependence write, indexed or not */
891  }
892  else {
893  /* The base address for the write is constant, the indices should be be checked */
894  /* The write effect is a direct effet, the other effect may be
895  direct or indirect, indexed or not. */
896  reference r1 = effect_any_reference(eff1);
897  list ind1 = reference_indices(r1);
898  list cind1 = list_undefined;
899 
900  /* FI: should be very similar to reference_with_store_independent_indices()? */
901 
902  /* Does the write impact some indices of the read? */
903  for(cind1 = ind1; !ENDP(ind1); POP(ind1)) {
904  expression s = EXPRESSION(CAR(cind1));
905  list rl = NIL;
906  list crl = list_undefined;
907  bool interfere_p = false;
908 
909  rl = expression_to_reference_list(s, rl);
910  for(crl=rl; !ENDP(rl); POP(rl)) {
911  reference r = REFERENCE(CAR(crl));
912  entity v = reference_variable(r);
913  if(v2==v) {
914  interfere_p = true;
915  break;
916  }
917  }
918 
919  if(interfere_p) {
920  pips_debug(8, "Interference detected\n");
921  /* May be shared because of persistant references */
922  //free_expression(s);
924  }
925  }
926  }
927  }
928  }
929  ifdebug(1)
930  pips_assert("The new effect is consistent", effect_consistent_p(n_eff1));
931  return n_eff1;
932 }
933 ␌
934 /* Functions dealing with actions */
935 
937 {
938  /* This is correct, but imprecise when action_kinds are taken into
939  account */
940  return action_read_p(ac)? "read" : "write";
941 }
942 
944 {
945  string s = string_undefined;
946  if(action_read_p(ac)) {
947  action_kind ak = action_read(ac);
948 
949  if(action_kind_store_p(ak))
950  s = "read memory";
951  else if(action_kind_environment_p(ak))
952  s = "read environment";
953  else if(action_kind_type_declaration_p(ak))
954  s = "read type";
955  }
956  else {
957  action_kind ak = action_write(ac);
958 
959  if(action_kind_store_p(ak))
960  s = "write memory";
961  else if(action_kind_environment_p(ak))
962  s = "write environment";
963  else if(action_kind_type_declaration_p(ak))
964  s = "write type";
965  }
966  return s;
967 }
968 
970 {
971  string s = string_undefined;
972  if(action_read_p(ac)) {
973  action_kind ak = action_read(ac);
974 
975  if(action_kind_store_p(ak))
976  s = "R";
977  else if(action_kind_environment_p(ak))
978  s = "RE";
979  else if(action_kind_type_declaration_p(ak))
980  s = "RT";
981  }
982  else {
983  action_kind ak = action_write(ac);
984 
985  if(action_kind_store_p(ak))
986  s = "W";
987  else if(action_kind_environment_p(ak))
988  s = "WE";
989  else if(action_kind_type_declaration_p(ak))
990  s = "WT";
991  }
992  return s;
993 }
994 
996 {
997  string s = string_undefined;
998 
999  if(action_kind_store_p(ak))
1000  s = "S";
1001  else if(action_kind_environment_p(ak))
1002  s = "E";
1003  else if(action_kind_type_declaration_p(ak))
1004  s = "T";
1005  else
1006  pips_internal_error("Unknown action kind.");
1007  return s;
1008 }
1009 
1010 /* To ease the extension of action with action_kind */
1012 {
1014  return a;
1015 }
1016 
1018 {
1020  return a;
1021 }
1022 
1024 {
1025  bool equal_p = false;
1026 
1027  if(action_tag(a1)==action_tag(a2)) {
1028  if(action_read_p(a1)) {
1029  action_kind ak1 = action_read(a1);
1030  action_kind ak2 = action_read(a2);
1031 
1032  equal_p = action_kind_tag(ak1)==action_kind_tag(ak2);
1033  }
1034  else /* action_write_p(a1) */ {
1035  action_kind ak1 = action_write(a1);
1036  action_kind ak2 = action_write(a2);
1037 
1038  equal_p = action_kind_tag(ak1)==action_kind_tag(ak2);
1039  }
1040  }
1041  return equal_p;
1042 
1043 }
1044 
1045 /* Without the consistency test, this function would certainly be
1046  inlined. Macros are avoided to simplify debugging and
1047  maintenance. */
1049 {
1050  pips_assert("consistent action kind.",action_read_p(a) || action_write_p(a));
1052  return ak;
1053 }
1054 
1056 {
1057  action ac = effect_action(eff);
1058  return action_to_action_kind(ac);
1059 }
1060 
1061 ␌
1063 {
1064  action a = effect_action(e);
1066  bool store_p = action_kind_store_p(ak);
1067 
1068  return store_p;
1069 }
1070 
1072 {
1073  action a = effect_action(e);
1075  bool env_p = action_kind_environment_p(ak);
1076 
1077  return env_p;
1078 }
1079 
1081 {
1082  action a = effect_action(e);
1084  bool decl_p = action_kind_type_declaration_p(ak);
1085 
1086  return decl_p;
1087 }
1088 
1089 
1090 
1092 {
1093  bool result = false;
1094  if(v) {
1095  FOREACH(EFFECT, e, el) {
1096  action a = effect_action(e);
1097  entity ev = effect_entity(e);
1098  if (action_write_p(a) && store_effect_p(e)
1099  && entities_may_conflict_p(ev,v) ) {
1100  result = true;
1101  break;
1102  }
1103  }
1104  }
1105  return result;
1106 }
1107 
1109 {
1110  bool result = false;
1111 
1112  FOREACH(EFFECT, e, el) {
1113  action a = effect_action(e);
1114  if (action_write_p(a) && store_effect_p(e)) {
1115  result = true;
1116  break;
1117  }
1118  }
1119 
1120  return result;
1121 }
1122 
1124 {
1125  bool result = false;
1126  if(v) {
1127  FOREACH(EFFECT, e, el) {
1128  action a = effect_action(e);
1129  entity ev = effect_entity(e);
1130  if (action_read_p(a) && store_effect_p(e)
1131  && entities_may_conflict_p(ev,v) ) {
1132  result = true;
1133  break;
1134  }
1135  }
1136  }
1137  return result;
1138 }
1139 
1140 /* Check that all effects in el are read effects */
1142 {
1143  bool result = true;
1144  FOREACH(EFFECT, e, el) {
1145  action a = effect_action(e);
1146  //entity ev = effect_entity(e);
1147  if (action_write_p(a)) {
1148  result = false;
1149  break;
1150  }
1151  }
1152  return result;
1153 }
1154 ␌
1155 /* Check if some references might be freed with the effects. This may
1156  lead to disaster if the references are part of another PIPS data
1157  structure. This information is not fully accurate, but
1158  conservative. */
1160 {
1161  bool safe_p = true;
1162  FOREACH(EFFECT, e, el) {
1163  cell c = effect_cell(e);
1164  if(cell_reference_p(c)) {
1165  reference r = cell_reference(c);
1166  list inds = reference_indices(r);
1167 
1168  if(ENDP(inds)) {
1169  /* The free is very likely to be unsafe */
1170  //entity v = reference_variable(r);
1171  safe_p = false;
1172  //fprintf(stderr, "cell_reference for %s", entity_name(v));
1173  }
1174  else {
1175  /* Is it a possible C reference or is it a synthetic reference
1176  generated by the effect analysis? Hard to decide... */
1177  //entity v = reference_variable(r);
1178  //fprintf(stderr, "cell_reference for %s", entity_name(v));
1179  //print_reference(r);
1180  }
1181  break;
1182  }
1183  }
1184  return safe_p;
1185 }
1186 
1187 
1188 /******************************************* COMBINATION OF APPROXIMATIONS */
1189 
1190 
1191 
1192 /* tag approximation_and(tag t1, tag t2)
1193  * input : two approximation tags.
1194  * output : the tag representing their "logical and", assuming that
1195  * must = true and may = false.
1196  * modifies : nothing
1197  */
1199 {
1200  if ((t1 == is_approximation_exact) && (t2 == is_approximation_exact))
1201  return(is_approximation_exact);
1202  else
1203  return(is_approximation_may);
1204 }
1205 
1206 
1207 /* tag approximation_or(tag t1, tag t2)
1208  * input : two approximation tags.
1209  * output : the tag representing their "logical or", assuming that
1210  * must = true and may = false.
1211  * modifies : nothing
1212  */
1214 {
1215  if ((t1 == is_approximation_exact) || (t2 == is_approximation_exact))
1216  return(is_approximation_exact);
1217  else
1218  return(is_approximation_may);
1219 }
1220 
1221 
1222 /** CELLS */
1223 /* test if two cells are equal; cells are supposed to be
1224  references. */
1225 
1226 bool cell_equal_p(cell c1, cell c2)
1227 {
1228  /* Has to be extended for GAPs */
1229  reference r1 = cell_to_reference(c1);
1230  reference r2 = cell_to_reference(c2);
1231  return reference_equal_p(r1, r2);
1232 }
1233 
1235 {
1236  /* Has to be extended for GAPs */
1237  reference r1 = cell_to_reference(c1);
1238  reference r2 = cell_to_reference(c2);
1239  return reference_variable(r1)==reference_variable(r2);
1240 }
1241 
1242 /* FI->FC/AM: some elements of the lattice must be exploited here... */
1244 {
1245  bool included_p = true;
1246  entity v1 = reference_variable(r1);
1247  entity v2 = reference_variable(r2);
1248 
1249  list dims1 = reference_indices(r1);
1250  list dims2 = reference_indices(r2);
1251 
1252  if(v1 == v2) {
1253  if(gen_length(dims1)==gen_length(dims2)) {
1254  list cdims2 = dims2;
1255  FOREACH(EXPRESSION, s1, dims1) {
1256  expression s2 = EXPRESSION(CAR(cdims2));
1257  if(!expression_equal_p(s1,s2)) {
1258  if(!unbounded_expression_p(s2)) {
1259  included_p = false;
1260  break;
1261  }
1262  }
1263  cdims2 = CDR(cdims2);
1264  }
1265  }
1266  else if(gen_length(dims1)>gen_length(dims2)) {
1267  list cdims1 = dims1;
1268  FOREACH(EXPRESSION, s2, dims2) {
1269  expression s1 = EXPRESSION(CAR(cdims1));
1270  if(!expression_equal_p(s1,s2)) {
1271  if(!unbounded_expression_p(s2)) {
1272  included_p = false;
1273  break;
1274  }
1275  }
1276  cdims1 = CDR(cdims1);
1277  }
1278  }
1279  else {
1280  included_p = false;
1281  }
1282  }
1283  else {
1284  // pips_internal_error("Abstract location lattice not implemented here.\n");
1285  // FI->AM/FC: you should check the inclusion of abstract_location(v1) and
1286  // abstract_location(v2)...
1287  included_p = false;
1288  }
1289  return included_p;
1290 }
1291 
1292 /* Check that all memory locations denoted by cell "c1" are included
1293  in cell "c2". */
1295 {
1296  /* Has to be extended for GAPs */
1297  reference r1 = cell_any_reference(c1);
1298  reference r2 = cell_any_reference(c2);
1299  return points_to_reference_included_p(r1, r2);
1300 }
1301 
1302 /* Check that memory locations denoted by cell "c1" can be reached by knowing
1303  * cell "c2" and by using pointer arithmetic or subscripting.
1304  *
1305  * In other words, the two cells only differ by their
1306  * subscripts... Which might be reducible to "based on the same
1307  * entity".
1308  *
1309  * FI: experimental...
1310  */
1312 {
1313  /* Has to be extended for GAPs */
1314  reference r1 = cell_any_reference(c1);
1315  reference r2 = cell_any_reference(c2);
1316  entity v1 = reference_variable(r1);
1317  entity v2 = reference_variable(r2);
1318  return v1==v2;
1319 }
1320 
1321 
1322 /* FI: probably to be moved elsewhere in ri-util */
1323 /* Here, we only know how to cope (for the time being) with
1324  cell_reference and cell_preference, not with cell_gap and other
1325  future fields. A bit safer than macro cell_any_reference(). */
1328 
1329  if (cell_reference_p(c))
1330  r = cell_reference(c);
1331  else if (cell_preference_p(c))
1333  else
1334  pips_internal_error("GAPs not implemented yet or unexpected cell tag.\n");
1335 
1336  return r;
1337 }
1338 ␌
1339 /* Debugging */
1341 {
1342  bool ok_p = true;
1343 
1344  FOREACH(EFFECT, e, el)
1345  ok_p = ok_p && effect_consistent_p(e);
1346 
1347  return ok_p;
1348 }
1349 
1350 
1351 /* DO NOT USE ANYMORE: NOT COMPATIBLE WITH ABSTRACT LOCATIONS */
1352 /* besides, I do not see the interest after having called effects_compatible_p. BC */
1353 /* Check compatibility conditions for effect union */
1355 {
1356  action a1 = effect_action(ef1);
1357  tag at1 = action_tag(a1);
1359  tag akt1 = action_kind_tag(ak1);
1360  entity e1 = effect_variable(ef1);
1361  descriptor d1 = effect_descriptor(ef1);
1362  action a2 = effect_action(ef2);
1363  tag at2 = action_tag(a2);
1365  tag akt2 = action_kind_tag(ak2);
1366  entity e2 = effect_variable(ef2);
1367  descriptor d2 = effect_descriptor(ef2);
1368  bool compatible_p = true;
1369 
1370  pips_assert("effect e1 is consistent", effect_consistent_p(ef1));
1371  pips_assert("effect e2 is consistent", effect_consistent_p(ef2));
1372 
1373  if(at1!=at2) {
1374  /* In general, you do not want to union a read and a write, but
1375  you might want to do so to generate the set of referenced
1376  elements, for instance to generate communications or to
1377  allocate memory */
1378  compatible_p = false;
1379  }
1380  else if(akt1!=akt2) {
1381  /* You do not want to union an effect on store with an effect on
1382  environment or type declaration */
1383  compatible_p = false;
1384  }
1385  else {
1386  /* Here we know: at1==at2 and akt1==akt2 */
1387  /* The code below could be further unified, but it would not make
1388  it easier to understand */
1389  if(akt1==is_action_kind_store) {
1390  if(e1!=e2) /* Beware: that's not true anymore because of abstract locations */
1391  compatible_p = false;
1392  else {
1393  tag dt1 = descriptor_tag(d1);
1394  tag dt2 = descriptor_tag(d2);
1395 
1396  if(dt1!=dt2)
1397  compatible_p = false;
1398  }
1399  }
1400  else {
1401  /* For environment and type declaration, the descriptor is
1402  useless for the time being */
1403  compatible_p = e1==e2;
1404  }
1405  }
1406 
1407  return compatible_p;
1408 }
1409 
1410 /* Returns the entity corresponding to the mutation. It could be
1411  called effect_to_variable(), but effects are sometimes summarized
1412  with abstract locations, i.e. sets of locations. */
1414 {
1415  /* FI unlikely to work with GAPs */
1417  entity e = reference_variable(r);
1418 
1419  return e;
1420 }
1421 
1422 /* bool vect_contains_phi_p(Pvecteur v)
1423  * input : a vector
1424  * output : true if v contains a PHI variable, false otherwise
1425  * modifies : nothing
1426  */
1428 {
1429  for(; !VECTEUR_NUL_P(v); v = v->succ)
1430  if (variable_phi_p((entity) var_of(v)))
1431  return(true);
1432 
1433  return(false);
1434 }
1435 
1436 ␌
1437 /* Functions about points-to cells - There is no cell.c file */
1438 
1439 /* add a field to a cell if it is meaningful
1440  *
1441  * FI: should we also add the necessary zero subscripts when the field
1442  * is an array?
1443  */
1445 {
1446  if(cell_reference_p(c)) {
1447  reference r = cell_reference(c);
1449  }
1450  else if(cell_preference_p(c)) {
1451  preference pr = cell_preference(c);
1454  }
1455  else if(cell_gap_p(c))
1456  pips_internal_error("Not applicable on gaps.\n");
1457  else
1458  pips_internal_error("Unknown kind of cell.\n");
1459  return c;
1460 }
1461 
1462 /* add a field f as a subscript to a reference r if it is
1463  * meaningful. Leave r unchanged if not.
1464  *
1465  * This function cannot be located in ri-util because it does need to
1466  * know about abstract locations.
1467  *
1468  * This does not build a standard reference, but a reference used
1469  * within effects computation. Field accesses are replaced by
1470  * subscripts.
1471  *
1472  * Note that the reference generated may contain extra 0 subscripts to
1473  * make it scalar...
1474  */
1476 {
1477  entity v = reference_variable(r);
1478 
1479  /* No fields can be added to some special abstract locations. */
1485  || entity_all_heap_locations_p(v) // Not typed, hopefully...
1486  )) {
1487  bool to_be_freed = false;
1488  type t = points_to_reference_to_type(r, &to_be_freed);
1489  //type t = ultimate_type(entity_type(v));
1491 
1492  if(struct_type_p(ut)) {
1494  type st = ultimate_type(entity_type(ste)); // FI: should be concrete_basic_type
1495  list fl = list_undefined;
1496  /* FI: a problem due to typedefs apparently */
1497  if(type_struct_p(st))
1498  fl = type_struct(st);
1499  else if(struct_type_p(st)) {
1501  type nst = ultimate_type(entity_type(nste));
1502  fl = type_struct(nst);
1503  }
1504  else
1505  pips_internal_error("Misunderstanding of struct typing.\n");
1506  entity nf = find_field_in_field_list(f, fl);
1507  if(!entity_undefined_p(nf)) {
1510  CONS(EXPRESSION, s, NIL));
1511  // FI: in case the field is an array
1513  }
1514  else {
1515  entity v = reference_variable(r);
1516  pips_internal_error("No field \"%s\" (\"%s\") for struct \"%s\"(\"%s\")\n",
1518  }
1519  }
1520  else {
1521  /* Take care of special cases */
1524  /* Nothing done when the heap is modeled by a unique entity */
1525  ; // FI: could be useful for unions as well
1526  }
1527  else if(array_of_struct_type_p(ut)) {
1528  extern bool get_int_property(const char *);
1529  bool strict_p = get_bool_property("POINTS_TO_STRICT_POINTER_TYPES");
1530  if(!strict_p) {
1531  // An implicit 0 subscript should be added
1533  // FI: This should be guarded as for the other structures
1534  // Some code should be factorized out
1536  pips_assert("No indices yet.\n", ENDP(reference_indices(r)));
1538  }
1539  }
1542  pips_assert("No indices yet.\n", ENDP(reference_indices(r)));
1544  }
1545  else
1546  pips_internal_error("Attempt at adding a field to an object that is not"
1547  " a struct.\n");
1548  }
1549  if(to_be_freed) free_type(t);
1550  }
1552  || entity_all_heap_locations_p(v) // Not typed, hopefully...?
1553  ) {
1554  /* This kind of entity cannot support a concrete access path but
1555  * the type must be updated according to the field "f"
1556  */
1557  type nt = entity_type(f); // concrete/ultimate_type()?
1560  reference_variable(r) = ne;
1562  }
1563  else if(entity_all_heap_locations_p(v)
1564  && !get_bool_property("ALIASING_ACROSS_TYPES")) {
1565  /* FI: This piece of code should be useless because the
1566  all_heap_locations entity is used only when
1567  ALIASING_ACROSS_TYPES is true. */
1569  reference_variable(r) = ne;
1571  }
1572  }
1573 
1574  return r;
1575 }
1576 
1577 /* Do not check anything, just add f as a last subscript.
1578  *
1579  * See above
1580 */
1582 {
1585  CONS(EXPRESSION, s, NIL));
1586  return r;
1587 }
1588 
1589 /* Convert a reference to an array into a reference to its first element
1590  *
1591  * Note: is this unconditional? Do you add the right number of
1592  * subscripts according to the type?
1593  */
1595 {
1596  bool to_be_freed = false;
1597  type t = type_undefined;
1600  //type at = points_to_array_reference_to_type(r);
1601  //t = array_type_to_element_type(at);
1603  // partial memory leak with "at"?
1604  }
1605  else
1606  t = points_to_cell_to_type(c, &to_be_freed);
1607 
1608  if(zero_p)
1610  else
1612  if(to_be_freed) free_type(t);
1613 }
1614 
1616 {
1618 }
1619 
1621 {
1624 }
1625 
1627 {
1630 }
1631 
1633 {
1635 }
1636 
1637 /* Transform reference a[i]...[j] and expression s into reference
1638  * a[i]..[j+s] if j and s are constant integer expressions, and into
1639  * reference a[i]..[*] otherwise. Cell c is updated by side effect.
1640  *
1641  * This has been implemented in several places...
1642  */
1644 {
1646  list sl = reference_indices(r);
1647  if(ENDP(sl)) {
1648  // FI: we could do something special for heap abstract locations...
1649  // entity v = reference_variable(r);
1650  pips_internal_error("Wrong argument c.\n");
1651  }
1652  else {
1653  list lsl = gen_last(sl);
1654  expression is = EXPRESSION(CAR(lsl));
1655  intptr_t c1, c2;
1657  if(expression_integer_value(is, &c1) && expression_integer_value(s, &c2)) {
1658  ns = int_to_expression((int) c1+c2);
1659  }
1660  else {
1662  }
1663  EXPRESSION_(CAR(lsl)) = ns;
1664  }
1665 }
1666 ␌
1667 
1669 {
1670  bool atomic_p = effect_scalar_p(e);
1671  if(!atomic_p) {
1672  /* Maybe it is an effect on a structure field */
1673  cell c = effect_cell(e);
1674  atomic_p = atomic_points_to_cell_p(c);
1675  }
1676  return atomic_p;
1677 }
1678 ␌
1679 // static list recursive_cell_to_pointer_cells(cell c)
1681 {
1682  list children = NIL;
1683  // Too strong for recursive calls
1684  //pips_assert("Cell \"c\" has no subscripts.",
1685  // ENDP(reference_indices(cell_any_reference(c))));
1686  bool to_be_freed;
1687  type ct = points_to_cell_to_type(c, &to_be_freed);
1688 
1689  if(pointer_type_p(ct)) {
1690  children = CONS(CELL, copy_cell(c), NIL);
1691  }
1692  else if(array_type_p(ct)) {
1693  /* Go down if it is an array of pointers or an array of struct */
1695  /* add indices to cell c */
1696  cell n_c = copy_cell(c);
1697  /* Add subscripts to reach array elements */
1699  children = recursive_cell_to_pointer_cells(n_c);
1700  free_cell(n_c);
1701  }
1702  else {
1703  ; // No children
1704  }
1705  }
1706  else if(struct_type_p(ct)) {
1707  /* Look for fields that are either pointers, or arrays or structs */
1709  entity dte = basic_derived(b);
1710  type dt = entity_type(dte);
1711  list fields = type_struct(dt);
1712  FOREACH(ENTITY, f, fields) {
1714  if(pointer_type_p(ft)
1715  || array_type_p(ft)
1716  || struct_type_p(ft)) {
1717  cell n_c = copy_cell(c);
1718  /* Add field subscript to reference */
1720  children = recursive_cell_to_pointer_cells(n_c);
1721  free_cell(n_c);
1722  }
1723  }
1724  }
1725 
1726  // Too strong for recursive calls
1727  //pips_assert("Cell \"c\" has children, "
1728  // "or this function would not have been called.", !ENDP(children));
1729  return children;
1730 }
1731 
1732 /* If the reference in "c" is not a pointer, see if it can be
1733  * transformed into a pointer reference by adding subscripts, field
1734  * subscripts or a combination of both...
1735  *
1736  * The "children" list is built with new cells. No sharing is created
1737  * between "c" and "children".
1738  */
1740 {
1741  list children = NIL;
1742  pips_assert("Cell \"c\" has no subscripts.",
1744 
1745  children = recursive_cell_to_pointer_cells(c);
1746 
1747  pips_assert("Cell \"c\" has children, "
1748  "or this function would not have been called.", !ENDP(children));
1749  return children;
1750 }
bool null_cell_p(cell c)
Definition: effects.c:466
statement_mapping effectsmap_to_listmap(statement_mapping efs_map)
Definition: effects.c:228
bool statement_has_a_module_formal_argument_write_effect_p(statement s, entity module, statement_mapping effects_list_map)
Return true if the statement has a write effect on at least one of the argument (formal parameter) of...
Definition: effects.c:247
bool std_file_cell_p(cell c)
Definition: effects.c:524
bool effect_comparable_p(effect e1, effect e2)
Can we merge these two effects because they are equal or because they only differ by their approximat...
Definition: effects.c:587
bool malloc_cell_p(cell c)
Definition: effects.c:483
bool effect_scalar_p(effect eff)
Definition: effects.c:567
effect effect_interference(effect eff1, effect eff2)
Modifies effect eff1 to make sure that any memory state modification abstracted by eff2 preserves the...
Definition: effects.c:863
bool malloc_effect_p(effect e)
Definition: effects.c:478
bool cell_included_p(cell c1, cell c2)
Check that all memory locations denoted by cell "c1" are included in cell "c2".
Definition: effects.c:1294
bool effects_all_read_p(list el)
Check that all effects in el are read effects.
Definition: effects.c:1141
void points_to_cell_add_unbounded_subscripts(cell c)
Definition: effects.c:1632
void points_to_cell_add_fixed_subscripts(cell c, bool zero_p)
Convert a reference to an array into a reference to its first element.
Definition: effects.c:1594
effect heap_effect(entity m, action ac)
Definition: effects.c:391
action_kind effect_action_kind(effect eff)
Definition: effects.c:1055
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
bool action_equal_p(action a1, action a2)
Definition: effects.c:1023
list effects_to_list(effects efs)
Definition: effects.c:209
entity effect_entity(effect e)
Created by B.
Definition: effects.c:52
tag approximation_or(tag t1, tag t2)
tag approximation_or(tag t1, tag t2) input : two approximation tags.
Definition: effects.c:1213
string full_action_to_short_string(action ac)
Definition: effects.c:969
bool all_heap_locations_cell_p(cell c)
Definition: effects.c:432
bool anywhere_effect_p(effect e)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
bool store_effect_p(effect e)
Definition: effects.c:1062
bool effect_list_can_be_safely_full_freed_p(list el)
Check if some references might be freed with the effects.
Definition: effects.c:1159
bool atomic_effect_p(effect e)
Definition: effects.c:1668
bool vect_contains_phi_p(Pvecteur v)
bool vect_contains_phi_p(Pvecteur v) input : a vector output : true if v contains a PHI variable,...
Definition: effects.c:1427
bool cell_equal_p(cell c1, cell c2)
CELLS.
Definition: effects.c:1226
string full_action_to_string(action ac)
Definition: effects.c:943
string action_to_string(action ac)
Functions dealing with actions.
Definition: effects.c:936
void points_to_cell_add_zero_subscripts(cell c)
Definition: effects.c:1615
bool cell_abstract_location_p(cell c)
Definition: effects.c:273
entity cell_entity(cell c)
Definition: effects.c:57
bool malloc_reference_p(reference r)
Definition: effects.c:488
effect effect_to_pointer_store_independent_effect(effect eff, entity p)
Modify eff so that the set of memory locations decribed after a write to some pointer p is still in t...
Definition: effects.c:815
bool store_independent_effect_p(effect eff)
Does this effect define the same set of memory locations regardless of the current (environment and) ...
Definition: effects.c:636
statement_mapping listmap_to_effectsmap(statement_mapping l_map)
Definition: effects.c:216
bool anywhere_reference_p(reference r)
Definition: effects.c:378
bool effects_interfere_p(effect eff1, effect eff2)
Two effects interfere if one of them modify the set of locations defined by the other one.
Definition: effects.c:714
bool any_anywhere_effect_p(effect e)
Is it a typed or untyped anywhere effect?
Definition: effects.c:358
bool heap_cell_p(cell c)
Any heap cell, more or less abstract or typed.
Definition: effects.c:420
bool effects_write_variable_p(list el, entity v)
Definition: effects.c:1091
bool std_file_effect_p(effect e)
Definition: effects.c:519
bool typed_anywhere_effect_p(effect e)
Is it a typed anywhere effect? ANYMMODULE:ANYWHERE_b0, 1, 2.
Definition: effects.c:352
action_kind action_to_action_kind(action a)
Without the consistency test, this function would certainly be inlined.
Definition: effects.c:1048
void points_to_cell_complete_with_zero_subscripts(cell c)
Definition: effects.c:1626
bool memory_dereferencing_p(reference r)
Does the set of locations referenced by r depend on a pointer dereferencing?
Definition: effects.c:92
bool points_to_reference_included_p(reference r1, reference r2)
FI->FC/AM: some elements of the lattice must be exploited here...
Definition: effects.c:1243
bool effects_read_variable_p(list el, entity v)
Definition: effects.c:1123
effects list_to_effects(list l_eff)
Future API for GAP, Generic Access Path.
Definition: effects.c:202
bool nowhere_cell_p(cell c)
Target of an undefined pointer.
Definition: effects.c:455
bool cell_equivalent_p(cell c1, cell c2)
Check that memory locations denoted by cell "c1" can be reached by knowing cell "c2" and by using poi...
Definition: effects.c:1311
cell points_to_cell_add_field_dimension(cell c, entity f)
Functions about points-to cells - There is no cell.c file.
Definition: effects.c:1444
bool cell_entity_equal_p(cell c1, cell c2)
Definition: effects.c:1234
bool environment_effect_p(effect e)
Definition: effects.c:1071
void points_to_cell_add_zero_subscript(cell c)
Definition: effects.c:1620
tag approximation_and(tag t1, tag t2)
tag approximation_and(tag t1, tag t2) input : two approximation tags.
Definition: effects.c:1198
bool union_compatible_effects_p(effect ef1, effect ef2)
DO NOT USE ANYMORE: NOT COMPATIBLE WITH ABSTRACT LOCATIONS.
Definition: effects.c:1354
reference cell_to_reference(cell c)
FI: probably to be moved elsewhere in ri-util.
Definition: effects.c:1326
bool io_effects_p(list effects)
Definition: effects.c:512
list recursive_cell_to_pointer_cells(cell c)
Definition: effects.c:1680
static bool generic_anywhere_effect_p(effect e, int kind)
Is it an anywhere effect (kind=0)? a typed anywhere effect (kind=1) ? or any kind of anywhere effect ...
Definition: effects.c:333
bool effects_write_p(list el)
Definition: effects.c:1108
action make_action_read_memory(void)
Definition: effects.c:1017
bool anywhere_cell_p(cell c)
Is it an anywhere cell?
Definition: effects.c:367
bool type_declaration_effect_p(effect e)
Definition: effects.c:1080
bool effect_abstract_location_p(effect eff)
Definition: effects.c:280
effect anywhere_effect(action ac)
Anywhere effect: an effect which can be related to any location of any areas.
Definition: effects.c:317
bool effect_on_non_local_variable_p(effect eff)
Test if an effect has a non local effect.
Definition: effects.c:674
bool io_effect_entity_p(entity e)
Definition: effects.c:496
bool io_effect_p(effect e)
Definition: effects.c:501
bool std_file_effects_p(list effects)
Definition: effects.c:529
reference cell_any_reference(cell c)
API for reference.
Definition: effects.c:77
effect effect_to_store_independent(effect eff)
Definition: effects.c:772
bool effects_abstract_location_p(list el)
Returns true if at least one effect of effect list el is related to an abstract location.
Definition: effects.c:288
bool io_cell_p(cell c)
Definition: effects.c:506
list cell_indices(cell c)
Definition: effects.c:64
entity effect_to_entity(effect ef)
Returns the entity corresponding to the mutation.
Definition: effects.c:1413
effect effect_to_non_pointer_store_independent_effect(effect eff)
Modify eff so that the set of memory locations decribed after a write to some non pointer variable is...
Definition: effects.c:844
bool effects_on_non_local_variable_p(list effects)
Test if a list of effects concerns non local variables.
Definition: effects.c:687
bool effect_list_consistent_p(list el)
Debugging.
Definition: effects.c:1340
list cell_to_pointer_cells(cell c)
If the reference in "c" is not a pointer, see if it can be transformed into a pointer reference by ad...
Definition: effects.c:1739
reference simple_reference_add_field_dimension(reference r, entity f)
Do not check anything, just add f as a last subscript.
Definition: effects.c:1581
void points_to_cell_update_last_subscript(cell c, expression s)
Transform reference a[i]...[j] and expression s into reference a[i]..[j+s] if j and s are constant in...
Definition: effects.c:1643
reference reference_add_field_dimension(reference r, entity f)
add a field f as a subscript to a reference r if it is meaningful.
Definition: effects.c:1475
bool heap_effect_p(effect e)
Definition: effects.c:408
string action_kind_to_string(action_kind ak)
Definition: effects.c:995
bool FILE_star_effect_reference_p(reference ref)
Definition: effects.c:536
int get_int_property(const string)
action make_action_read(action_kind _field_)
Definition: effects.c:123
cell make_cell_reference(reference _field_)
Definition: effects.c:293
action copy_action(action p)
ACTION.
Definition: effects.c:77
action_kind make_action_kind_store(void)
Definition: effects.c:65
void free_effect(effect p)
Definition: effects.c:451
effects make_effects(list a)
Definition: effects.c:568
bool effect_consistent_p(effect p)
Definition: effects.c:457
void free_cell(cell p)
Definition: effects.c:249
action make_action_write(action_kind _field_)
Definition: effects.c:126
approximation make_approximation_may(void)
Definition: effects.c:179
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
descriptor make_descriptor_none(void)
Definition: effects.c:442
cell copy_cell(cell p)
CELL.
Definition: effects.c:246
bool reference_consistent_p(reference p)
Definition: ri.c:2056
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
void free_expression(expression p)
Definition: ri.c:853
void free_type(type p)
Definition: ri.c:2658
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 entity_typed_anywhere_locations(type t)
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
bool entity_typed_anywhere_locations_p(entity e)
Test if an entity is the bottom of the lattice.
bool entity_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool entity_anywhere_locations_p(entity e)
test if an entity is the bottom of the lattice
entity entity_all_locations()
eturn ANY_MODULE:ANYWHERE (the top of the lattice)
bool entity_all_module_heap_locations_p(entity e)
test if an entity is the a heap area
entity entity_all_heap_locations_typed(type t)
bool entity_all_heap_locations_p(entity e)
test if an entity is the set of all heap locations
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
void const char const char const int
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
#define variable_phi_p(e)
true if e is a phi variable PHI entities have a name like: REGIONS:PHI#, where # is a number.
type points_to_cell_to_type(cell, bool *)
FI: I need more generality than is offered by cell_to_type()
Definition: type.c:665
type points_to_reference_to_type(reference, bool *)
FI: I need more generality than is offered by cell_to_type()
Definition: type.c:527
type points_to_expression_to_concrete_type(expression)
The type returned is stored in a hash-table.
Definition: type.c:617
bool points_to_array_reference_p(reference)
Is this a reference to an array or a reference to a pointer? This is not linked to the type of the re...
Definition: points_to.c:599
bool atomic_points_to_cell_p(cell)
Is it a unique concrete memory location?
Definition: points_to.c:423
type points_to_array_reference_to_type(reference)
If this is an array reference, what is the type of the underlying array type?
Definition: points_to.c:657
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define action_write(x)
Definition: effects.h:316
#define cell_reference_p(x)
Definition: effects.h:467
#define descriptor_tag(x)
Definition: effects.h:595
@ is_action_kind_store
Definition: effects.h:237
#define action_kind_environment_p(x)
Definition: effects.h:262
#define action_kind_tag(x)
Definition: effects.h:258
#define action_kind_store_p(x)
Definition: effects.h:259
#define effect_action(x)
Definition: effects.h:642
#define effect_undefined
Definition: effects.h:614
#define action_read(x)
Definition: effects.h:313
#define action_write_p(x)
Definition: effects.h:314
#define cell_gap_p(x)
Definition: effects.h:473
#define action_tag(x)
Definition: effects.h:310
#define CELL(x)
CELL.
Definition: effects.h:424
#define action_read_p(x)
Definition: effects.h:311
#define action_kind_type_declaration_p(x)
Definition: effects.h:265
#define effect_descriptor(x)
Definition: effects.h:646
#define effects_effects(x)
Definition: effects.h:710
#define cell_preference_p(x)
Definition: effects.h:470
@ is_approximation_may
Definition: effects.h:341
@ is_approximation_exact
Definition: effects.h:343
#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....
static entity a_variable
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
#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
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#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
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
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
#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 HEAP_AREA_LOCAL_NAME
Definition: naming-local.h:71
#define GET_STATEMENT_MAPPING(map, stat)
Definition: newgen-local.h:49
#define MAKE_STATEMENT_MAPPING()
Definition: newgen-local.h:43
#define STATEMENT_MAPPING_MAP(s, v, code, h)
Definition: newgen-local.h:53
#define same_string_p(s1, s2)
int tag
TAG.
Definition: newgen_types.h:92
#define string_undefined
Definition: newgen_types.h:40
struct cons * list
Definition: newgen_types.h:106
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
string string_of_type(const type)
Definition: type.c:56
#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
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool malloc_effect_entity_p(entity e)
Definition: entity.c:1158
bool io_luns_entity_p(entity e)
Definition: entity.c:1146
bool std_file_entity_p(entity e)
Definition: entity.c:1232
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
void reference_complete_with_zero_subscripts(reference r)
Reference r to an array maybe partial, as is possible in C: with declaration "int a[10][10]",...
Definition: expression.c:278
bool extended_integer_constant_expression_p(expression e)
More extensive than next function.
Definition: expression.c:858
void reference_add_zero_subscripts(reference r, type t)
Definition: expression.c:261
expression make_unbounded_expression()
Definition: expression.c:4339
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
void reference_add_zero_subscript(reference r)
No check on reference r.
Definition: expression.c:267
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
bool reference_equal_p(reference r1, reference r2)
Definition: expression.c:1500
void reference_add_unbounded_subscripts(reference r, type t)
Definition: expression.c:300
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
bool reference_with_constant_indices_p(reference r)
Definition: expression.c:3022
reference reference_with_store_independent_indices(reference r)
Return by side effect a reference whose memory locations includes the memory locations of r in case t...
Definition: expression.c:3045
list expression_to_reference_list(expression e, list lr)
conversion of an expression into a list of references; references are appended to list lr as they are...
Definition: expression.c:1263
type ultimate_type(type)
Definition: type.c:3466
bool array_type_p(type)
Definition: type.c:2942
bool variable_is_a_module_formal_parameter_p(entity, entity)
Definition: variable.c:1547
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 array_of_pointers_type_p(type)
Definition: type.c:3025
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
type subscripted_type_to_type(type, expression)
Returns the type of an object of type t subscripted by expression se.
Definition: type.c:5562
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
unsigned int array_type_dimension(type)
Definition: type.c:2947
size_t type_depth(type)
Number of steps to access the lowest leave of type t without dereferencing.
Definition: type.c:4880
bool struct_type_p(type)
Returns true if t is of type derived and if the derived type is a struct.
Definition: type.c:3121
type array_type_to_element_type(type)
returns the type of the elements of an array type, as a newly allocated type.
Definition: type.c:5700
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
bool array_of_struct_type_p(type)
Definition: type.c:3133
entity find_field_in_field_list(entity, list)
To deal with fields declared in different C files.
Definition: type.c:5401
#define type_functional_p(x)
Definition: ri.h:2950
#define type_struct(x)
Definition: ri.h:2964
#define basic_pointer(x)
Definition: ri.h:637
#define type_struct_p(x)
Definition: ri.h:2962
#define REFERENCE(x)
REFERENCE.
Definition: ri.h:2296
#define reference_undefined
Definition: ri.h:2302
#define EXPRESSION_(x)
Definition: ri.h:1220
#define reference_variable(x)
Definition: ri.h:2326
#define basic_derived(x)
Definition: ri.h:640
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define basic_derived_p(x)
Definition: ri.h:638
#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 expression_undefined
Definition: ri.h:1223
#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 type_undefined
Definition: ri.h:2883
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
#define intptr_t
Definition: stdint.in.h:294
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
struct Svecteur * succ
Definition: vecteur-local.h:92
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define VECTEUR_NUL_P(v)
#define var_of(varval)