PIPS
locations.c File Reference
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "c_syntax.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text.h"
#include "text-util.h"
#include "misc.h"
+ Include dependency graph for locations.c:

Go to the source code of this file.

Functions

static string constant_memory_access_path_to_location_name (reference cp)
 package location. More...
 
entity make_location_entity (reference cp)
 locations.c More...
 
entity constant_memory_access_path_to_location_entity (reference cp)
 A constant memory access path may not be considered. More...
 
bool location_entity_p (entity le)
 
bool location_entity_of_module_p (entity le, entity m)
 
bool array_location_entity_of_module_p (entity le, entity m)
 Expanded version of location_entity_of_module_p() More...
 
list module_to_analyzed_array_locations (entity m)
 m is supposed to be a module entity More...
 

Function Documentation

◆ array_location_entity_of_module_p()

bool array_location_entity_of_module_p ( entity  le,
entity  m 
)

Expanded version of location_entity_of_module_p()

Parameters
lee

Definition at line 374 of file locations.c.

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 }
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_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
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_reference(x)
Definition: ri.h:3085
#define reference_variable(x)
Definition: ri.h:2326
#define entity_undefined_p(x)
Definition: ri.h:2762
#define value_reference_p(x)
Definition: ri.h:3083
#define entity_initial(x)
Definition: ri.h:2796

References array_type_p(), entity_basic_concrete_type(), entity_initial, entity_module_name(), entity_undefined_p, entity_user_name(), reference_variable, value_reference, value_reference_p, and value_undefined_p.

Referenced by module_to_analyzed_array_locations().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ constant_memory_access_path_to_location_entity()

entity constant_memory_access_path_to_location_entity ( reference  cp)

A constant memory access path may not be considered.

An undefined entity is returned and the caller must handle the issue.

This occurs, for instance, in the semantics analysis when a wider memory effect contain this constant path. E.g. an untyped anwyhere effect.

It also happens when the caller consider a[*] as a constant reference. It is a constant set of references and no entity is returned.

Parameters
cpp

Definition at line 329 of file locations.c.

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 }
entity gen_find_entity(char *s)
Definition: ri.c:2551
void free_reference(reference p)
Definition: ri.c:2050
void free(void *)
static string constant_memory_access_path_to_location_name(reference cp)
package location.
Definition: locations.c:237
reference constant_reference_to_normalized_constant_reference(reference cr)
Allocate a new reference with evaluated subscripts.
Definition: eval.c:1068
#define reference_undefined_p(x)
Definition: ri.h:2303
#define entity_undefined
Definition: ri.h:2761
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87

References constant_memory_access_path_to_location_name(), constant_reference_to_normalized_constant_reference(), cp, entity_undefined, entity_undefined_p, free(), free_reference(), gen_find_entity(), and reference_undefined_p.

Referenced by apply_concrete_effect_to_transformer(), assign_rhs_to_cp_to_transformer(), forward_substitute_array_location_in_transformer(), generic_apply_effect_to_transformer(), generic_effects_maymust_read_or_write_scalar_entity_p(), generic_reference_to_transformer(), generic_unary_operation_to_transformer(), lhs_expression_to_transformer(), new_array_element_backward_substitution_in_transformer(), perform_array_element_substitutions_in_transformer(), pointer_unary_operation_to_transformer(), substitute_struct_stub_in_transformer(), substitute_stubs_in_transformer(), substitute_stubs_in_transformer_with_translation_binding(), transformer_apply_field_assignments_or_equalities(), transformer_apply_unknown_field_assignments_or_equalities(), and update_cp_with_rhs_to_transformer().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ constant_memory_access_path_to_location_name()

static string constant_memory_access_path_to_location_name ( reference  cp)
static

package location.

Francois Irigoin, 2016.

File: locations.c

This file contains various functions to represent specific memory locations, concrete locations, as entities in order to extend the semantics analysis, which is based on scalar entities, for struct fields, pointed struct fields and array elememts.

Concrete locations are represented as constant memory access paths. Those are store-independent references, i.e. references based on a variable and several constant indices. An index can be either an array index, a[5], or a structure field s.f represented as s[2] if f is the second field. When struct and array declarations are nested, the subscript list grows.

Note that some apparently constant memory access paths such as p[3], may hide a pointer dereferencing and not be store-independent (i.e. not a constant memory access path).

