PIPS
value.c
Go to the documentation of this file.
1 /*
2 
3  $Id: value.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  /* VARIABLE VALUE MANAGEMENT PACKAGE FOR TRANSFORMERS
28  *
29  * Values of variables could be a new data structure or a special kind of
30  * entities. To avoid an increase in data structure declarations and an
31  * increased size for the implicit array of entities, values are often
32  * entities with special names. Their meaning is defined with respect to
33  * an environment defined at the module level and so, constant during the
34  * analysis of a module.
35  *
36  * Constant values may be used as values. They are 0-ary functions. They
37  * are used to encode character strings. They are not dealt with by this
38  * package. It is possible to handle scalar floating point
39  * constants in the same way.
40  *
41  * Temporary values may be used to denote expression values. These
42  * temporary values have no names. They are read only. They must be
43  * eliminated from long lasting data structures as their semantics is
44  * local to a single expression, usually a right hand side. Only the most
45  * basic entity printing routine can be used for such values.
46  *
47  * Only scalar variables are analyzed.
48  *
49  * Properties are used to select the variables types that are to be
50  * analyzed among integer, boolean, string, float and/or complex. Any
51  * combination of types is legal. Scalar variables of an analyzed type
52  * are said to be analyzable but they may be not analyzed because of some
53  * static aliasing (EQUIVALENCE).
54  *
55  * Three different kind of variable values are used: new, old and
56  * intermediate. New values are used in post-condition predicates. Old
57  * values are used in pre-condition predicates. New and old values are
58  * also used in predicate transformers. Intermediate values are used to
59  * combine transformers.
60  *
61  * New values are directly referenced by the corresponding scalar
62  * variable, a regular entity, with types integer, boolean, float,
63  * complex or string. However they are printed with a different name to
64  * avoid confusion between variables and values. The value name is the
65  * variable name, suffixed by "#new".
66  *
67  * Old values and intermediate values are referenced via special
68  * entities, distinguished by their names made of a specific prefix
69  * followed by a number (see OLD_VALUE_PREFIX and
70  * INTERMEDIATE_VALUE_PREFIX in transformer.h).
71  *
72  * The type of a value is the type of the associated entity. Equivalenced
73  * variables are handled only if they all have the same type.
74  *
75  * Pre-values, a.k.a. old values, for local dynamic entities are
76  * named "o#XX", where "XX" is a number. A pre-value is associated to
77  * an entity via a hash table used by the function
78  * entity_to_old_value(). Static aliasing (i.e. EQUIVALENCEs) is
79  * dealed with by associating the same value entity to the two
80  * aliased variable entities.
81  *
82  * Pre-values, a.k.a. old values, for analyzed scalar formal
83  * parameters and analyzed scalar global variables are represented by
84  * special entities named from the relevant variable entity, by
85  * suffixing its name by "#init". These values have to be represented
86  * by specific entities to let us consider parameter values at entry
87  * point and to let us perform interprocedural semantics analysis.
88  *
89  * Intermediate values are referenced by special entities named "i#XX",
90  * which are reused from procedure to procedure. Within a procedure,
91  * each variable is linked to one intermediate value entity.
92  *
93  * These conventions are used by value_to_name(e) to generate EXTERNAL
94  * names I#new, I#old and I#tmp and to print readable debug information.
95  *
96  * To accelerate conversions between new, old and intermediate value
97  * entities, four hash tables must set up for each module before
98  * semantics analysis is started or used:
99  *
100  * - hash_entity_to_new_value associates an entity representing a new
101  * value to each scalar variable with an analyzed type; this value
102  * entity is most of the time the variable entity itself and thus this
103  * hash table almost represents an identity function; however,
104  * perfectly equivalenced variables are represented by one of them
105  * only and some eligible analyzable scalar variables are not mapped to
106  * anything because they are equivalenced to an array
107  *
108  * - hash_entity_to_old_value associates an entity representing an old
109  * value to each scalar analyzable variable
110  *
111  * - hash_entity_to_intermediate_value
112  *
113  * - hash_value_to_name: associates user-readable names to value entity;
114  * used for debugging and display purposes.
115  *
116  * Francois Irigoin, December 1989 (updated June 2001,... August 2009)
117  *
118  * Modifications:
119  *
120  * - only integer variables used to be analyzed; the analysis is
121  * extended to strings, bool and floating point scalar variables
122  * (Francois Irigoin, 14 June 2001).
123  *
124  * - temporary values are added to deal with subexpressions and to
125  * analyze non-linear expressions (Francois Irigoin, 14 June 2001).
126  *
127  * - the three mappings between variable entities and value entities
128  * were done differently for each transformer and based on the arguments
129  * field; efficiency was limited because the mappings were based on
130  * lists and because transformers had to be renamed before they could be
131  * combined; aliasis information had to be computed at each step instead
132  * of being factored out at hashing time (Francois Irigoin, April 90)
133  *
134  * - *** assigments to array or to non integer scalar can now affect
135  * transformer on integer scalar variables (Francois Irigoin, April
136  * 90)*** no longer true - such integer scalar variables are just
137  * ignored; however, it would be easy to do slightly better (21 April
138  * 1990)
139  *
140  * - old value suffix is now "#init" because it's nicer in
141  * prettyprinting predicates; it's also worse for transformer but they
142  * are less interesting for the users (Francois Irigoin, 18 April 1990)
143  *
144  * - fourth hash_table entity->new_value added to handle EQUIVALENCEs
145  * (Francois Irigoin, 18 April 1990)
146  *
147  * - only analyzable scalar variables that are not aliased or that are
148  * aliased to another scalar variable with same type are analyzed; dubious
149  * interest but April 24th is close (Francois Irigoin, 21 April 1990)
150  *
151  * Bugs/Features:
152  *
153  * - once the hash tables are lost, intraprocedural transformers are
154  * useless while they were still interpretable when mappings were
155  * based on arguments; they could be translated into the previous
156  * representation when their computation is completed (Francois Irigoin,
157  * April 1990)
158  *
159  * - hash tables are static; recursion is not possible for
160  * interprocedural analysis; topographical order will have to be used
161  * for it (Francois Irigoin, April 1990)
162  *
163  * Assumptions:
164  *
165  * - all variable values and only variable values used in a module have
166  * names in value_to_name(); however, constants, which also are values,
167  * do not appear in this mapping;
168  *
169  * - all variables whose values may be imported have entries in the
170  * three mappings entity_to_xxx_value() if they are defined within the
171  * current module, directly or indirectly thru calls; the information is
172  * derived interprocedurally from the memory effects which do not take
173  * aliasing into account; aliasing is handled using these three
174  * mappings; several exactly aliased variables are represented by the
175  * variable that appears first in the module effects, or by default, if
176  * none of these variables is in the scope of the current module, by any
177  * of them, probably the first one in the interprocedural effects;
178  * variables that are only read, i.e. used, are mapped only in
179  * entity_to_new_value();
180  *
181  * - a summary_transformer imported for a callee may be difficult to
182  * print before it is translated in the current module frame;
183  *
184  * - there is no absolute frame to express summary_preconditions for the
185  * time being (maybe, this has been fixed!)
186  *
187  * Francois Irigoin, 13 January 1994
188  */
189 
190 #include <stdlib.h>
191 #include <stdio.h>
192 #include <stdlib.h>
193 #include <string.h>
194 
195 #include "genC.h"
196 #include "linear.h"
197 
198 #include "misc.h"
199 #include "properties.h"
200 
201 #include "ri.h"
202 #include "ri-util.h"
203 #include "workspace-util.h"
204 #include "prettyprint.h" // type_to_full_string_definition
205 
206 #include "effects.h"
207 #include "effects-util.h"
208 
209 #include "transformer.h"
210 ␌
211 /* STATIC VARIABLES */
212 
213 /* Four global hash tables used to map scalar analyzable variable entities
214  * onto the different kind of value entities and to map value entities
215  * onto their external names.
216  *
217  * They prevent recursive calls.
218  */
224 
226 
228 
230 {
232 }
233 
234 
235 /* Two counters used to assign meaningless value entities to local variables.
236  * A special global prefix, SEMANTICS_MODULE_NAME, and two special local
237  * prefixes, OLD_VALUE_PREFIX and INTERMEDIATE_VALUE_PREFIX, are also used
238  */
239 
241 static int local_old_value_counter = 0;
243 
245 {
248 }
249 
251 {
253 }
254 
256 {
258 }
259 ␌
260 /* TYPING */
261 
264 static bool analyze_string_scalar_entities = false;
265 static bool analyze_float_scalar_entities = false;
268 
269 static bool analyze_constant_path = false;
270 
272 {
274  get_bool_property("SEMANTICS_ANALYZE_SCALAR_INTEGER_VARIABLES");
276  get_bool_property("SEMANTICS_ANALYZE_SCALAR_BOOLEAN_VARIABLES");
278  get_bool_property("SEMANTICS_ANALYZE_SCALAR_STRING_VARIABLES");
280  get_bool_property("SEMANTICS_ANALYZE_SCALAR_FLOAT_VARIABLES");
282  get_bool_property("SEMANTICS_ANALYZE_SCALAR_COMPLEX_VARIABLES");
284  get_bool_property("SEMANTICS_ANALYZE_SCALAR_POINTER_VARIABLES");
286  get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH");
287 }
288 
290 {
297  analyze_constant_path = false;
298 }
299 
301 {
303 }
304 
306 {
308 }
309 
311 {
313 }
314 
316 {
318 }
319 
321 {
323 }
324 
326 {
328 }
329 
331 {
332  return analyze_constant_path;
333 }
334 
335 
336 /* The basic corresponds to one of the analyzed types */
338 {
339  bool analyzed_p = false;
340 
342  analyzed_p = true;
344  analyzed_p = true;
346  analyzed_p = true;
348  analyzed_p = true;
350  pips_debug(9,"pointer type : %s\n", type_to_string(basic_pointer(b)));
351  analyzed_p = true;
352  }
354  analyzed_p = true;
356  entity de = basic_derived(b);
358  analyzed_p = type_enum_p(dt);
359  }
360  else
361  analyzed_p = false;
362 
363  return analyzed_p;
364 }
365 
366 /* The type t is one of the analyzed types */
368 {
369  bool result = false;
371 
372  if(type_variable_p(bct)) {
373  variable v = type_variable(bct);
374  if (!volatile_variable_p(v)
375  && ENDP(variable_dimensions(v)) //NL : for checking the dimension instead of entity_scalar_p which filter pointer type
376  ) {
377  result = analyzed_basic_p(variable_basic(v));
378  }
379  }
380 
381  return result;
382 }
383 
384 /* Does struct s contain directly or indirectly a field that may be
385  * analyzable?
386  */
388 {
389  bool analyzed_p = false;
391  FOREACH(ENTITY, f, fl) {
393  if(analyzed_type_p(ft)) {
394  analyzed_p = true;
395  break;
396  }
397  else if(struct_type_p(ft)) {
398  analyzed_p = analyzed_struct_p(f);
399  if(analyzed_p)
400  break;
401  }
402  }
403  return analyzed_p;
404 }
405 
407 {
408  bool analyzed_p = false;
409  list fl = struct_type_to_fields(st);
410  FOREACH(ENTITY, f, fl) {
411  // FI: might be shorter an safer to call entity_analyzed_p(f)
413  if(analyzed_type_p(ft)) {
414  analyzed_p = true;
415  break;
416  }
417  else if(struct_type_p(ft)) {
418  analyzed_p = analyzed_struct_type_p(ft);
419  if(analyzed_p)
420  break;
421  }
422  else if(array_type_p(ft)) {
423  analyzed_p = analyzed_array_type_p(ft);
424  if(analyzed_p)
425  break;
426  }
427  }
428  return analyzed_p;
429 }
430 
431 /* Does array a contain directly or indirectly a field that may be
432  * analyzable?
433  */
435 {
436  bool analyzed_p = false;
439  if(analyzed_type_p(et))
440  analyzed_p = true;
441  else if(struct_type_p(et))
442  analyzed_p = analyzed_struct_type_p(et);
443  return analyzed_p;
444 }
445 
447 {
448  bool analyzed_p = false;
450  if(analyzed_type_p(et))
451  analyzed_p = true;
452  else if(struct_type_p(et))
453  analyzed_p = analyzed_struct_type_p(et);
454  return analyzed_p;
455 }
456 
458 {
459  bool analyzed_p = false;
461  if(analyzed_type_p(et))
462  analyzed_p = true;
463  else if(struct_type_p(et))
464  analyzed_p = analyzed_struct_type_p(et);
465  else if(array_type_p(et))
466  analyzed_p = analyzed_array_type_p(et);
467  return analyzed_p;
468 }
469 
470 /* The entity type is one of the analyzed types */
472 {
473  bool result = false;
474 
475  if(!abstract_state_variable_p(e) // for packages such as IO or RAND
476  && !typedef_entity_p(e)
479  && !place_holder_variable_p(e)) { // Because enum are analyzed
481  result = analyzed_type_p(bct);
482  }
483  return result;
484 }
485 
486 /* The constant may appear as a variable in the linear systems */
488 {
489  /* is f a 0-ary function, i.e. a constant of proper type? */
490  if(entity_constant_p(f)) {
493 
494  /* integer and logical constants are handled explicitly */
495 
497  return true;
499  return true;
501  return true;
503  return true;
504  }
505  return false;
506 }
507 
508 /* FI: Nelson explains the motivation for
509  * can_be_constant_path_p() but I do not understand them.
510  *
511  * He also explains the motivation for
512  * strict_constant_path_p() and I do not understand them
513  * either.
514  *
515  * Stricly speaking, this funtion should be called
516  * analyzed_points_to_reference_p()
517  */
519 {
520  pips_debug(7, "analyzed_reference_p, ref : %s\n", reference_to_string(r));
521  bool result = false;
522  entity v = reference_variable(r);
523 
525  //&& atomic_points_to_reference_p(r)) {
527  && !effects_package_entity_p(v)) {
529  result = analyzed_type_p(t);
530  }
531  else {
532  // e.g. a[i]
533  result = false;
534  }
535 
536  pips_debug(7, "analyzed_reference_p result : %i\n", result);
537  return result;
538 }
539 
540 
541 ␌
542 /* LOCAL VALUE ENTITY */
543 
544 /* static entity make_local_value_entity(int n, bool old): find or generate
545  * an entity representing an old or an intermediate value of number n
546  */
547 static entity make_local_value_entity(int n, int nature, type t)
548 {
549  entity v;
550  /* 13 is a magic number that can accommodate 2 prefix characters,
551  10 digits and a null character */
552  char value_name[13];
553  char * s;
554 
555  if(nature==0)
556  (void) strcpy(value_name, OLD_VALUE_PREFIX);
557  else if(nature==1)
558  (void) strcpy(value_name, INTERMEDIATE_VALUE_PREFIX);
559  else
560  (void) strcpy(value_name, TEMPORARY_VALUE_PREFIX);
561  (void) sprintf(value_name+2,"%d",n);
562  pips_debug(8,"value name: %s\n",value_name);
564  MODULE_SEP_STRING, value_name, (char *) NULL));
565 
566  /* find entity or define it */
568  if(v==entity_undefined)
569  v = make_entity(s,
570  copy_type(t),
573  else {
574  free(s);
575  /* Another option might be to undefine types when counters are
576  reset? */
577  /* It is likely to take longer to compare types than to free one and
578  allocate one... */
579  /* Well, type_equal_p() replaces typedefs types by the underlying
580  type which leads to disasters; see suppress_dead_code04.c */
581  if(true || type_equal_p(entity_type(v), t)) {
583  entity_type(v) = copy_type(t);
584  }
586  /* The previous test always returns true for strings */
588  entity_type(v) = copy_type(t);
589  }
590  }
591 
592  return v;
593 }
594 
596 {
598 }
599 
601 {
603 }
604 
606 {
608 
609  /* FI: is it easier to admit value of type void than to make a
610  special case? Let see if it works... No, it's not a good idea
611  because value are assumed of type variable in many places. */
612  if(analyzed_type_p(t))
614  else
615  pips_internal_error("Request for a temporary value with a non analyzed type.\n");
616 
617  return tv;
618 }
619 
621 {
624 
625  free_type(t);
626  return tmp;
627 }
628 
630 {
631  basic b = make_basic(is_basic_int, (void *) 4);
634 
635  free_type(t);
636  return tmp;
637 }
638 
639 /* Return true if an entity is a local old value (such as "o#0" for a
640  global value "i#init"...).
641 */
643 {
644  /* This is not a general test; it will only work for LOCAL values */
645  return strncmp(entity_local_name(e), OLD_VALUE_PREFIX, 2) == 0;
646 }
647 
649 {
650  /* this is not a general test; it will only work for LOCAL values */
651  return strncmp(entity_local_name(e), INTERMEDIATE_VALUE_PREFIX, 2) == 0;
652 }
653 
655 {
656  /* this is not a general test; it will only work for LOCAL values */
657  return strncmp(entity_local_name(e), TEMPORARY_VALUE_PREFIX, 2) == 0;
658 }
659 
661 {
663 }
664 ␌
665 /* GLOBAL VALUES */
666 
668 {
669  bool new = false;
670  /* this is not a general test; it will only work for GLOBAL values */
671 
672  /* this function should always return false because new value = variable (FI) */
673 
674  /* => suf == NULL
675  string suf = strchr(entity_local_name(e), SEMANTICS_SEPARATOR);
676 
677  pips_assert("global_new_value", suf != NULL);
678 
679  new = strcmp(entity_module_name(e), SEMANTICS_MODULE_NAME) != 0 &&
680  strcmp(suf, NEW_VALUE_SUFFIX) == 0;
681  */
682 
683  pips_assert("global_new_value", new == false && e==e);
684 
685  return new;
686 }
687 
688 /* Return true if an entity is a global old value (such as
689  "i#init"...). */
691 {
692  /* this is not a general test; it will only work for GLOBAL values */
693  string suf = strchr(entity_local_name(e), SEMANTICS_SEPARATOR);
694  bool old = false;
695 
696  if(suf!=NULL)
697  old = strcmp(entity_module_name(e), SEMANTICS_MODULE_NAME) != 0 &&
698  strcmp(suf, OLD_VALUE_SUFFIX) == 0;
699 
700  return old;
701 }
702 
704 {
705  /* this is not a general test; it will only work for GLOBAL values */
706  string suf = strchr(entity_local_name(e), SEMANTICS_SEPARATOR);
707  bool intermediate = false;
708 
709  if(suf!=NULL)
710  intermediate = strcmp(entity_module_name(e), SEMANTICS_MODULE_NAME) != 0 &&
711  strcmp(suf, INTERMEDIATE_VALUE_SUFFIX) == 0;
712 
713  return intermediate;
714 }
715 
717 {
718  entity v_old = entity_undefined;
719 
720  /* There is no real test for global new values */
721 
722  pips_assert("new value must be a real variable entity, denoting the new value",
723  strcmp(entity_module_name(v_new), SEMANTICS_MODULE_NAME) != 0);
724 
725  string v_old_name = concatenate(entity_name(v_new), OLD_VALUE_SUFFIX, NULL);
726  v_old = (entity) gen_find_tabulated(v_old_name, entity_domain);
727  if(v_old==NULL) v_old = entity_undefined;
728 
729  return v_old;
730 }
731 ␌
732 /* HASH TABLE USE
733  *
734  * Return a variable value name or map a variable to its different
735  * variable values.
736  *
737  */
738 
739 /* the '#' character used in value naming conflicts with the reserved
740  character for struct naming*/
741 const char* global_value_name_to_user_name(const char* gn)
742 {
743  const char* un = strrchr(gn, BLOCK_SEP_CHAR);
744 
745  if(un==NULL)
746  un = local_name(gn);
747  else
748  un++;
749 
750  return un;
751 }
752 
754 {
755  const char* s = string_undefined;
756  if(entity_constant_p(e)) {
757  // Used for floating point and string constants? Why entity name?
758  s = entity_local_name(e);
759  }
760  else if(entity_symbolic_p(e)) {
761  // Used for locations, i.e. constant memory access paths
762  s = entity_local_name(e);
763  }
764  else if(null_pointer_value_entity_p(e)) {
765  s = entity_name(e);
766  }
767  else {
768  // it must be one of the values attached to a user variable
770  s = hash_get(hash_value_to_name, (char *) e);
771  // type t = entity_type(e);
772 
774  //&& type_variable_p(t)
775  && !variable_in_module_p(e,m)) {
776  if(global_new_value_p(e)) {
778  s = hash_get(hash_value_to_name, (char *) a);
779  }
780  else if(global_old_value_p(e)) {
782  s = hash_get(hash_value_to_name, (char *) a);
783  }
784  else if(global_intermediate_value_p(e)) {
786  s = hash_get(hash_value_to_name, (char *) a);
787  }
788  else {
789  /* This should never occur. Please core dump! */
790  pips_internal_error("\nUnexpected value \"%s\""
791  " for current module \"%s\"",
792  entity_name(e),
794  }
795  }
796 
797  pips_assert("A value name must be defined",
798  s != HASH_UNDEFINED_VALUE);
799 
800  if(strcmp(module_local_name(m), module_name(s)) == 0
801  ||strcmp(TOP_LEVEL_MODULE_NAME, module_name(s)) == 0) {
802  //s = local_name(s);
804  }
805  }
806 
807  return s;
808 }
809 
810 /* This function is called many times when the constraints and the
811  system of constraints are sorted using lexicographic information
812  based on this particular value name. See for instance
813  Semantics-New/freia_52.c. Hence it is memorized.
814 */
816 {
817  pips_debug(9, "start with entity : %s\n", entity_name(e));
818  const char* uvn = string_undefined;
819 
820  if(e == (entity) TCST) {
821  uvn = "";
822  }
823  else {
824  // To check the execution speed, uncomment the next line
825  // return entity_name(e);
826  uvn = hash_get(hash_entity_to_user_value_name, (char *) e);
827 
828  if(uvn==HASH_UNDEFINED_VALUE) {
829  // Need to discriminate the case of an address_of value
830  // because the hash table are reset between each pass
831  if (address_of_value_entity_p(e)) {
832  entity v = value_to_variable(e);
833  string temp = strdup(entity_name(e));
834  string indice = strstr(temp, "[");
835  if (indice != NULL)
836  *(indice+strlen(indice)-strlen(ADDRESS_OF_SUFFIX)) = '\0';
837  uvn = strdup(concatenate("&", entity_user_name(v), indice, (char *) NULL));
838  free(temp);
839  }
840  else if (null_pointer_value_entity_p(e)) {
841  uvn = strdup("NULL");
842  }
843  else if (sizeof_value_entity_p(e)) {
844  type t = entity_type(e);
845  uvn = strdup(concatenate("sizeof(", type_to_full_string_definition(t), ")", (char *) NULL));
846  }
847  else {
848  (void) gen_check((gen_chunk *) e, entity_domain);
851  }
852  hash_put(hash_entity_to_user_value_name, (char *) e, uvn);
853  }
854  }
855  pips_debug(9, "end with string : %s\n", uvn);
856  return uvn;
857 }
858 ␌
860 {
861  entity n;
862  if((n = (entity) hash_get(hash_entity_to_new_value, (char *) e))
863  == entity_undefined)
864  pips_internal_error("unbounded entity %s",
865  entity_name(e));
866  return n;
867 }
868 
870 {
871  entity o;
872  if((o = (entity) hash_get(hash_entity_to_old_value, (char *) e))
873  == entity_undefined)
874  pips_internal_error("unbounded entity %s",
875  entity_name(e));
876  return o;
877 }
878 
880 {
881  entity i;
882  if((i = (entity) hash_get(hash_entity_to_intermediate_value, (char *) e))
883  == entity_undefined)
884  pips_internal_error("unbounded entity %s",
885  entity_name(e));
886  return i;
887 }
888 
890 {
891  entity n;
892  if((n = (entity) hash_get(hash_reference_to_address_of_value, (char *) r))
893  == entity_undefined)
894  pips_internal_error("unbounded reference %s",
896  return n;
897 }
898 
900 {
901  entity i;
902  if((i = (entity) hash_get(hash_type_to_sizeof_value, (char *) t))
903  == entity_undefined)
904  pips_internal_error("unbounded type %s : %s",
906  return i;
907 }
908 
909 /* This function could be made more robust by checking the storage of
910  e. Formal parameters of analyzed type always have values. */
912 {
913  /* is e a variable whose value(s) (already) are analyzed?
914  */
915  pips_assert("value hash table is defined",
917  bool has_values_p = hash_defined_p(hash_entity_to_new_value, (char *) e);
918  return has_values_p;
919 }
920 
921 /* the following three functions are directly or indirectly relative
922  * to the current module and its value hash tables.
923  */
924 
926 {
927  /* since new values are always variable entities, hash_entity_to_new_value
928  can be used for this test */
929 
930  pips_assert("new_value_entity_p",e != entity_undefined);
931 
932  return (entity) hash_get(hash_entity_to_new_value, (char *) e)
933  == e;
934 }
935 
937 {
938  /* Temporary values do not have an external name. */
939  /* OLD_VALUE_PREFIX is not used for global old values */
940  /* string s = strstr(external_value_name(e), OLD_VALUE_SUFFIX); */
941  /* string s = strstr(entity_local_name(e), OLD_VALUE_PREFIX); */
942 
944  string s1 = strstr(entity_local_name(e), OLD_VALUE_SUFFIX);
945  // Need to remake the search for OLD_VALUE_PREFIX
946  // bug for toto#...
947  string s2 = strstr(entity_local_name(e), OLD_VALUE_PREFIX);
948  // s2==entity_local_name(e) : for the case toto#...
949  return s1!=NULL || (s2!=NULL && s2==entity_local_name(e));
950  }
951  else
952  return false;
953 }
954 
956 {
957  string s = strstr(external_value_name(e), INTERMEDIATE_VALUE_SUFFIX);
958 
959  return s!=NULL;
960 }
961 
963 {
964  string s = strstr(entity_local_name(e), ADDRESS_OF_SUFFIX);
965 
966  return s!=NULL;
967 }
968 
970 {
971  string s = strstr(entity_local_name(e), SIZEOF_SUFFIX);
972 
973  return s!=NULL;
974 }
975 
977 {
978  /* tells if e is seen as a variable value in the current module */
979  string s = hash_get(hash_value_to_name, (char *) e);
980 
981  if(s == (char*) HASH_UNDEFINED_VALUE) {
982  return false;
983  }
984  else {
985  return true;
986  }
987 }
988 ␌
989 /* used with hash_table_fprintf */
990 static string string_identity(string s)
991 { return s;}
992 
994 {
995  (void) fprintf(stderr,"\nhash table value to name:\n");
998 
999  (void) fprintf(stderr,"\nhash table entity to new value:\n");
1000  /*
1001  hash_table_fprintf(stderr, entity_local_name, external_value_name,
1002  hash_entity_to_new_value);
1003  */
1006 
1007  (void) fprintf(stderr,"\nhash table entity to old value:\n");
1010 
1011  (void) fprintf(stderr, "\nhash table entity to intermediate value:\n");
1014 
1015  (void) fprintf(stderr, "\nhash table reference to address_of value:\n");
1018 
1019  (void) fprintf(stderr, "\nhash table entity to sizeof value:\n");
1022 }
1023 
1025 {
1026  size_t count = 0;
1027  list values = NIL;
1028 
1029  HASH_MAP(var, val, {
1030  if(!gen_in_list_p((entity) val, values)) {
1031  values = CONS(ENTITY,(entity) val, values);
1032  count++;
1033  }
1034  }, h);
1035 
1036  pips_assert("The number of insertions is equal to the list length",
1037  count == gen_length(values));
1038  gen_free_list(values);
1039  return count;
1040 }
1041 
1042 /* Returns the list of entities in the mapping domain
1043  *
1044  * Could be more efficient to return a set.
1045  *
1046  * Note: this is a copy of mapping_to_value_number()
1047 */
1049 {
1050  size_t count = 0;
1051  list values = NIL;
1052 
1053  HASH_MAP(var, val, {
1054  if(!gen_in_list_p((entity) val, values)) {
1055  values = CONS(ENTITY,(entity) var, values);
1056  count++;
1057  }
1058  }, h);
1059 
1060  pips_assert("The number of insertions is equal to the list length",
1061  count == gen_length(values));
1062 
1063  return values;
1064 }
1065 #if 0
1066 /* Returns the list of entities in the mapping range.
1067  *
1068  * Could be more efficient to return a set.
1069  *
1070  * Note: this is a copy of mapping_to_value_number()
1071 */
1072 static list mapping_to_range_list(hash_table h)
1073 {
1074  size_t count = 0;
1075  list values = NIL;
1076 
1077  HASH_MAP(var, val, {
1078  if(!gen_in_list_p((entity) val, values)) {
1079  values = CONS(ENTITY,(entity) val, values);
1080  count++;
1081  }
1082  }, h);
1083 
1084  pips_assert("The number of insertions is equal to the list length",
1085  count == gen_length(values));
1086 
1087  return values;
1088 }
1089 #endif
1090 
1091 /* Return the list of all analyzed variables which are modified in
1092  the current module. If they are modified, they must have old
1093  values. */
1095 {
1096  /* The intermediate values could be used as well */
1097  /*
1098  list ivl = mapping_to_domain_list(hash_entity_to_old_value); // initial
1099  // value list
1100  list wvl = NIL; // written variable list
1101 
1102  FOREACH(ENTITY, e, ivl) {
1103  entity wv = new_value_to_variable(e);
1104  ivl = CONS(ENTITY, wv, ivl);
1105  }
1106 
1107  gen_reverse(wvl);
1108  */
1110  return wvl;
1111 }
1112 
1114 {
1115  int nbo = 0;
1116  int nbi = 0;
1117  int nbn = 0;
1118 
1119  pips_assert("The number of old values is equal to the number of intermediate values",
1122  /* This second assert is too strong when some analyzable variables are
1123  equivalenced together. The number of values required is smaller
1124  since two (or more) different variables share the same value: the
1125  number of entries in the tables is greater than the number of
1126  values. We must compute the number of values in each table.
1127  */
1128  /*
1129  pips_assert("The number of values is greater than the number"
1130  " of new, old and intermediate values",
1131  hash_table_entry_count(hash_value_to_name) >=
1132  hash_table_entry_count(hash_entity_to_new_value)
1133  + nbo + nbi);
1134  */
1138 
1139  /* Why greater instead of equal? Because the equivalence variable
1140  appears in the equivalence equations although it should never
1141  appear in regular constraints, except under its canonical name. */
1142  pips_assert("The number of values with a name is greater than the number"
1143  " of new, old and intermediate values",
1145  nbn + nbo + nbi);
1146 }
1147 
1149 {
1151 }
1152 
1154 {
1155  /* FI: I do not know if equivalenced variables are well taken into account*/
1157 }
1158 
1159 /* FI: looks more like the number of values used. */
1161 {
1163 }
1164 
1165 void allocate_value_mappings(int n, int o, int i)
1166 {
1167  pips_assert("undefined mappings for allocation",
1174 
1175  /* hash_warn_on_redefinition(); */
1181  hash_table_make(hash_pointer, n + o + i + n); // The last +n for the pointer
1183  hash_table_make(hash_pointer, n + o + i + n); // The last +n for the pointer
1186 }
1187 
1188 static void reset_value_mappings(void)
1189 {
1197 }
1198 
1200 {
1202 }
1203 
1204 /* To be called by error handler only. Potential memory leak. */
1206 {
1208 }
1209 
1210 /* Normal call to free the mappings */
1211 
1213 {
1215  pips_assert("no free of undefined mappings",
1218 }
1219 
1220 /* To be called by an error handler */
1221 
1223 {
1224  /* free previous hash tables, desallocate names; this implies ALL
1225  value names were malloced and were not pointer to a ri part */
1226 
1227  /* the three tables are assumed to be allocated all together */
1228 
1229  /* free names in hash_value_to_name; the other two hash tables
1230  contain pointers to the entity tabulated domain and thus need
1231  no value freeing */
1232  /* k is discovered unused by lint; it is syntaxically necessary */
1233  HASH_MAP(k, v, {free(v);}, hash_value_to_name);
1234  // Do not deallocate the names: they are pointers towards parts of
1235  // entity names
1236  //HASH_MAP(k, v, {free(v);}, hash_entity_to_user_value_name);
1237  /* free the three tables themselves */
1245 
1249 }
1250 ␌
1251 /* HASH TABLE INITIALIZATION */
1252 
1253 /* void add_new_value_name(entity e): add a new value name for entity e */
1255 {
1256  string new_value_name =
1258  (char *) NULL));
1259  pips_debug(8,"begin: for %s\n", entity_name(e));
1261  hash_put(hash_value_to_name, (char *) e, (char *) new_value_name);
1262  else
1263  free(new_value_name);
1264 }
1265 
1266 /* The address is the address of a variable or of a reference such as
1267  * &a[5], not a of a value. The reference must be a constant memory
1268  * access path. It does not have to be atomic, as struct are not
1269  * considered atomic, following Pierre Jouvelot's view point since
1270  * partial updates are possible.
1271  *
1272  * An address is a constant within a C user function.
1273  *
1274  * As a constant, it must be encoded as a 0-ary function, just like 1.0 or true.
1275  *
1276  * We use the user representation as entity name, namey &a[5].
1277  *
1278  * We do not use array names as constant pointers because they alreay
1279  * are entities with types and storage. So the address of array a is
1280  * &a[0].
1281  *
1282  * References can be points-to references, i.e. fields can be encoded
1283  * as indices.
1284  */
1286 {
1288  // if(can_be_constant_path_p(r) /*strict_constant_path_p(r)*/) {
1289  /*strict_constant_path_p(r)*/
1291  entity v = reference_variable(r);
1292  /* Should this local constant be added to the module declarations ? */
1293  string mn = (string) entity_module_name(v);
1294  string ln = strdup(concatenate("&", reference_to_string(r), NULL));
1297  a = FindOrCreateEntity(mn, ln);
1298  entity_type(a) = ft;
1305  }
1306  return a;
1307 }
1308 
1310 {
1311  pips_internal_error("Obsolete function.\n");
1312  entity e = reference_variable(r);
1313  entity address_of_value;
1314  string address_of_value_name;
1315  string indice = strstr(reference_to_string(r), "[");
1316 
1317  if (indice != NULL)
1318  address_of_value_name = concatenate(
1319  entity_name(e), indice, ADDRESS_OF_SUFFIX, (char *) NULL);
1320  else
1321  address_of_value_name = concatenate(
1322  entity_name(e), ADDRESS_OF_SUFFIX, (char *) NULL);
1323 
1324 
1325  //address_of_value = gen_find_entity(address_of_value_name);
1326  address_of_value = gen_find_tabulated(address_of_value_name, entity_domain);
1327  //if (entity_undefined_p(address_of_value))
1328  if(address_of_value == entity_undefined)
1329  address_of_value = make_entity(strdup(address_of_value_name),
1330  copy_type(t),
1332  value_undefined);
1333 
1334  /* add the couple (e, address_of_value) */
1336  hash_put(hash_reference_to_address_of_value, (char *) r, (char *) address_of_value);
1337  /* add its name */
1338  hash_put(hash_value_to_name, (char *) address_of_value,
1339  strdup(entity_name(address_of_value)));
1340  // The next table be reset after the analysis, can't be reuse for the prettyprint, so useless to add in the table?
1341  entity v = value_to_variable(address_of_value);
1342  hash_put(hash_entity_to_user_value_name, (char *) address_of_value,
1343  strdup(concatenate("&", entity_user_name(v), indice, (char *) NULL)));
1344  }
1345 }
1346 
1347 /* For a given architecture, sizeof(t) is a constant. It has no old
1348  * value, no new value, it is a value.
1349  *
1350  * Constants are encoded as 0-ary functions, not as values.
1351  */
1353 {
1354  entity sizeof_value;
1355  string sizeof_value_name;
1356 
1357  // improvement create the entity with the name of type
1358  // issue because of value_to_variable
1359  /* find the sizeof entity if possible, else, generate it */
1360  sizeof_value_name =
1361  concatenate(
1363  type_to_full_string_definition(t), SIZEOF_SUFFIX, (char *) NULL);
1364  sizeof_value = gen_find_tabulated(sizeof_value_name, entity_domain);
1365  if(sizeof_value == entity_undefined)
1366  sizeof_value =
1367  make_entity(strdup(sizeof_value_name),
1368  //make_type(is_type_variable,
1369  // make_variable(make_basic(is_basic_int, (void*)sizeof(int)),NIL,NIL)),
1370  copy_type(t),
1372  value_undefined);
1373  /* add the couple (e, old_value) */
1375  hash_put(hash_type_to_sizeof_value, (char *) t, (char *) sizeof_value);
1376  /* add its name */
1377  hash_put(hash_value_to_name, (char *) sizeof_value,
1378  strdup(entity_name(sizeof_value)));
1379  hash_put(hash_entity_to_new_value, (char *) sizeof_value,
1380  (char *) sizeof_value);
1381  hash_put(hash_entity_to_user_value_name, (char *) sizeof_value,
1382  concatenate("sizeof(", type_to_full_string_definition(t), ")", (char *) NULL));
1383  }
1384 }
1385 
1387 {
1388  pips_debug(8,"begin: for %s\n", entity_name(e));
1389  if(hash_get(hash_entity_to_new_value, (char *) e)
1390  == HASH_UNDEFINED_VALUE) {
1391  hash_put(hash_entity_to_new_value, (char *) e, (char *) e);
1392  add_new_value_name(e);
1393  }
1394 }
1395 
1397 {
1399  pips_debug(8, "begin: for %s and %s\n",
1400  entity_name(e),entity_name(a));
1401  pips_assert("hash_entity_to_new_value is defined",
1402  (hash_get(hash_entity_to_new_value, (char *) e)
1403  == HASH_UNDEFINED_VALUE));
1404 
1405  v = entity_to_new_value(a);
1406 
1407  hash_put(hash_entity_to_new_value, (char *) e, (char *) v);
1408  /* add_new_value_name(e); */
1409 }
1410 
1412 {
1413  /* there is no decisive test here; a necessary condition is used instead */
1414 
1415  entity e_new;
1416 
1417  pips_assert("e must be a type analyzable scalar variable", analyzable_scalar_entity_p(e));
1418  e_new = e;
1419  return e_new;
1420 }
1421 
1423 {
1424  /* find the old value entity if possible or abort
1425  I should never have to call this function on an local entity
1426  (local entities include static local variables) */
1427 
1428  entity old_value;
1429  string old_value_name;
1430 
1431  old_value_name = concatenate(entity_name(e),OLD_VALUE_SUFFIX,
1432  (char *) NULL);
1433  old_value = gen_find_tabulated(old_value_name, entity_domain);
1434 
1435  pips_assert("external_entity_to_old_value", old_value!=entity_undefined);
1436 
1437  return old_value;
1438 }
1439 
1441 {
1442  entity old_value;
1443  string old_value_name;
1444 
1445  /* find the old value entity if possible, else, generate it */
1446  old_value_name = concatenate(entity_name(e),OLD_VALUE_SUFFIX,
1447  (char *) NULL);
1448  old_value = gen_find_tabulated(old_value_name, entity_domain);
1449  if(old_value == entity_undefined)
1450  old_value = make_entity(strdup(old_value_name),
1451  copy_type(entity_type(e)),
1453  value_undefined);
1454  /* add the couple (e, old_value) */
1456  hash_put(hash_entity_to_old_value, (char *) e, (char *) old_value);
1457  /* add its name */
1458  hash_put(hash_value_to_name, (char *) old_value,
1459  strdup(entity_name(old_value)));
1460  }
1461 }
1462 
1464 {
1466 
1467  pips_assert("add_old_alias_valued", (hash_get(hash_entity_to_old_value, (char *) e)
1468  == HASH_UNDEFINED_VALUE));
1469 
1470  v = entity_to_old_value(a);
1471 
1472  hash_put(hash_entity_to_old_value, (char *) e, (char *) v);
1473  /* add_new_value_name(e); */
1474 }
1475 
1477 {
1478  entity intermediate_value;
1479 
1480  /* get a new intermediate value, if necessary */
1481  if((intermediate_value =
1484  intermediate_value = make_local_intermediate_value_entity(entity_type(e));
1486  (char *) intermediate_value);
1487  /* add its (external) name */
1488  hash_put(hash_value_to_name, (char *) intermediate_value,
1491  (char *) NULL)));
1492  }
1493 }
1494 
1496 {
1498 
1499  pips_assert("add_intermediate_alias_valued",
1501  == HASH_UNDEFINED_VALUE));
1502 
1504 
1505  hash_put(hash_entity_to_intermediate_value, (char *) e, (char *) v);
1506  /* add_new_value_name(e); */
1507 }
1508 
1510 {
1511  entity old_value;
1512 
1513  /* get a new old value, if necessary */
1514  if((old_value =
1515  (entity) hash_get(hash_entity_to_old_value, (char *) e))
1517  old_value = make_local_old_value_entity(entity_type(e));
1518  hash_put(hash_entity_to_old_value, (char *) e, (char *) old_value);
1519  /* add its (external) name */
1520  hash_put(hash_value_to_name, (char *) old_value,
1522  (char *) NULL)));
1523  }
1524 }
1525 
1527 {
1528  entity intermediate_value;
1529 
1530  /* get a new intermediate value, if necessary */
1531  if((intermediate_value =
1534  intermediate_value = make_local_intermediate_value_entity(entity_type(e));
1536  (char *) intermediate_value);
1537  /* add its (external) name */
1538  hash_put(hash_value_to_name, (char *) intermediate_value,
1541  (char *) NULL)));
1542  }
1543 }
1544 
1545 void remove_entity_values(entity e, bool readonly)
1546 {
1547  entity new_value = entity_to_new_value(e);
1548  const char* s;
1549 
1550  /* pips_assert("remove_entity_values", e != entity_undefined); */
1551  pips_assert("remove_entity_values", new_value != entity_undefined);
1552 
1553  s = external_value_name(new_value);
1554  pips_assert("remove_entity_values", s != (char *) NULL);
1555  (void) hash_del(hash_value_to_name, (char *) new_value);
1556  (void) hash_del(hash_entity_to_new_value, (char *) e);
1557 
1558  if(!readonly) {
1559  entity old_value = entity_to_old_value(e);
1560  entity intermediate_value = entity_to_intermediate_value(e);
1561 
1562  pips_assert("remove_entity_values", old_value != entity_undefined);
1563  pips_assert("remove_entity_values",
1564  intermediate_value!=entity_undefined);
1565 
1566  s = external_value_name(old_value);
1567  pips_assert("remove_entity_values", s != (char *) NULL);
1568  (void) hash_del(hash_value_to_name, (char *) old_value);
1569  s = external_value_name(intermediate_value);
1570  pips_assert("remove_entity_values", s != (char *) NULL);
1571  (void) hash_del(hash_value_to_name, (char *) intermediate_value);
1572 
1573  (void) hash_del(hash_entity_to_old_value, (char *) e);
1574  (void) hash_del(hash_entity_to_intermediate_value, (char *) e);
1575  }
1576 }
1577 
1578 void add_synonym_values(entity e, entity eq, bool readonly)
1579 {
1580  /* e and eq are entities whose values are always equal because they
1581  * share the exact same memory location (i.e. they are alias). Values
1582  * for e have already been declared. Values for eq have to be
1583  * declared. */
1584  entity new_value = entity_to_new_value(e);
1585  entity intermediate_value;
1586 
1587  pips_debug(8, "Begin for registered variable %s"
1588  " equivalenced with new variable %s"
1589  " with status %s\n",
1591  readonly? "readonly" : "read/write");
1592 
1594  (char *) new_value);
1595  if(!readonly) {
1596  entity old_value = entity_to_old_value(e);
1597  intermediate_value = entity_to_intermediate_value(e);
1598  add_old_value(eq);
1600  (char *) intermediate_value);
1602  (char *) old_value);
1603  /* hash_put(hash_value_to_name, (char *) old_value_eq, entity_name(old_value_eq)); */
1604  }
1605  /* The name does not change. It is not used until the equivalence
1606  equations are added */
1607  hash_put(hash_value_to_name, (char *) eq,
1609  NEW_VALUE_SUFFIX, (char *) NULL)));
1610 
1611  pips_debug(8, "End\n");
1612 }
1613 
1614 
1615 /* Get the primitive variable associated to any value involved in a
1616  transformer.
1617 
1618  For example can associate values such as "o#0" to "i" (via "i#init").
1619 
1620  This function used to be restricted to values seen by the current
1621  module. It was extended to values in general to cope with translation
1622  issues.
1623 */
1625 {
1626  entity var = entity_undefined;
1627  int l_suffix = -1; /* for gcc only! */
1628  string s = hash_get(hash_value_to_name, (char *) val);
1629  string var_name;
1630 
1631  /* pips_assert("value_to_variable", s != HASH_UNDEFINED_VALUE); */
1632 
1633  /* pips_assert("value_to_variable",
1634  strchr(entity_name(val), (int) SEMANTICS_SEPARATOR) != NULL); */
1635 
1636  // TODO : Maybe redesign the search of suffix/prefix
1637  // Can bug if the variable name is/begin/end with
1638  // o, i, t, new, init, int, address_of see SUFFIX and PREFIX in transformer.h
1639  if(s == HASH_UNDEFINED_VALUE) {
1640  /* this may be a value, but it is unknown in the current module */
1641  string val_name = entity_name(val);
1642 
1643  if(strstr(val_name, NEW_VALUE_SUFFIX) != NULL)
1644  l_suffix = strlen(NEW_VALUE_SUFFIX);
1645  else if(strstr(val_name, OLD_VALUE_SUFFIX) != NULL)
1646  l_suffix = strlen(OLD_VALUE_SUFFIX);
1647  else if(strstr(val_name, INTERMEDIATE_VALUE_SUFFIX) != NULL)
1648  l_suffix = strlen(INTERMEDIATE_VALUE_SUFFIX);
1649  else if(strstr(val_name, ADDRESS_OF_SUFFIX) != NULL)
1650  l_suffix = strlen(ADDRESS_OF_SUFFIX);
1651  else if(strstr(val_name, SIZEOF_SUFFIX) != NULL)
1652  l_suffix = 0;
1653  else if(strchr(val_name, (int) SEMANTICS_SEPARATOR) == NULL) {
1654  /* new values in fact have no suffixes... */
1655  l_suffix = 0;
1656  }
1657  else
1658  pips_internal_error("%s is not a non-local value", entity_name(val));
1659 
1660  s = val_name;
1661  }
1662  else {
1663  if(sizeof_value_entity_p(val))
1664  l_suffix = 0;
1665  else if(new_value_entity_p(val))
1666  l_suffix = strlen(NEW_VALUE_SUFFIX);
1667  else if(old_value_entity_p(val))
1668  l_suffix = strlen(OLD_VALUE_SUFFIX);
1669  else if(intermediate_value_entity_p(val))
1670  l_suffix = strlen(INTERMEDIATE_VALUE_SUFFIX);
1671  else if(address_of_value_entity_p(val))
1672  l_suffix = strlen(ADDRESS_OF_SUFFIX);
1673  else
1674  /* It can be an equivalenced variable... Additional testing
1675  should be performed! */
1676  pips_internal_error("%s is not a locally visible value",
1677  entity_name(val));
1678  }
1679 
1680  var_name = strdup(s);
1681  *(var_name+strlen(var_name)-l_suffix) = '\0';
1682  if(address_of_value_entity_p(val)) {
1683  string temp = strstr(var_name, "[");
1684  if(temp != NULL)
1685  *temp = '\0';
1686  }
1687 
1688  var = gen_find_tabulated(var_name, entity_domain);
1689  free(var_name);
1690 
1691  if( var == entity_undefined )
1692  pips_internal_error("no related variable for val=%s",
1693  entity_name(val));
1694 
1695  return var;
1696 }
1697 ␌
1699 {
1700  entity var = entity_undefined;
1701  entity n_val = entity_undefined;
1702 
1703  var = value_to_variable(o_val);
1704  /* o_val = variable_to_old_value(var); */
1705  n_val = entity_to_new_value(var);
1706 
1707  return n_val;
1708 }
1709 
1711 {
1712  entity o_val = entity_undefined;
1713 
1714  /* FI: correct code
1715  entity var = entity_undefined;
1716 
1717  var = value_to_variable(n_val);
1718  o_val = entity_to_old_value(var);
1719  */
1720 
1721  /* FI: faster code */
1722  o_val = entity_to_old_value(n_val);
1723 
1724  return o_val;
1725 }
1726 
1727 /* Static aliasing. useful for Fortran, useless for C. When no alias
1728  is found, an undefined entity must be returned. */
1730 {
1732 
1733  pips_debug(8,"begin: for %s\n", entity_name(e));
1734 
1735  /* lookup the current value name mapping and return an arbitrary "representant"
1736  of the interprocedural alias set of e; the equivalence relation is "has
1737  same location" */
1738  HASH_FOREACH(entity, var, string, val, hash_value_to_name) {
1739  if(variable_entity_p(var)
1740  && entities_may_conflict_p(var, e)) {
1741  a = var;
1742  break;
1743  }
1744  }
1745 
1746  if(a==entity_undefined)
1747  pips_debug(8, "return: %s\n", "entity_undefined");
1748  else
1749  pips_debug(8, "return: %s\n", entity_name(a));
1750 
1751  return a;
1752 }
1753 
1754 /* FI: not used, not debugged */
1756 {
1758  return v;
1759 }
1760 
1761 /* for debugging purposes */
1763 {
1764  return entity_name(v);
1765 }
1766 
1767 /* For debugging purposes, we might have to print system with temporary
1768  values */
1770 {
1771  const char* n ;
1772 
1774  n = entity_local_name(v);
1775  }
1776  else {
1777  n = external_value_name(v);
1778  }
1779 
1780  return n;
1781 }
functional make_functional(list a1, type a2)
Definition: ri.c:1109
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
storage make_storage_rom(void)
Definition: ri.c:2285
type copy_type(type p)
TYPE.
Definition: ri.c:2655
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
type make_type_functional(functional _field_)
Definition: ri.c:2718
symbolic make_symbolic(expression a1, constant a2)
Definition: ri.c:2369
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
void free_type(type p)
Definition: ri.c:2658
constant make_constant_unknown(void)
Definition: ri.c:424
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
value make_value_symbolic(symbolic _field_)
Definition: ri.c:2838
static int count
Definition: SDG.c:519
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
bool entity_heap_location_p(entity b)
package abstract location.
bool entity_typed_anywhere_locations_p(entity e)
Test if an entity is the bottom of the lattice.
Pvecteur vect_rename_variables(Pvecteur v, bool(*renamed_p)(Variable), Variable(*new_variable)(Variable))
Pvecteur vect_rename_variables(v, renamed_p, new_variable) Pvecteur v; bool (*renamed_p)(Variable); V...
Definition: base.c:281
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
bool generic_atomic_points_to_reference_p(reference, bool)
Is it a unique concrete memory location?
Definition: points_to.c:489
bool null_pointer_value_entity_p(entity)
bool store_independent_points_to_reference_p(reference)
Functions for points-to references, the kind of references used in points-to cells.
Definition: points_to.c:1247
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
gen_chunk * gen_check(gen_chunk *obj, int t)
GEN_CHECK checks that the gen_chunk received OBJ is of the appropriate TYPE.
Definition: genClib.c:2356
void free(void *)
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#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
void hash_table_fprintf(FILE *f, gen_string_func_t key_to_string, gen_string_func_t value_to_string, const hash_table htp)
This function prints the content of the hash_table pointed to by htp on file descriptor f,...
Definition: hash.c:548
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
Definition: hash.c:491
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
void * hash_del(hash_table htp, const void *key)
this function removes from the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:439
int hash_table_entry_count(hash_table htp)
now we define observers in order to hide the hash_table type...
Definition: hash.c:818
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
void reset_hooks_unregister(reset_func_t)
remove registered cleanup hook.
Definition: reset_hooks.c:73
#define BLOCK_SEP_CHAR
Definition: naming-local.h:51
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define MODULE_SEP_STRING
Definition: naming-local.h:30
const char * entity_minimal_name(entity e)
Do preserve scope informations.
Definition: naming.c:214
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
@ hash_pointer
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define HASH_FOREACH(key_type, k, value_type, v, ht)
Definition: newgen_hash.h:71
#define hash_table_undefined_p(h)
Definition: newgen_hash.h:50
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
string(* gen_string_func_t)(const void *)
Definition: newgen_types.h:111
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#define UU
Definition: newgen_types.h:98
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
char * dump_value_name(entity e)
char * dump_value_name(e): used as functional argument because entity_name is a macro
Definition: io.c:128
entity value_to_variable(entity val)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624
void error_free_value_mappings(void)
To be called by an error handler.
Definition: value.c:1222
entity external_entity_to_old_value(entity e)
Definition: value.c:1422
void add_old_alias_value(entity e, entity a)
Definition: value.c:1463
bool global_intermediate_value_p(entity e)
Definition: value.c:703
static hash_table hash_entity_to_new_value
VARIABLE VALUE MANAGEMENT PACKAGE FOR TRANSFORMERS.
Definition: value.c:219
bool new_value_entity_p(entity e)
the following three functions are directly or indirectly relative to the current module and its value...
Definition: value.c:925
int number_of_analyzed_variables()
FI: looks more like the number of values used.
Definition: value.c:1160
bool intermediate_value_entity_p(entity e)
Definition: value.c:955
void add_intermediate_value(entity e)
Definition: value.c:1476
void test_mapping_entry_consistency()
Definition: value.c:1113
entity entity_to_intermediate_value(entity e)
Definition: value.c:879
int number_of_temporary_values()
Definition: value.c:255
const char * pips_user_value_name(entity e)
This function is called many times when the constraints and the system of constraints are sorted usin...
Definition: value.c:815
bool entity_has_values_p(entity e)
This function could be made more robust by checking the storage of e.
Definition: value.c:911
static bool analyze_string_scalar_entities
Definition: value.c:264
bool complex_analyzed_p()
Definition: value.c:320
static entity make_local_value_entity(int n, int nature, type t)
LOCAL VALUE ENTITY.
Definition: value.c:547
static int local_temporary_value_counter
Definition: value.c:242
bool analyzed_constant_p(entity f)
The constant may appear as a variable in the linear systems.
Definition: value.c:487
void add_address_of_value(reference r, type t)
Definition: value.c:1309
static hash_table hash_reference_to_address_of_value
Definition: value.c:225
static int mapping_to_value_number(hash_table h)
Definition: value.c:1024
static hash_table hash_entity_to_old_value
Definition: value.c:220
bool analyzed_array_type_p(type at)
Definition: value.c:446
entity entity_to_new_value(entity e)
Definition: value.c:859
string value_full_name(entity v)
for debugging purposes
Definition: value.c:1762
void add_synonym_values(entity e, entity eq, bool readonly)
Definition: value.c:1578
entity reference_to_address_of_value(reference r)
Definition: value.c:889
static bool analyze_integer_scalar_entities
TYPING.
Definition: value.c:262
void add_local_old_value(entity e)
Definition: value.c:1509
bool float_analyzed_p()
Definition: value.c:315
bool hash_entity_to_values_undefined_p()
value.c
Definition: value.c:229
const char * external_value_name(entity e)
Definition: value.c:753
entity entity_to_old_value(entity e)
Definition: value.c:869
static list mapping_to_domain_list(hash_table h)
Returns the list of entities in the mapping domain.
Definition: value.c:1048
bool analyzed_struct_type_p(type st)
Definition: value.c:406
bool string_analyzed_p()
Definition: value.c:310
entity make_local_temporary_value_entity_with_basic(basic b)
Definition: value.c:620
bool global_old_value_p(entity e)
Return true if an entity is a global old value (such as "i#init"...).
Definition: value.c:690
bool address_of_value_entity_p(entity e)
Definition: value.c:962
entity new_value_to_old_value(entity n_val)
Definition: value.c:1710
bool analyzed_array_p(entity a)
Does array a contain directly or indirectly a field that may be analyzable?
Definition: value.c:434
bool value_entity_p(entity e)
Definition: value.c:976
bool local_old_value_entity_p(entity e)
Return true if an entity is a local old value (such as "o#0" for a global value "i#init"....
Definition: value.c:642
Pvecteur vect_variables_to_values(Pvecteur v)
FI: not used, not debugged.
Definition: value.c:1755
bool old_value_entity_p(entity e)
Definition: value.c:936
bool analyzed_reference_p(reference r)
FI: Nelson explains the motivation for can_be_constant_path_p() but I do not understand them.
Definition: value.c:518
void set_analyzed_types()
Definition: value.c:271
void add_old_value(entity e)
Definition: value.c:1440
static entity make_local_intermediate_value_entity(type t)
Definition: value.c:600
const char * readable_value_name(entity v)
For debugging purposes, we might have to print system with temporary values.
Definition: value.c:1769
entity global_new_value_to_global_old_value(entity v_new)
Definition: value.c:716
int aproximate_number_of_analyzed_variables()
Definition: value.c:1153
static bool analyze_boolean_scalar_entities
Definition: value.c:263
void add_sizeof_value(type t)
For a given architecture, sizeof(t) is a constant.
Definition: value.c:1352
static bool analyze_complex_scalar_entities
Definition: value.c:266
static int local_old_value_counter
Definition: value.c:241
const char * global_value_name_to_user_name(const char *gn)
HASH TABLE USE.
Definition: value.c:741
void reset_temporary_value_counter()
Definition: value.c:250
void add_intermediate_alias_value(entity e, entity a)
Definition: value.c:1495
bool analyzable_scalar_entity_p(entity e)
The entity type is one of the analyzed types.
Definition: value.c:471
static hash_table hash_entity_to_intermediate_value
Definition: value.c:221
static bool analyze_float_scalar_entities
Definition: value.c:265
bool boolean_analyzed_p()
Definition: value.c:305
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
static string string_identity(string s)
used with hash_table_fprintf
Definition: value.c:990
entity external_entity_to_new_value(entity e)
Definition: value.c:1411
bool local_temporary_value_entity_p(entity e)
Definition: value.c:654
void reset_value_counters()
Definition: value.c:244
entity reference_to_address_entity(reference r)
The address is the address of a variable or of a reference such as &a[5], not a of a value.
Definition: value.c:1285
static hash_table hash_type_to_sizeof_value
Definition: value.c:227
static void add_new_value_name(entity e)
HASH TABLE INITIALIZATION.
Definition: value.c:1254
static bool non_local_temporary_value_entity_p(entity e)
Definition: value.c:660
bool analyzed_entity_p(entity e)
Definition: value.c:457
bool analyzed_struct_p(entity s)
Does struct s contain directly or indirectly a field that may be analyzable?
Definition: value.c:387
void add_new_alias_value(entity e, entity a)
Definition: value.c:1396
bool constant_path_analyzed_p()
Definition: value.c:330
void add_local_intermediate_value(entity e)
Definition: value.c:1526
bool analyzed_type_p(type t)
The type t is one of the analyzed types.
Definition: value.c:367
static int local_intermediate_value_counter
Two counters used to assign meaningless value entities to local variables.
Definition: value.c:240
bool integer_analyzed_p()
Definition: value.c:300
void add_new_value(entity e)
Definition: value.c:1386
void remove_entity_values(entity e, bool readonly)
Definition: value.c:1545
bool pointer_analyzed_p()
Definition: value.c:325
bool analyzed_basic_p(basic b)
The basic corresponds to one of the analyzed types.
Definition: value.c:337
static hash_table hash_entity_to_user_value_name
Definition: value.c:223
entity old_value_to_new_value(entity o_val)
Definition: value.c:1698
void error_reset_value_mappings(void)
To be called by error handler only.
Definition: value.c:1205
list modified_variables_with_values()
Return the list of all analyzed variables which are modified in the current module.
Definition: value.c:1094
static void reset_value_mappings(void)
Definition: value.c:1188
bool global_new_value_p(entity e)
GLOBAL VALUES.
Definition: value.c:667
static entity make_local_old_value_entity(type t)
Definition: value.c:595
static bool analyze_pointer_scalar_entities
Definition: value.c:267
static bool analyze_constant_path
Definition: value.c:269
void reset_analyzed_types()
Definition: value.c:289
void print_value_mappings()
Definition: value.c:993
entity value_alias(entity e)
Static aliasing.
Definition: value.c:1729
entity make_local_temporary_integer_value_entity()
Definition: value.c:629
bool sizeof_value_entity_p(entity e)
Definition: value.c:969
void allocate_value_mappings(int n, int o, int i)
Definition: value.c:1165
bool local_intermediate_value_entity_p(entity e)
Definition: value.c:648
entity make_local_temporary_value_entity(type t)
Definition: value.c:605
static hash_table hash_value_to_name
Definition: value.c:222
int number_of_analyzed_values()
Definition: value.c:1148
bool hash_value_to_name_undefined_p()
Definition: value.c:1199
entity type_to_sizeof_value(type t)
Definition: value.c:899
string reference_to_string(reference r)
Definition: expression.c:87
string type_to_full_string_definition(type)
type.c
Definition: type.c:45
#define make_entity(n, t, s, i)
#define entity_symbolic_p(e)
#define unary_intrinsic_expression(name, e)
Building quickly bool expressions, FC.
#define ADDRESS_OF_OPERATOR_NAME
#define entity_constant_p(e)
@ DEFAULT_ENTITY_KIND
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
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
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
bool typedef_entity_p(entity e)
Definition: entity.c:1902
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
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool abstract_state_variable_p(entity v)
Definition: entity.c:2572
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
expression reference_to_expression(reference r)
Definition: expression.c:196
bool array_type_p(type)
Definition: type.c:2942
bool place_holder_variable_p(entity)
Definition: variable.c:2069
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70
bool type_equal_p(type, type)
Definition: type.c:547
bool variable_in_module_p(entity, entity)
This test can only be applied to variables, not to functions, subroutines or commons visible from a m...
Definition: variable.c:1610
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
list struct_type_to_fields(type)
Definition: type.c:5798
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 volatile_variable_p(variable)
Definition: variable.c:1649
string type_to_string(const type)
type.c
Definition: type.c:51
list struct_variable_to_fields(entity)
Assume that v is declared as a struct.
Definition: variable.c:2045
#define type_enum_p(x)
Definition: ri.h:2968
#define value_undefined
Definition: ri.h:3016
@ is_basic_int
Definition: ri.h:571
#define basic_pointer(x)
Definition: ri.h:637
#define functional_result(x)
Definition: ri.h:1444
#define basic_complex_p(x)
Definition: ri.h:626
#define basic_int_p(x)
Definition: ri.h:614
#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_functional(x)
Definition: ri.h:2952
#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 entity_storage(x)
Definition: ri.h:2794
@ is_storage_rom
Definition: ri.h:2494
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_kind(x)
Definition: ri.h:2798
@ is_type_variable
Definition: ri.h:2900
#define basic_string_p(x)
Definition: ri.h:629
#define entity_type(x)
Definition: ri.h:2792
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define variable_basic(x)
Definition: ri.h:3120
#define basic_logical_p(x)
Definition: ri.h:620
#define basic_float_p(x)
Definition: ri.h:617
#define entity_initial(x)
Definition: ri.h:2796
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
s1
Definition: set.c:247
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define INTERMEDIATE_VALUE_SUFFIX
#define OLD_VALUE_PREFIX
internal entity names (FI: I should have used suffixes to be consistent with external suffixes
#define TEMPORARY_VALUE_PREFIX
#define NEW_VALUE_SUFFIX
external suffixes (NEW_VALUE_SUFFIX is not used, new values are represented by the variable itself,...
#define OLD_VALUE_SUFFIX
#define SEMANTICS_SEPARATOR
Must be used in suffixes and prefixes below.
#define SEMANTICS_MODULE_NAME
include file for transformer library
#define INTERMEDIATE_VALUE_PREFIX
#define SIZEOF_SUFFIX
#define ADDRESS_OF_SUFFIX
A gen_chunk is used to store every object.
Definition: genC.h:58
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60