PIPS
locations.c
Go to the documentation of this file.
1 /*
2 
3  $Id: locations.c$
4 
5  Copyright 1989-2016 MINES ParisTech
6  Copyright 2009-2010 HPC Project
7 
8  This file is part of PIPS.
9 
10  PIPS is free software: you can redistribute it and/or modify it
11  under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  any later version.
14 
15  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
16  WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  FITNESS FOR A PARTICULAR PURPOSE.
18 
19  See the GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
23 
24 */
25 
26 /* package location. Francois Irigoin, 2016.
27  *
28  * File: locations.c
29  *
30  *
31  * This file contains various functions to represent specific memory
32  * locations, concrete locations, as entities in order to extend the
33  * semantics analysis, which is based on scalar entities, for struct fields,
34  * pointed struct fields and array elememts.
35  *
36  * Concrete locations are represented as constant memory access
37  * paths. Those are store-independent references, i.e. references
38  * based on a variable and several constant indices. An index can be
39  * either an array index, a[5], or a structure field s.f represented
40  * as s[2] if f is the second field. When struct and array
41  * declarations are nested, the subscript list grows.
42  *
43  * Note that some apparently constant memory access paths such as
44  * p[3], may hide a pointer dereferencing and not be
45  * store-independent (i.e. not a constant memory access path).
46  *
47  * Note also that the internal array and struct names include scope
48  * information and module information to be unique across a whole
49  * program.
50  *
51  * So we have to allocate new constant entities to represent each
52  * location. These entities belong to a specific module, but not to
53  * its declarations. It is not clear at first which local name, which
54  * module name (an entity name is the concatenation of its module and
55  * local names), which type, which storage and which initial value
56  * they should have. Their type should be the type of the scalar
57  * accessed. The storage is unclear.
58  *
59  * To decide what a location entity should be, we first define a
60  * number of constraints that should be met by the chosen
61  * implementation.
62  *
63  * To perform the semantic analyses, we must be able:
64  *
65  * C1. to map a constant memory access path reference to a location
66  * entity to reuse the semantics analyses; a possible unique local
67  * identifier is the character string representing the constant memory
68  * access path, maybe plus some scope information to avoid name
69  * conflicts, maybe plus some prefix to check the entity kind as for
70  * intermediate or old value entities; two equivalent constant memory
71  * access paths, such as a[2] and a[4/2], must be linked to the same
72  * location entity
73  *
74  * C2. to map a location entity to its user visible name, e.g. "s.f",
75  * to derive and allocate value entities and to print out the results
76  * in a readable form;
77  *
78  * C3. to link a location entity to a constant memory access path to
79  * be able to check memory conflicts between aliased locations, for
80  * instance, a[*] and a[5], or s.f and s; plus some scope information
81  * to distinguish between a in a[*] and a in a[5] since the two a
82  * might be declared in different scopes;
83  *
84  * C4. to import interprocedural information, including information
85  * about global variables; so a location entity should be unique no
86  * matter where it is needed; the same constant memory path, which is
87  * always defined interprocedurally because variable entities have
88  * unique names to exploit a multiscope interprocedural symbol table
89  * without any renaming, should lead to the same location entity
90  * whether it is processed in a global context, a caller or a callee
91  * context;
92  *
93  * C5. to obtain the same location memory global name regardless of
94  * the PIPS pass ordering;
95  *
96  * C6. to type them to decide if their values should be analyzed or
97  * not (for instance, integer scalar variables might be the only
98  * variables whose values are anayzed; but floating point values might
99  * be sought too).
100  *
101  * To preserve PIPS intermediate representation internal consistency,
102  * we must be able:
103  *
104  * C7. to hide location entities in all printouts, including the
105  * symbol table;
106  *
107  * C8. to (re)perform the memory allocation of static and dynamic
108  * variables in any module and not be impacted by location entities
109  * (i.e. they are not variables).
110  *
111  * To minimize the new development necessary to introduce entity
112  * location, we must be able:
113  *
114  * C9. to ignore them without adding new tests about entity kinds in
115  * existing passes but the semantic analysis. Or to add a small number
116  * of tests at a low level, e.g. library ri-util.
117  *
118  * C10. to avoid as much as possible modifications of the internal
119  * representation delcared in ri.newgen.
120  *
121  * Location entities are based, by definition of a reference, on one
122  * variable entity defined by the variable field, having a uniquely
123  * defined name in the PIPS interprocedural symbol tables, and by a
124  * list of constant subscripts, numerical or symbolic, by definition
125  * of a constant memory access path.
126  *
127  * The definition of an entity implies the definition of its module
128  * name, its local name, its type, its storage, its initial value and
129  * its kind:
130  *
131  * tabulated entity = name:string x type x storage x initial:value x kind:int ;
132  *
133  * where kind is redundant with information carried by other fields
134  * and only intended to accelerate PIPS procesing by replacing string
135  * operations by a unique integer comparison. It would be better to
136  * have an enum field to keep track of the different kind of entities.
137  *
138  * Location entities could be defined and managed in many different ways:
139  *
140  * 1. their module names could be either 1) the module name of their
141  * base variable, 2) a special location module name for all locations
142  * as is done for values (i.e. the same temporary, old or intermediate
143  * value entity may represent differents values in different modules),
144  * 3) a special location module name for each module.
145  *
146  * 2. their local names contain either 1) a prefix to identify the
147  * entity as a location entity, or 2) no prefix as the prefix is no
148  * longer necessary as entities have now a "kind" field that could be
149  * used instead (but this would not be consistent with the past design
150  * choices: names are discriminant and kinds are only used to speed up
151  * the processing),
152  *
153  * 3. their local names could be either 1) unique within a module (as
154  * usual in PIPS), or 2) unique at the interprocedural level.
155  *
156  * 4. their local names could be either 1) a unique artificial unique
157  * number to disambiguate between different location entities within a
158  * module or within the whole symbol table (this may be tricky wrt the
159  * pass ordering constraint), 2) a uniquely defined name derived from
160  * the base entity local name and the subscripts of the constant
161  * memory path (e.g. a print out o the points-to reference), but this might ;
162  *
163  * 5. Type: it could be either an address, a pointer, or the type of
164  * the value at the location. To be compatible with the semantic
165  * analysis, the type of a location entity must be the type of the
166  * value.
167  *
168  * 6. Initial value: there is no initial value since the location
169  * entities are not declared... except when a data structure or an
170  * array is statically initialized; this field could be used to link
171  * the location entity to its constant access memory path; but the
172  * meaning of initial value would be lost and its type would not match
173  * the entity type; a mapping could carry the information, but each
174  * module would require its own mapping; these mappings would then
175  * have to be resources...
176  *
177  * 7. Storage some kind of RAM storage is currently expected for all
178  * variables wose values at different control points are
179  * analyzed. However, the location entities are aliased to some
180  * components of programmer variables or memory areas. They should not
181  * be taken into account to allocate variables in the different
182  * areas. The aliasing information is supposed to be stored implicitly
183  * in the offset field of the ram data structure:
184  *
185  * ram = function:entity x section:entity x offset:int x shared:entity* ;
186  *
187  * but the offset is currently an int. Additional information is
188  * carried by the entities in the field shared. This was designed to
189  * manage Fortran 77 static aliasing due to the EQUIVALENCE statement
190  * and the multiple declarations of commons. To store the constant
191  * memory access path reference, it is possible to redefine the offset
192  * field, to add a new field in ram, e.g. virtual_offset or
193  * internal_offset, or to add a new kind of storage in:
194  *
195  * storage = return:entity + ram + formal + rom:unit ;
196  *
197  * such as
198  *
199  * storage = ... + cmap: reference
200  *
201  * 8. If all the information needed is not stored in the location
202  * entity and accessible thru the symbol table, additional hash tables
203  * could be added. The consistency would have to be tackled globally,
204  * as bit as if a new interprocedural symbol table had been added.
205  *
206  * 9. additional hash tables could be added to speed up information
207  * access even it all the information is already stored in the symbol
208  * table. The consistency would have to be maintained only at the module level.
209  *
210  */
211 
212 #ifdef HAVE_CONFIG_H
213  #include "pips_config.h"
214 #endif
215 
216 #include <stdio.h>
217 #include <string.h>
218 #include <stdlib.h>
219 
220 #include "genC.h"
221 #include "linear.h"
222 #include "ri.h"
223 #include "effects.h"
224 // #include "points_to_private.h"
225 #include "ri-util.h"
226 #include "c_syntax.h" // for scope_to_block_scope()
227 #include "prettyprint.h" // for debugging
228 #include "effects-util.h"
229 #include "text.h" // for text-util.h
230 #include "text-util.h" // for reference_to_string() ?
231 #include "misc.h" // for pips_internal_error()
232 // #include "properties.h"
233 
234 /* The caller is assumed to have checked that cp is a normalized
235  * constant memory access path: a[4/2] must have been reduced to a[2]
236  */
238 {
239  entity elhs = reference_variable(cp);
240  /* Due to global variables and various dereferencing, the module
241  * name is linked to the module name of elhs and not of the current
242  * module.
243  */
244  //string module_name = get_current_module_name();
245  string module_name = (string) entity_module_name(elhs);
246 
247  string cp_name =
252  (char *) NULL));
253 
254  return cp_name;
255 }
256 
257 /*
258  * Location entity
259  *
260  * If location entities are reused across modules just like value
261  * entities, they can be allocated in a specific package and not break
262  * the consistency of the user module.
263  *
264  * But then call site processing has to be carefully programmed so as
265  * not to use locations in both caller and callee frames at the same
266  * time.
267  *
268  * It is easier to make them local to a specific module.
269  *
270  * Note that no entity is created most of the time. Simple scalar
271  * references return the variable itself.
272  */
273 
275 {
276  entity elhs = reference_variable(cp);
277 
279  // Evaluation the constant subscript expressions such as a[4/2]
281  string cp_name = constant_memory_access_path_to_location_name(ncp);
282 
283  // Do not make the same entity twice
284  entity ecp = gen_find_entity(cp_name);
285  if(entity_undefined_p(ecp)) {
286  ecp = make_entity(
287  strdup(cp_name),
288  copy_type(t),
290  make_value_reference(ncp));
291 
292  /* Add the new entity to the module declarations */
293  string mn = (string) entity_module_name(elhs);
295  value val = entity_initial(m);
296  if(value_code_p(val)) {
297  code c = value_code(val);
298  code_declarations(c) =
299  CONS(ENTITY, ecp, code_declarations(c));
300  }
301  else
302  pips_internal_error("Module entity \"%s\" is not a module.\n",
303  entity_name(m));
304  }
305  else {
306  free_reference(ncp);
307  }
308 
309  // FI: if this is useful to maintain the intermediate
310  // representation, then the module owning ecp should be computed. It
311  // does not have to be the current module.
312 
313  // AddEntityToCurrentModuleWithoutDeclaration(ecp);
314 
315  return ecp;
316 }
317 
318 /* A constant memory access path may not be considered. An undefined
319  * entity is returned and the caller must handle the issue.
320  *
321  * This occurs, for instance, in the semantics analysis when a wider
322  * memory effect contain this constant path. E.g. an untyped anwyhere
323  * effect.
324  *
325  * It also happens when the caller consider a[*] as a constant
326  * reference. It is a constant set of references and no entity is
327  * returned.
328  */
330 {
331  entity ecp = entity_undefined;
333  if(!reference_undefined_p(ncp)) {
334  string cp_name = constant_memory_access_path_to_location_name(ncp);
335  free_reference(ncp);
336 
337  // find (or do not create) an entity for the constant path
338  // The entity is supposed to have been created earlier explictly
339  ecp = gen_find_entity(cp_name);
340  if (entity_undefined_p(ecp)) {
341  // pips_internal_error("location entity should have been created explictly during an initialization phase\n");
342  ; // Let the caller deals with the problem
343  }
344  free(cp_name);
345  }
346  return ecp;
347 }
348 
350 {
351  bool location_p = false;
352  if(!entity_undefined_p(le)) {
353  value v = entity_initial(le);
354  if(!value_undefined_p(v))
355  location_p = value_reference_p(v);
356  }
357  return location_p;
358 }
359 
361 {
362  bool location_p = false;
363  if(!entity_undefined_p(le)) {
364  value v = entity_initial(le);
365  if(!value_undefined_p(v))
366  if(value_reference_p(v))
367  // FI: could be checked with a pointer equality via the storage field
368  location_p = strcmp(entity_module_name(le), entity_user_name(m))==0;
369  }
370  return location_p;
371 }
372 
373 /* Expanded version of location_entity_of_module_p() */
375 {
376  bool location_p = false;
377  if(!entity_undefined_p(le)) {
378  value v = entity_initial(le);
379  if(!value_undefined_p(v))
380  if(value_reference_p(v))
381  // FI: could be checked with a pointer equality via the storage field
382  if(strcmp(entity_module_name(le), entity_user_name(m))==0) {
383  reference r = value_reference(v);
384  entity a = reference_variable(r);
386  location_p = array_type_p(t);
387  }
388  }
389  return location_p;
390 }
391 
392 /* m is supposed to be a module entity */
394 {
395  list ll = NIL;
396  value v = entity_initial(m);
397  code c = value_code(v);
398  list dl = code_declarations(c);
399 
400  FOREACH(ENTITY, e, dl) {
402  ll = CONS(ENTITY, e, ll);
403  }
404  return ll;
405 }
entity gen_find_entity(char *s)
Definition: ri.c:2551
type copy_type(type p)
TYPE.
Definition: ri.c:2655
void free_reference(reference p)
Definition: ri.c:2050
value make_value_reference(reference _field_)
Definition: ri.c:2853
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
string scope_to_block_scope(string)
Allocate a new string containing only block scope information.
Definition: cyacc.tab.c:268
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void free(void *)
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
entity constant_memory_access_path_to_location_entity(reference cp)
A constant memory access path may not be considered.
Definition: locations.c:329
bool array_location_entity_of_module_p(entity le, entity m)
Expanded version of location_entity_of_module_p()
Definition: locations.c:374
list module_to_analyzed_array_locations(entity m)
m is supposed to be a module entity
Definition: locations.c:393
bool location_entity_p(entity le)
Definition: locations.c:349
bool location_entity_of_module_p(entity le, entity m)
Definition: locations.c:360
static string constant_memory_access_path_to_location_name(reference cp)
package location.
Definition: locations.c:237
entity make_location_entity(reference cp)
locations.c
Definition: locations.c:274
#define pips_internal_error
Definition: misc-local.h:149
#define MODULE_SEP_STRING
Definition: naming-local.h:30
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
char * string
STRING.
Definition: newgen_types.h:39
string reference_to_string(reference r)
Definition: expression.c:87
#define make_entity(n, t, s, i)
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 module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
reference constant_reference_to_normalized_constant_reference(reference cr)
Allocate a new reference with evaluated subscripts.
Definition: eval.c:1068
bool array_type_p(type)
Definition: type.c:2942
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_code_p(x)
Definition: ri.h:3065
#define value_reference(x)
Definition: ri.h:3085
#define reference_variable(x)
Definition: ri.h:2326
#define reference_undefined_p(x)
Definition: ri.h:2303
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
#define code_declarations(x)
Definition: ri.h:784
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define value_code(x)
Definition: ri.h:3067
#define value_reference_p(x)
Definition: ri.h:3083
#define entity_initial(x)
Definition: ri.h:2796
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
char * strdup()
The structure used to build lists in NewGen.
Definition: newgen_list.h:41