Note also that the internal array and struct names include scope information and module information to be unique across a whole program.

So we have to allocate new constant entities to represent each location. These entities belong to a specific module, but not to its declarations. It is not clear at first which local name, which module name (an entity name is the concatenation of its module and local names), which type, which storage and which initial value they should have. Their type should be the type of the scalar accessed. The storage is unclear.

To decide what a location entity should be, we first define a number of constraints that should be met by the chosen implementation.

To perform the semantic analyses, we must be able:

C1. to map a constant memory access path reference to a location entity to reuse the semantics analyses; a possible unique local identifier is the character string representing the constant memory access path, maybe plus some scope information to avoid name conflicts, maybe plus some prefix to check the entity kind as for intermediate or old value entities; two equivalent constant memory access paths, such as a[2] and a[4/2], must be linked to the same location entity

C2. to map a location entity to its user visible name, e.g. "s.f", to derive and allocate value entities and to print out the results in a readable form;

C3. to link a location entity to a constant memory access path to be able to check memory conflicts between aliased locations, for instance, a[*] and a[5], or s.f and s; plus some scope information to distinguish between a in a[*] and a in a[5] since the two a might be declared in different scopes;

C4. to import interprocedural information, including information about global variables; so a location entity should be unique no matter where it is needed; the same constant memory path, which is always defined interprocedurally because variable entities have unique names to exploit a multiscope interprocedural symbol table without any renaming, should lead to the same location entity whether it is processed in a global context, a caller or a callee context;

C5. to obtain the same location memory global name regardless of the PIPS pass ordering;

C6. to type them to decide if their values should be analyzed or not (for instance, integer scalar variables might be the only variables whose values are anayzed; but floating point values might be sought too).

To preserve PIPS intermediate representation internal consistency, we must be able:

C7. to hide location entities in all printouts, including the symbol table;

C8. to (re)perform the memory allocation of static and dynamic variables in any module and not be impacted by location entities (i.e. they are not variables).

To minimize the new development necessary to introduce entity location, we must be able:

C9. to ignore them without adding new tests about entity kinds in existing passes but the semantic analysis. Or to add a small number of tests at a low level, e.g. library ri-util.

C10. to avoid as much as possible modifications of the internal representation delcared in ri.newgen.

Location entities are based, by definition of a reference, on one variable entity defined by the variable field, having a uniquely defined name in the PIPS interprocedural symbol tables, and by a list of constant subscripts, numerical or symbolic, by definition of a constant memory access path.

The definition of an entity implies the definition of its module name, its local name, its type, its storage, its initial value and its kind:

tabulated entity = name:string x type x storage x initial:value x kind:int ;

where kind is redundant with information carried by other fields and only intended to accelerate PIPS procesing by replacing string operations by a unique integer comparison. It would be better to have an enum field to keep track of the different kind of entities.

Location entities could be defined and managed in many different ways:

  1. their module names could be either 1) the module name of their base variable, 2) a special location module name for all locations as is done for values (i.e. the same temporary, old or intermediate value entity may represent differents values in different modules), 3) a special location module name for each module.
  2. their local names contain either 1) a prefix to identify the entity as a location entity, or 2) no prefix as the prefix is no longer necessary as entities have now a "kind" field that could be used instead (but this would not be consistent with the past design choices: names are discriminant and kinds are only used to speed up the processing),
  3. their local names could be either 1) unique within a module (as usual in PIPS), or 2) unique at the interprocedural level.
  4. their local names could be either 1) a unique artificial unique number to disambiguate between different location entities within a module or within the whole symbol table (this may be tricky wrt the pass ordering constraint), 2) a uniquely defined name derived from the base entity local name and the subscripts of the constant memory path (e.g. a print out o the points-to reference), but this might ;
  5. Type: it could be either an address, a pointer, or the type of the value at the location. To be compatible with the semantic analysis, the type of a location entity must be the type of the value.
  6. Initial value: there is no initial value since the location entities are not declared... except when a data structure or an array is statically initialized; this field could be used to link the location entity to its constant access memory path; but the meaning of initial value would be lost and its type would not match the entity type; a mapping could carry the information, but each module would require its own mapping; these mappings would then have to be resources...
  7. Storage some kind of RAM storage is currently expected for all variables wose values at different control points are analyzed. However, the location entities are aliased to some components of programmer variables or memory areas. They should not be taken into account to allocate variables in the different areas. The aliasing information is supposed to be stored implicitly in the offset field of the ram data structure:

ram = function:entity x section:entity x offset:int x shared:entity* ;

but the offset is currently an int. Additional information is carried by the entities in the field shared. This was designed to manage Fortran 77 static aliasing due to the EQUIVALENCE statement and the multiple declarations of commons. To store the constant memory access path reference, it is possible to redefine the offset field, to add a new field in ram, e.g. virtual_offset or internal_offset, or to add a new kind of storage in:

storage = return:entity + ram + formal + rom:unit ;

such as

storage = ... + cmap: reference

  1. If all the information needed is not stored in the location entity and accessible thru the symbol table, additional hash tables could be added. The consistency would have to be tackled globally, as bit as if a new interprocedural symbol table had been added.
  2. additional hash tables could be added to speed up information access even it all the information is already stored in the symbol table. The consistency would have to be maintained only at the module level. The caller is assumed to have checked that cp is a normalized constant memory access path: a[4/2] must have been reduced to a[2]

Due to global variables and various dereferencing, the module name is linked to the module name of elhs and not of the current module.

Definition at line 237 of file locations.c.

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 }
string scope_to_block_scope(string)
Allocate a new string containing only block scope information.
Definition: cyacc.tab.c:268
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
#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 entity_name(x)
Definition: ri.h:2790
char * strdup()

References concatenate(), cp, entity_module_name(), entity_name, module_name(), MODULE_SEP_STRING, reference_to_string(), reference_variable, scope_to_block_scope(), and strdup().

Referenced by constant_memory_access_path_to_location_entity(), and make_location_entity().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ location_entity_of_module_p()

bool location_entity_of_module_p ( entity  le,
entity  m 
)
Parameters
lee

Definition at line 360 of file locations.c.

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 }

References entity_initial, entity_module_name(), entity_undefined_p, entity_user_name(), value_reference_p, and value_undefined_p.

Referenced by clean_up_points_to_stubs().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ location_entity_p()

bool location_entity_p ( entity  le)
Parameters
lee

Definition at line 349 of file locations.c.

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 }

References entity_initial, entity_undefined_p, value_reference_p, and value_undefined_p.

Referenced by entities_maymust_conflict_p(), generic_effects_maymust_read_or_write_scalar_entity_p(), generic_reference_to_transformer(), module_to_value_mappings(), points_to_cells_parameters(), transformer_formal_parameter_projection(), and value_passing_summary_transformer().

+ Here is the caller graph for this function:

◆ make_location_entity()

entity make_location_entity ( reference  cp)

locations.c

Add the new entity to the module declarations

Parameters
cpp

Definition at line 274 of file locations.c.

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 }
type copy_type(type p)
TYPE.
Definition: ri.c:2655
value make_value_reference(reference _field_)
Definition: ri.c:2853
storage copy_storage(storage p)
STORAGE.
Definition: ri.c:2228
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define pips_internal_error
Definition: misc-local.h:149
#define make_entity(n, t, s, i)
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
#define value_code_p(x)
Definition: ri.h:3065
#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 value_code(x)
Definition: ri.h:3067

References code_declarations, CONS, constant_memory_access_path_to_location_name(), constant_reference_to_normalized_constant_reference(), copy_storage(), copy_type(), cp, ENTITY, entity_initial, entity_module_name(), entity_name, entity_storage, entity_undefined_p, free_reference(), gen_find_entity(), make_entity, make_value_reference(), module_name_to_entity(), pips_internal_error, points_to_reference_to_concrete_type(), reference_variable, strdup(), value_code, and value_code_p.

Referenced by add_inter_or_intraprocedural_field_entities(), add_reference_values(), and module_to_value_mappings().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ module_to_analyzed_array_locations()

list module_to_analyzed_array_locations ( entity  m)

m is supposed to be a module entity

Definition at line 393 of file locations.c.

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 }
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#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
bool array_location_entity_of_module_p(entity le, entity m)
Expanded version of location_entity_of_module_p()
Definition: locations.c:374
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References array_location_entity_of_module_p(), code_declarations, CONS, ENTITY, entity_initial, FOREACH, NIL, and value_code.

Referenced by apply_array_effect_to_transformer().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: