PIPS
alias_propagation.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "alias_private.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "database.h"
#include "pipsdbm.h"
#include "resources.h"
#include "misc.h"
#include "properties.h"
#include "transformer.h"
#include "instrumentation.h"
#include "text-util.h"
#include "transformations.h"
#include "callgraph.h"
#include "alias-classes.h"
+ Include dependency graph for alias_propagation.c:

Go to the source code of this file.

Macros

#define ALIAS_SECTION   "ALIAS_SECTION"
 Aliasing occurs when two or more variables refer to the same storage location at the same program point. More...
 

Functions

static void display_alias_propagation_statistics ()
 Special alias section counter. More...
 
expression translate_to_module_frame (entity mod1, entity mod2, expression e1, call c)
 This function translates an expression e1 from the frame of module 1 to the frame of module 2 1.If e1 is a reference:
1.1. More...
 
static void ram_variable_add_aliases (call c, call_site cs, entity actual_var, entity formal_var, expression subval)
 
static bool common_is_visible_p (entity sec, entity mod)
 This function tests if a common com (TOP_LEVEL:~FOO) is visible in the module mod or in at least one callee (direct and indirect) of this module. More...
 
static bool same_section_formal_variable_in_list_p (entity actual_var, entity sec, list actual_path, list l, list l_aliases)
 
static bool same_section_common_variable_in_list_p (entity sec, list l)
 
static void formal_variable_add_aliases (call c, call_site cs, entity actual_var, entity formal_var, expression subval, list l_actuals)
 
static list list_of_same_or_equivalence_arguments (entity e, list l)
 
static void same_or_equivalence_argument_add_aliases (list l, call c, call_site cs, list l_actual, bool equiv)
 Add alias_association for each formal variable whose offset is in the list l. More...
 
static bool add_aliases_for_current_call_site (call c)
 
static void add_aliases_for_current_caller ()
 
static list alias_propagation_callers (list l_callers)
 
bool alias_propagation (char *module_name)
 

Variables

static entity current_mod = entity_undefined
 Define a static stack and related functions to remember the current statement. More...
 
static entity current_caller = entity_undefined
 
static const char * caller_name
 
static list l_current_aliases = NIL
 
static list l_traversed = NIL
 
static int number_of_alias_associations = 0
 
static int number_of_unknown_offsets = 0
 
static int number_of_known_offsets = 0
 
static int number_of_processed_modules = 0
 
static int unique_section_number = 0
 

Macro Definition Documentation

◆ ALIAS_SECTION

#define ALIAS_SECTION   "ALIAS_SECTION"

Aliasing occurs when two or more variables refer to the same storage location at the same program point.

This phase tries to compute as precise as possible the interprocedural alias information in a whole program.

In Fortran 77, there are several ways to create aliases:

  1. EQUIVALENCE: two or more entities in the same program unit share storages units
  2. COMMON: associates different variables in different subprograms with the same storage
  3. An actual argument is passed to different formal parameters
  4. A global variable is passed as an actual argument and a variable aliased to the global variable is passed as another actual argument => alias between the two corresponding formal parameters.
  5. Formal parameters aliases can be passed through chains of calls.

The basic idea for computing interprocedural aliases is to follow all possible chains of argument-parameters and nonlocal variable-parameter bindings at all call sites. The call graph of program is traversed in invocation order, and alias information is accumulated incrementally.

We use the newgen structure alias_association = (formal_parameter,section, offset, call_path) to store alias information for each formal parameter of each module. Call_path = list of call_sites, call_site = (caller, ordering of the call site) (this is the only current way to store the location of a call site).

Let ai be the considering actual argument in the current call site, by separating the treatment of formal parameters from the treatment of global variables, we only have to treat the following case:

  1. Alias between formal parameter and common variable A global variable can only become aliased to a formal parameter in a routine in which it is visible and only by its being passed as an actual argument to that formal parameter.

1.1 Alias created by only one call:

Case 1. ai is a common variable and is visible in the current module or in at least one callee (direct and indirect) of this module => add alias association for fi with section of the common : TOP-LEVEL:~FOO

1.2 Alias created through chain of calls:

Case 2. ai is a formal variable with a common section and this common is visible in the current module or in at least one callee (direct and indirect) of this module => add alias association for fi with section of the common : TOP-LEVEL:~FOO and path = path(formal ai) + (C,ordering)

=> useless tests between fi and other variables in the same common block with ai, if not take into account the size of ai (assumption: no [interprocedural] array bound violation), because the section is not enough (unique)

  1. Alias between formal parameters

2.1 Alias created by only one call:

Case 3. An actual argument is bound to different formal parameters or there are
different actual arguments but equivalent. So for a call site, we can divide the argument list into groups of same actual or equivalence arguments. For example: EQUIVALENCE (V1(1,1),V2(5)) EQUIVALENCE (U,W) CALL FOO(V1,A,B(TR(I)),C,B(TR(K)),B(H),V1(I,J),V2(K),C,A,M,U,W) SUBROUTINE FOO(F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13) => (F1,F7,F8), (F2,F10), (F3,F5,F6),(F4,F9), (F12,F13)

We add alias associations for these formal parameters, all parameters in a same group have same and unique section, path = {(C,ordering)}. The difference among the group (F1,F7,F8), (F12,F13) and the others is that we need to know the initial offsets of F1, F7, F8 and F12, F13 because they can be different variables, and their sections are ram section. For the other cases, we can use section = ALIAS_SPECIAL_i, initial_off = 0.

=> useless tests ??? Not for same variables because the section is unique but useless tests for equivalence variables, as U and V1 have the same section => test between F8,F12, ...

2.2 Alias created through chain of calls

Case 4. Actual arguments are formal variables of the caller and have same section from two included call paths. ai, aj : formal variables, same section, call_path(ai) (is) include(s/d) call_path(aj); add alias association for fi with call_path = path_formal(ai)

  • (C,ordering)

Case 5. Actual argument is a formal variable that has same section with other actual argument that is a common variable:

5.1 If ai is the formal variable => add alias association for fi with call_path = path_formal(ai) + (C,ordering)

5.2 If ai is the common variable => add alias association for fi with call_path = (C,ordering)

To compute the offset, we do not use preconditions that may be corrupted by alias violation

Definition at line 158 of file alias_propagation.c.

Function Documentation

◆ add_aliases_for_current_call_site()

static bool add_aliases_for_current_call_site ( call  c)
static

Correspond to different cases of alias, we make the following groups and order : Case 3. list_of_same_or_equivalence_arguments Case 1 + Case 5.2. common variable Case 2 + Case 4 + Case 5.1. formal variable

To distinguish between equivalence or same argument cases

Definition at line 794 of file alias_propagation.c.

795 {
796  if(call_function(c) == current_mod)
797  {
798  statement stmt = current_statement_head();
799  list l_actuals = call_arguments(c);
800  list l = gen_full_copy_list(l_actuals);
801  int order = statement_ordering(stmt);
802  int i = 0;
804  // list path = gen_full_copy_list(CONS(CALL_SITE,cs,NIL));
805  ifdebug(2)
806  {
807  pips_debug(2,"\nCurrent caller: %s", caller_name);
808  fprintf(stderr,"\nCurrent call site:");
810  }
811  message_assert("call_site is consistent", call_site_consistent_p(cs));
812  l_traversed = NIL;
813  FOREACH(EXPRESSION,actual_arg, l)
814  {
815  i++;
816  if (expression_reference_p(actual_arg))
817  {
818  /* Correspond to different cases of alias, we make the following groups and order :
819  Case 3. list_of_same_or_equivalence_arguments
820  Case 1 + Case 5.2. common variable
821  Case 2 + Case 4 + Case 5.1. formal variable */
822  reference actual_ref = expression_reference(actual_arg);
823  entity actual_var = reference_variable(actual_ref);
824  list l_actual_inds = reference_indices(actual_ref);
825  expression subval = subscript_value_stride(actual_var,l_actual_inds);
827  list l_same_or_equiv = NIL;
828  /* To distinguish between equivalence or same argument cases*/
829  int j = gen_length(l_traversed);
830  bool equiv = false;
831  if (!variable_in_list_p(actual_var,l_traversed))
832  {
833  l_same_or_equiv = list_of_same_or_equivalence_arguments(actual_var,l);
834  if ((int)gen_length(l_traversed)>j) equiv = true;
835  l_traversed = CONS(ENTITY,actual_var,l_traversed);
836  }
837  ifdebug(3)
838  {
839  if (equiv)
840  fprintf(stderr,"\nList of equivalent arguments: ");
841  else
842  fprintf(stderr,"\nList of same arguments: ");
843  MAP(INT,l,
844  {
845  fprintf(stderr,"%d,",l);
846  },l_same_or_equiv);
847  }
848  if (gen_length(l_same_or_equiv) > 1)
849  same_or_equivalence_argument_add_aliases(l_same_or_equiv,c,cs,l_actuals,equiv);
850  if (variable_in_common_p(actual_var))
851  {
852  storage s = entity_storage(actual_var);
853  entity sec = ram_section(storage_ram(s));
854  list l_caller_aliases = alias_associations_list((alias_associations)
855  db_get_memory_resource(DBR_ALIAS_ASSOCIATIONS,caller_name, true));
856  if (common_is_visible_p(sec,current_mod) ||
857  same_section_formal_variable_in_list_p(actual_var,sec,NIL,l_actuals,l_caller_aliases))
858  ram_variable_add_aliases(c,cs,actual_var,formal_var,subval);
859  }
860  if (storage_formal_p(entity_storage(actual_var)))
861  formal_variable_add_aliases(c,cs,actual_var,formal_var,subval,l_actuals);
862  }
863  }
864  l_traversed = NIL;
865  gen_free_list(l);
866  }
867  return true;
868 }
call_site make_call_site(entity a1, intptr_t a2)
bool call_site_consistent_p(call_site p)
#define alias_associations_list(x)
Definition: alias_private.h:86
static void same_or_equivalence_argument_add_aliases(list l, call c, call_site cs, list l_actual, bool equiv)
Add alias_association for each formal variable whose offset is in the list l.
static bool same_section_formal_variable_in_list_p(entity actual_var, entity sec, list actual_path, list l, list l_aliases)
static entity current_caller
static bool common_is_visible_p(entity sec, entity mod)
This function tests if a common com (TOP_LEVEL:~FOO) is visible in the module mod or in at least one ...
static list l_traversed
static void ram_variable_add_aliases(call c, call_site cs, entity actual_var, entity formal_var, expression subval)
static entity current_mod
Define a static stack and related functions to remember the current statement.
static const char * caller_name
static list list_of_same_or_equivalence_arguments(entity e, list l)
static void formal_variable_add_aliases(call c, call_site cs, entity actual_var, entity formal_var, expression subval, list l_actuals)
@ INT
Definition: atomic.c:48
#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
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define message_assert(msg, ex)
Definition: newgen_assert.h:47
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
entity find_ith_formal_parameter(entity the_fnct, int rank)
This function gives back the ith formal parameter, which is found in the declarations of a call or a ...
Definition: entity.c:1863
expression subscript_value_stride(entity arr, list l_inds)
Definition: expression.c:4127
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool variable_in_common_p(entity)
true if v is in a common.
Definition: variable.c:1570
bool variable_in_list_p(entity, list)
Definition: variable.c:1623
#define storage_formal_p(x)
Definition: ri.h:2522
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_ordering(x)
Definition: ri.h:2454
#define entity_storage(x)
Definition: ri.h:2794
#define ram_section(x)
Definition: ri.h:2249
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define reference_indices(x)
Definition: ri.h:2328
#define storage_ram(x)
Definition: ri.h:2521
#define call_arguments(x)
Definition: ri.h:711
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54

References alias_associations_list, call_arguments, call_function, call_site_consistent_p(), caller_name, common_is_visible_p(), CONS, current_caller, current_mod, db_get_memory_resource(), ENTITY, entity_storage, EXPRESSION, expression_reference(), expression_reference_p(), find_ith_formal_parameter(), FOREACH, formal_variable_add_aliases(), fprintf(), gen_free_list(), gen_full_copy_list(), gen_length(), ifdebug, INT, l_traversed, list_of_same_or_equivalence_arguments(), make_call_site(), MAP, message_assert, NIL, pips_debug, print_statement(), ram_section, ram_variable_add_aliases(), reference_indices, reference_variable, same_or_equivalence_argument_add_aliases(), same_section_formal_variable_in_list_p(), statement_ordering, storage_formal_p, storage_ram, subscript_value_stride(), variable_in_common_p(), and variable_in_list_p().

Referenced by add_aliases_for_current_caller().

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

◆ add_aliases_for_current_caller()

static void add_aliases_for_current_caller ( )
static

Definition at line 870 of file alias_propagation.c.

871 {
872  statement caller_statement = (statement) db_get_memory_resource
873  (DBR_CODE,caller_name, true);
874  set_ordering_to_statement(caller_statement);
875  make_current_statement_stack();
876  gen_multi_recurse(caller_statement,
877  statement_domain, current_statement_filter,current_statement_rewrite,
879  NULL);
880  free_current_statement_stack();
882 }
static bool add_aliases_for_current_call_site(call c)
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58

References add_aliases_for_current_call_site(), call_domain, caller_name, db_get_memory_resource(), gen_multi_recurse(), gen_null(), reset_ordering_to_statement(), set_ordering_to_statement(), and statement_domain.

Referenced by alias_propagation_callers().

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

◆ alias_propagation()

bool alias_propagation ( char *  module_name)

No alias for main program

If the current module is never called by the main program => don't need to compute aliases for this module

search for formal parameters in the declaration list

if there is no formal parameter, do nothing

Take the list of callers, if there is no caller, do nothing

The module has no caller => don't need to compute aliases for this module

save to resource

Parameters
module_nameodule_name

Definition at line 903 of file alias_propagation.c.

904 {
905  list l_aliases = NIL;
908  // number_of_alias_associations = 0;
910  debug_on("ALIAS_PROPAGATION_DEBUG_LEVEL");
911  pips_debug(1,"\nBegin alias propagation for module %s \n", module_name);
912  /* No alias for main program*/
914  {
915  if (get_bool_property("ALIAS_CHECKING_USING_MAIN_PROGRAM") &&
917  /* If the current module is never called by the main program =>
918  don't need to compute aliases for this module*/
919  pips_user_warning("Module %s is not called by the main program \n",module_name);
920  else
921  {
923  list l_formals = NIL;
924  /* search for formal parameters in the declaration list */
925  MAP(ENTITY, e,
926  {
927  if (formal_parameter_p(e))
928  l_formals = gen_nconc(l_formals,CONS(ENTITY,e,NIL));
929  },l_decls);
930  /* if there is no formal parameter, do nothing */
931  if (l_formals != NIL)
932  {
933  /* Take the list of callers, if there is no caller, do nothing */
934  callees callers = (callees) db_get_memory_resource(DBR_CALLERS,module_name,true);
935  list l_callers = callees_callees(callers);
936  if (l_callers != NIL)
937  {
938  ifdebug(2)
939  {
940  fprintf(stderr,"The list of formal parameters:");
941  print_entities(l_formals);
942  fprintf(stderr,"\nThe list of callers: ");
944  (void) fprintf(stderr, "%s, ", caller_name);
945  }, l_callers);
946  (void) fprintf(stderr, "\n");
947  }
948  l_aliases = alias_propagation_callers(l_callers);
949  }
950  else
951  /* The module has no caller => don't need to compute aliases for this module*/
952  pips_user_warning("\n Module %s has no caller \n",module_name );
953  }
954  }
955  }
956  /* save to resource */
957  DB_PUT_MEMORY_RESOURCE(DBR_ALIAS_ASSOCIATIONS,module_name,make_alias_associations(l_aliases));
961  debug_off();
962  return true;
963 }
alias_associations make_alias_associations(list a)
Definition: alias_private.c:52
static void display_alias_propagation_statistics()
Special alias section counter.
static int number_of_processed_modules
static list alias_propagation_callers(list l_callers)
bool module_is_called_by_main_program_p(entity mod)
Definition: callgraph.c:103
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....
#define STRING(x)
Definition: genC.h:87
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
#define debug_on(env)
Definition: misc-local.h:157
#define pips_user_warning
Definition: misc-local.h:146
#define debug_off()
Definition: misc-local.h:160
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
code entity_code(entity e)
Definition: entity.c:1098
bool entity_main_module_p(entity e)
Definition: entity.c:700
void print_entities(list l)
Definition: entity.c:167
bool formal_parameter_p(entity)
Definition: variable.c:1489
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define callees_callees(x)
Definition: ri.h:675
#define code_declarations(x)
Definition: ri.h:784
#define entity_undefined
Definition: ri.h:2761

References alias_propagation_callers(), callees_callees, caller_name, code_declarations, CONS, current_mod, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, display_alias_propagation_statistics(), ENTITY, entity_code(), entity_main_module_p(), entity_undefined, formal_parameter_p(), fprintf(), gen_nconc(), get_bool_property(), ifdebug, local_name_to_top_level_entity(), make_alias_associations(), MAP, module_is_called_by_main_program_p(), module_name(), NIL, number_of_processed_modules, pips_debug, pips_user_warning, print_entities(), reset_current_module_entity(), set_current_module_entity(), and STRING.

+ Here is the call graph for this function:

◆ alias_propagation_callers()

static list alias_propagation_callers ( list  l_callers)
static

Traverse each caller and add aliases to the list of aliases (l_current_aliases)

If the current caller is never called by the main program => no need to follow this caller

Definition at line 884 of file alias_propagation.c.

885 {
886  /* Traverse each caller and add aliases to the list of aliases (l_current_aliases) */
888  MAP(STRING, c_name,
889  {
892  if (get_bool_property("ALIAS_CHECKING_USING_MAIN_PROGRAM") &&
894  /* If the current caller is never called by the main program =>
895  no need to follow this caller*/
896  pips_user_warning("Module %s is not called by the main program \n",caller_name);
897  else
899  }, l_callers);
900  return l_current_aliases;
901 }
static void add_aliases_for_current_caller()
static list l_current_aliases
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582

References add_aliases_for_current_caller(), caller_name, current_caller, get_bool_property(), l_current_aliases, local_name_to_top_level_entity(), MAP, module_is_called_by_main_program_p(), module_local_name(), NIL, pips_user_warning, and STRING.

Referenced by alias_propagation().

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

◆ common_is_visible_p()

static bool common_is_visible_p ( entity  sec,
entity  mod 
)
static

This function tests if a common com (TOP_LEVEL:~FOO) is visible in the module mod or in at least one callee (direct and indirect) of this module.

search for the common declaration in the list

search for the common declaration in the callees

Definition at line 466 of file alias_propagation.c.

467 {
468  list l_decl = code_declarations(entity_code(mod));
469  /* search for the common declaration in the list */
470  MAP(ENTITY, ei,
471  {
472  storage si = entity_storage(ei);
473  if (storage_ram_p(si))
474  {
475  entity seci = ram_section(storage_ram(si));
476  if (same_entity_p(sec,seci))
477  return true;
478  }
479  }, l_decl);
480  /* search for the common declaration in the callees */
481  if (!entity_main_module_p(mod))
482  {
483  const char* mod_name = module_local_name(mod);
484  callees all_callees = (callees) db_get_memory_resource(DBR_CALLEES,mod_name,true);
485  list l_callees = callees_callees(all_callees);
486  MAP(STRING,callee_name,
487  {
489  if (common_is_visible_p(sec,current_callee)) return true;
490  },l_callees);
491  }
492  return false;
493 }
static entity current_callee
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
#define storage_ram_p(x)
Definition: ri.h:2519

References callees_callees, code_declarations, current_callee, db_get_memory_resource(), ENTITY, entity_code(), entity_main_module_p(), entity_storage, local_name_to_top_level_entity(), MAP, module_local_name(), ram_section, same_entity_p(), storage_ram, storage_ram_p, and STRING.

Referenced by add_aliases_for_current_call_site(), and formal_variable_add_aliases().

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

◆ display_alias_propagation_statistics()

static void display_alias_propagation_statistics ( )
static

Special alias section counter.

Definition at line 176 of file alias_propagation.c.

177 {
178  user_log("\n Number of added alias associations: %d",number_of_alias_associations);
179  user_log("\n Number of known offsets: %d",number_of_known_offsets);
180  user_log("\n Number of unknown offsets: %d",number_of_unknown_offsets);
181  user_log("\n Number of processed modules: %d\n",number_of_processed_modules);
182 }
void user_log(const char *format,...)
Definition: message.c:234
static int number_of_unknown_offsets
static int number_of_known_offsets
static int number_of_alias_associations

References number_of_alias_associations, number_of_known_offsets, number_of_processed_modules, number_of_unknown_offsets, and user_log().

Referenced by alias_propagation().

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

◆ formal_variable_add_aliases()

static void formal_variable_add_aliases ( call  c,
call_site  cs,
entity  actual_var,
entity  formal_var,
expression  subval,
list  l_actuals 
)
static

a gen_full_copy_list here is to copy the list and its contain without this : gen_write => gen_trav ....=> bug unknown type 1 because the CDR of path point to a newgen data in the caller which is freed before , no more in the memory

To be modified : init_off = lower_offset ...

If offset of aa is not expression_undefined, we must translate it to the module's frame by using binding information

We must translate the subscript value from current caller to the current module's frame by using binding information. This value must be multiplied by the size of array element (number of numerical/character storage units, according to Fortran standard, in PIPS 1 storage unit=1 byte)

init_off <= off <= init_off + SizeOfArray - SizeOfElement (no bound violation ;-))

Definition at line 583 of file alias_propagation.c.

585 {
586  list l_caller_aliases = alias_associations_list((alias_associations)
587  db_get_memory_resource(DBR_ALIAS_ASSOCIATIONS,caller_name,true));
588  pips_debug(2,"\nActual argument %s is a formal parameter",
589  entity_name(actual_var));
591  {
592  entity caller_var = alias_association_variable(aa);
593  if (same_entity_p(caller_var,actual_var))
594  {
595  /* a gen_full_copy_list here is to copy the list and its contain
596  without this : gen_write => gen_trav ....=> bug unknown type 1
597  because the CDR of path point to
598  a newgen data in the caller which is freed before , no more in the memory */
600  list actual_path = alias_association_call_chain(aa);
602  || same_section_formal_variable_in_list_p(actual_var,sec,actual_path,l_actuals,l_caller_aliases)
603  || same_section_common_variable_in_list_p(sec,l_actuals))
604  {
608  expression initial_off = alias_association_offset(aa);
609  /* To be modified : init_off = lower_offset ...*/
610 
611  int init_off = -1;
612  int end_off = -1;
613  // path = gen_nconc(path,gen_full_copy_list(alias_association_call_chain(aa)));
614  ifdebug(3)
615  fprintf(stderr,"\nEntry for %s found in the alias_association",
616  entity_name(caller_var));
617  /* If offset of aa is not expression_undefined, we must translate
618  it to the module's frame by using binding information */
619  if (!expression_undefined_p(initial_off))
620  {
622  initial_off,c);
623  ifdebug(3)
624  {
625  fprintf(stderr, "\nInitial offset expression before translation: \n");
626  print_expression(initial_off);
627  fprintf(stderr, "\nInitial offset expression after translation: \n");
628  print_expression(new_initial_off);
629  }
630  if (!expression_undefined_p(new_initial_off))
631  {
632  if (expression_equal_integer_p(subval,0))
633  off = copy_expression(new_initial_off);
634  else
635  {
636  /* We must translate the subscript value from current caller to the
637  current module's frame by using binding information. This value must be
638  multiplied by the size of array element (number of numerical/character
639  storage units, according to Fortran standard, in PIPS 1 storage unit=1 byte)*/
641  copy_expression(subval),c);
642  ifdebug(3)
643  {
644  fprintf(stderr, "\n Subval expression before translation: \n");
645  print_expression(subval);
646  fprintf(stderr, "\n Subval expression after translation: \n");
647  print_expression(new_subval);
648  }
649  if (!expression_undefined_p(new_subval))
651  copy_expression(new_initial_off),
652  copy_expression(new_subval));
653  }
654  if (expression_constant_p(new_initial_off))
655  {
656  init_off = expression_to_int(new_initial_off);
657  if (array_entity_p(actual_var))
658  {
659  int tmp;
660  if (SizeOfArray(actual_var, &tmp))
661  end_off = tmp - SizeOfElements(variable_basic(type_variable(entity_type(actual_var))))
662  + init_off;
663  }
664  else
665  end_off = init_off;
666  }
667  }
668 
669  }
670  if (expression_undefined_p(off))
672  else
674  /* init_off <= off <= init_off + SizeOfArray - SizeOfElement (no bound violation ;-))*/
675  one_alias = make_alias_association(formal_var,sec,off,init_off,end_off,path);
676  message_assert("alias_association is consistent",
677  alias_association_consistent_p(one_alias));
678  ifdebug(2)
679  print_alias_association(one_alias);
682  CONS(ALIAS_ASSOCIATION,one_alias, NIL));
683  }
684  }
685  },
686  l_caller_aliases);
687 }
bool alias_association_consistent_p(alias_association p)
Definition: alias_private.c:67
alias_association make_alias_association(entity a1, entity a2, expression a3, intptr_t a4, intptr_t a5, list a6)
Definition: alias_private.c:94
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
void print_alias_association(alias_association aa)
Definition: alias_check.c:301
#define CALL_SITE(x)
CALL_SITE.
#define alias_association_section(x)
#define alias_association_variable(x)
#define ALIAS_ASSOCIATION(x)
ALIAS_ASSOCIATION.
Definition: alias_private.h:90
#define alias_association_call_chain(x)
#define alias_association_undefined
Definition: alias_private.h:96
#define alias_association_offset(x)
static bool same_section_common_variable_in_list_p(entity sec, list l)
expression translate_to_module_frame(entity mod1, entity mod2, expression e1, call c)
This function translates an expression e1 from the frame of module 1 to the frame of module 2 1....
if(!(yy_init))
Definition: genread_lex.c:1029
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define PLUS_OPERATOR_NAME
#define binary_intrinsic_expression(name, e1, e2)
bool entity_special_area_p(entity e)
Definition: area.c:154
bool array_entity_p(entity e)
Definition: entity.c:793
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
bool expression_equal_integer_p(expression exp, int i)
================================================================
Definition: expression.c:1977
bool SizeOfArray(entity, int *)
This function computes the total size of a variable in bytes, ie.
Definition: size.c:87
_int SizeOfElements(basic)
This function returns the length in bytes of the Fortran or C type represented by a basic,...
Definition: size.c:297
#define type_variable(x)
Definition: ri.h:2949
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
#define expression_undefined_p(x)
Definition: ri.h:1224
#define entity_type(x)
Definition: ri.h:2792
#define variable_basic(x)
Definition: ri.h:3120

References ALIAS_ASSOCIATION, alias_association_call_chain, alias_association_consistent_p(), alias_association_offset, alias_association_section, alias_association_undefined, alias_association_variable, alias_associations_list, array_entity_p(), binary_intrinsic_expression, CALL_SITE, caller_name, common_is_visible_p(), CONS, copy_expression(), current_caller, current_mod, db_get_memory_resource(), entity_name, entity_special_area_p(), entity_type, expression_constant_p(), expression_equal_integer_p(), expression_to_int(), expression_undefined, expression_undefined_p, fprintf(), gen_full_copy_list(), gen_nconc(), ifdebug, l_current_aliases, make_alias_association(), MAP, message_assert, NIL, number_of_alias_associations, number_of_known_offsets, number_of_unknown_offsets, pips_debug, PLUS_OPERATOR_NAME, print_alias_association(), print_expression(), same_entity_p(), same_section_common_variable_in_list_p(), same_section_formal_variable_in_list_p(), SizeOfArray(), SizeOfElements(), translate_to_module_frame(), type_variable, and variable_basic.

Referenced by add_aliases_for_current_call_site().

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

◆ list_of_same_or_equivalence_arguments()

static list list_of_same_or_equivalence_arguments ( entity  e,
list  l 
)
static

Definition at line 693 of file alias_propagation.c.

694 {
695  list retour = NIL;
696  int j;
697  for (j=1;j<=(int)gen_length(l);j++)
698  {
701  {
704  if (same_entity_p(var,e))
705  retour = CONS(INT,j,retour);
706  else
707  if (entities_may_conflict_p(var,e) &&
709  {
711  retour = CONS(INT,j,retour);
712  }
713  }
714  }
715  return retour;
716 }
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
void const char const char const int
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References CONS, entities_may_conflict_p(), ENTITY, exp, expression_reference(), expression_reference_p(), find_ith_argument(), gen_length(), int, INT, l_traversed, NIL, ref, reference_variable, same_entity_p(), and variable_in_common_p().

Referenced by add_aliases_for_current_call_site().

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

◆ ram_variable_add_aliases()

static void ram_variable_add_aliases ( call  c,
call_site  cs,
entity  actual_var,
entity  formal_var,
expression  subval 
)
static

The offset of actual variable is an integer that can always be translated into the module's frame

We must translate the subscript value from current caller to the current module's frame by using binding information. This value must be multiplied by the size of array element (number of numerical/character storage units, according to Fortran standard, in PIPS 1 storage unit=1 byte)

subval is translated to the module's frame

Attention: normalization of an expression equal to 0 returns a Pvecteur null

initial_off <= off <= initial_off + SizeOfArray - SizeOfElement (no bound violation ;-))

Definition at line 394 of file alias_propagation.c.

396 {
397  storage s = entity_storage(actual_var);
398  ram r = storage_ram(s);
399  entity sec = ram_section(r);
400  int initial_off = ram_offset(r),end_off = -1;
401  list path = CONS(CALL_SITE,cs,NIL);
404  if (array_entity_p(actual_var))
405  {
406  int tmp;
407  if (SizeOfArray(actual_var, &tmp))
408  end_off = tmp - SizeOfElements(variable_basic(type_variable(entity_type(actual_var)))) + initial_off;
409  }
410  else
411  end_off = initial_off;
412  ifdebug(4)
413  {
414  fprintf(stderr, "\nActual argument %s is a ram variable",entity_name(actual_var));
415  fprintf(stderr,"\nwith initial ram offset %d and end offset %d",initial_off,end_off);
416  }
417  if (expression_equal_integer_p(subval,0))
418  /* The offset of actual variable is an integer
419  that can always be translated into the module's frame*/
420  off = int_to_expression(initial_off);
421  else
422  {
423  /* We must translate the subscript value from current caller to the
424  current module's frame by using binding information. This value must be
425  multiplied by the size of array element (number of numerical/character
426  storage units, according to Fortran standard, in PIPS 1 storage unit=1 byte)*/
428  ifdebug(4)
429  {
430  fprintf(stderr, "\nSubval expression before translation:");
431  print_expression(subval);
432  fprintf(stderr, "\nSubval expression after translation:");
433  print_expression(new_subval);
434  }
435  if (!expression_undefined_p(new_subval))
436  {
437  /* subval is translated to the module's frame */
438  if (initial_off ==0)
439  off = copy_expression(new_subval);
440  else
442  int_to_expression(initial_off),
443  copy_expression(new_subval));
444  }
445  }
446  if (expression_undefined_p(off))
448  else
450  /* Attention: normalization of an expression equal to 0 returns a Pvecteur null*/
451  /* initial_off <= off <= initial_off + SizeOfArray - SizeOfElement (no bound violation ;-))*/
452  one_alias = make_alias_association(formal_var,sec,off,initial_off,end_off,path);
454  message_assert("alias_association is consistent",
455  alias_association_consistent_p(one_alias));
456  ifdebug(2)
457  print_alias_association(one_alias);
459  CONS(ALIAS_ASSOCIATION,one_alias, NIL));
460 }
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
#define ram_offset(x)
Definition: ri.h:2251

References ALIAS_ASSOCIATION, alias_association_consistent_p(), alias_association_undefined, array_entity_p(), binary_intrinsic_expression, CALL_SITE, CONS, copy_expression(), current_caller, current_mod, entity_name, entity_storage, entity_type, expression_equal_integer_p(), expression_undefined, expression_undefined_p, fprintf(), gen_nconc(), ifdebug, int_to_expression(), l_current_aliases, make_alias_association(), message_assert, NIL, number_of_alias_associations, number_of_known_offsets, number_of_unknown_offsets, PLUS_OPERATOR_NAME, print_alias_association(), print_expression(), ram_offset, ram_section, SizeOfArray(), SizeOfElements(), storage_ram, translate_to_module_frame(), type_variable, and variable_basic.

Referenced by add_aliases_for_current_call_site(), and same_or_equivalence_argument_add_aliases().

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

◆ same_or_equivalence_argument_add_aliases()

static void same_or_equivalence_argument_add_aliases ( list  l,
call  c,
call_site  cs,
list  l_actual,
bool  equiv 
)
static

Add alias_association for each formal variable whose offset is in the list l.

The offset of the actual variable is an integer that can always be translated into the module's frame

0 <= off <= 0 + array_size_stride (no bound violation ;-))

Definition at line 719 of file alias_propagation.c.

721 {
722  if (equiv)
723  {
724  MAP(INT,k,
725  {
726  expression actual_arg = find_ith_argument(l_actual,k);
727  reference actual_ref = expression_reference(actual_arg);
728  entity actual_var = reference_variable(actual_ref);
730  list l_actual_inds = reference_indices(actual_ref);
731  expression subval = subscript_value_stride(actual_var,l_actual_inds);
732  ram_variable_add_aliases(c,cs,actual_var,formal_var,subval);
733  },l);
734  }
735  else
736  {
737  string istr = int2a(unique_section_number++);
738  string ename = strdup(concatenate(ALIAS_SECTION,istr,NULL));
740  free(ename);
741  free(istr);
742  MAP(INT,k,
743  {
744  expression actual_arg = find_ith_argument(l_actual,k);
745  reference actual_ref = expression_reference(actual_arg);
746  entity actual_var = reference_variable(actual_ref);
748  list l_actual_inds = reference_indices(actual_ref);
749  expression subval = subscript_value_stride(actual_var,l_actual_inds);
751  int end_off = -1;
753  list path = CONS(CALL_SITE,cs,NIL);
754  if (array_entity_p(actual_var))
755  {
756  int tmp;
757  if (SizeOfArray(actual_var, &tmp))
758  end_off = tmp - SizeOfElements(variable_basic(type_variable(entity_type(actual_var))));
759  }
760  else
761  end_off = 0;
762  if (expression_equal_integer_p(subval,0))
763  /* The offset of the actual variable is an integer
764  that can always be translated into the module's frame*/
765  off = int_to_expression(0);
766  else
767  {
769  ifdebug(4)
770  {
771  fprintf(stderr, "\nSubval expression before translation: \n");
772  print_expression(subval);
773  fprintf(stderr, "\nSubval expression after translation: \n");
774  print_expression(off);
775  }
776  }
777  if (expression_undefined_p(off))
779  else
781  /* 0 <= off <= 0 + array_size_stride (no bound violation ;-))*/
782  one_alias = make_alias_association(formal_var,sec,off,0,end_off,path);
784  message_assert("alias_association is consistent",
785  alias_association_consistent_p(one_alias));
786  ifdebug(2)
787  print_alias_association(one_alias);
789  CONS(ALIAS_ASSOCIATION,one_alias, NIL));
790  },l);
791  }
792 }
#define ALIAS_SECTION
Aliasing occurs when two or more variables refer to the same storage location at the same program poi...
static int unique_section_number
void free(void *)
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
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
char * strdup()
char * int2a(int)
util.c
Definition: util.c:42

References ALIAS_ASSOCIATION, alias_association_consistent_p(), alias_association_undefined, ALIAS_SECTION, array_entity_p(), CALL_SITE, concatenate(), CONS, current_caller, current_mod, entity_type, expression_equal_integer_p(), expression_reference(), expression_undefined, expression_undefined_p, find_ith_argument(), find_ith_formal_parameter(), FindOrCreateEntity(), fprintf(), free(), gen_nconc(), ifdebug, INT, int2a(), int_to_expression(), l_current_aliases, make_alias_association(), MAP, message_assert, NIL, number_of_alias_associations, number_of_known_offsets, number_of_unknown_offsets, print_alias_association(), print_expression(), ram_variable_add_aliases(), reference_indices, reference_variable, SizeOfArray(), SizeOfElements(), strdup(), subscript_value_stride(), TOP_LEVEL_MODULE_NAME, translate_to_module_frame(), type_variable, unique_section_number, and variable_basic.

Referenced by add_aliases_for_current_call_site().

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

◆ same_section_common_variable_in_list_p()

static bool same_section_common_variable_in_list_p ( entity  sec,
list  l 
)
static

Definition at line 547 of file alias_propagation.c.

548 {
550  {
552  {
555  if (variable_in_common_p(var))
556  {
557  storage si = entity_storage(var);
558  entity seci = ram_section(storage_ram(si));
559  if (same_entity_p(seci,sec))
560  {
561  pips_debug(3,"\nAliases from an actual argument that is a common variable and has same section with other actual argument that is a formal variable.\n");
562  return true;
563  }
564  }
565  }
566  },l);
567  return false;
568 }

References entity_storage, exp, EXPRESSION, expression_reference(), expression_reference_p(), MAP, pips_debug, ram_section, ref, reference_variable, same_entity_p(), storage_ram, and variable_in_common_p().

Referenced by formal_variable_add_aliases().

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

◆ same_section_formal_variable_in_list_p()

static bool same_section_formal_variable_in_list_p ( entity  actual_var,
entity  sec,
list  actual_path,
list  l,
list  l_aliases 
)
static

INCLUDED CALL CHAIN ????????

Definition at line 504 of file alias_propagation.c.

506 {
508  {
510  {
513  if (!same_entity_p(var,actual_var))
514  {
515  storage si = entity_storage(var);
516  if (storage_formal_p(si))
517  {
519  {
520  entity formal_var = alias_association_variable(aa);
521  if (same_entity_p(formal_var,var))
522  {
523  entity formal_sec = alias_association_section(aa);
524  list formal_path = alias_association_call_chain(aa);
525  if (same_entity_p(formal_sec,sec) &&
526  included_call_chain_p(actual_path,formal_path))
527  {
528  /* INCLUDED CALL CHAIN ????????*/
529  pips_debug(3,"\nAliases from an actual argument that is a formal parameter and has same section with other actual argument (the last one can be a common variable or another formal variable).\n");
530  return true;
531  }
532  }
533  },
534  l_aliases);
535  }
536  }
537  }
538  },l);
539  return false;
540 }
bool included_call_chain_p(list l1, list l2)
Definition: alias_check.c:246

References ALIAS_ASSOCIATION, alias_association_call_chain, alias_association_section, alias_association_variable, entity_storage, exp, EXPRESSION, expression_reference(), expression_reference_p(), included_call_chain_p(), MAP, pips_debug, ref, reference_variable, same_entity_p(), and storage_formal_p.

Referenced by add_aliases_for_current_call_site(), and formal_variable_add_aliases().

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

◆ translate_to_module_frame()

expression translate_to_module_frame ( entity  mod1,
entity  mod2,
expression  e1,
call  c 
)

This function translates an expression e1 from the frame of module 1 to the frame of module 2 1.If e1 is a reference:
1.1.

alias_propagation.c

Common variable in mod1 => return corresponding common variable e2 in mod2 1.2. Special case : e1 is a formal parameter in mod1, mod2 is caller of mod1 => take corresponding actual argument e2 in call c 1.3. From the association information, if we have e1 = e2 where e2 is constant or contains variables of the mod2 => return e2 2.If e1 is a call : 2.1. Storage rom : numerical constant or symbolic value (PARAMETER) => return e1 2.2. Recursive : e1 = ex1 * ey1 ex2 = translate_to_module_frame(mod1,mod2,ex1,c) ey2 = translate_to_module_frame(mod1,mod2,ey1,c)
=> return e2=ex2*ey2 3.If e1 is a range : error

Return expression_undefined if we can not translate

Check if the common variable is also declared in the mod2 or not We can use ram_shared which contains a list of aliased variables with en but it does not work ????
Another way : looking for a variable in the declaration of the mod2 that has the same offset in the same common block

ATTENTION : enti may be an array, such as A(2): COMMON C1,C2,C3,C4,C5 COMMON C1,A(2,2) we must return A(1,1), not A

Special case : e1 is a formal parameter in mod1, mod2 is caller of mod1 miss a check : mod2 = caller of mod1 => can be wrong !!!

Use the association of the call site: Take only the equalities. Project all variables belonging to mod1 , except the current variable e1 there are 2 cases :

  1. The projection is not exact , there are over flows Return the SC_UNDEFINED => what to do, like before ?
  2. The result is exact, three small cases: 2.1 The system is always false sc_empty => unreachable code ? 2.2 The system is always true sc_rn => we have nothing ? 2.3 The system is parametric =>

Look for equality that contain e1 Delete e1 from the vector Check if the remaining of the vectors contains only constant (TCTS) or variables of mod2 => return

Attention : here the transformer binding_context is consistent but not the system ps_tmp. I do not understand why ? fprintf(stderr, "consistent psystem ps_tmp before"); pips_assert("consistent psystem ps_tmp", sc_consistent_p(ps_tmp));

Take only the equations of the system

he coefficient of e is 1 or -1. Check if the remaining vector contains only constant or variavbles of mod2

Numerical constant or symbolic value (PARAMETER)

e1 is a call, not a constant Recursive : with the arguments of the call As our generated expression e1 is a call with operators : +,-,* only, we treat only these cases

Parameters
mod1od1
mod2od2
e11

Definition at line 202 of file alias_propagation.c.

203 {
204  if (!expression_undefined_p(e1)) {
205  syntax syn = expression_syntax(e1);
206  tag t = syntax_tag(syn);
207  switch(t){
208  case is_syntax_reference:
209  {
212  normalized ne;
213  if (variable_in_common_p(en))
214  {
215  /* Check if the common variable is also declared in the mod2 or not
216  * We can use ram_shared which contains a list of aliased variables with en
217  * but it does not work ????
218  * Another way : looking for a variable in the declaration of the mod2
219  * that has the same offset in the same common block */
220  list l_decls = code_declarations(entity_code(mod2));
221  MAP(ENTITY, enti,{
222  if (same_scalar_location_p(en,enti))
223  {
224  pips_debug(4,"\nThe common variable %s is translated\n",entity_local_name(en));
225  if (array_entity_p(enti))
226  {
227  /* ATTENTION : enti may be an array, such as A(2):
228  COMMON C1,C2,C3,C4,C5
229  COMMON C1,A(2,2)
230  we must return A(1,1), not A */
231  variable varenti = type_variable(entity_type(enti));
232  int len = gen_length(variable_dimensions(varenti));
233  list l_inds = make_list_of_constant(1,len);
234  reference refer = make_reference(enti,l_inds);
235  return reference_to_expression(refer);
236  }
237  return entity_to_expression(enti);
238  }
239  },l_decls);
240  // return the common variable although it is not declared in the module !!!!!!
241  // return entity_to_expression(en);
242  }
244  {
246  entity fun = call_function(c);
247  if (same_entity_p(fun,mod1))
248  {
249  /* Special case : e1 is a formal parameter in mod1, mod2 is caller of mod1
250  miss a check : mod2 = caller of mod1 => can be wrong !!!*/
251  int off = formal_offset(fo);
252  list l_args = call_arguments(c);
253  pips_debug(4,"\nThe formal parameter %s is translated to the caller's frame\n",
254  entity_local_name(en));
255  return find_ith_argument(l_args,off);
256  }
257  }
258  /* Use the association of the call site:
259  Take only the equalities.
260  Project all variables belonging to mod1 , except the current variable e1
261  there are 2 cases :
262  1. The projection is not exact , there are over flows
263  Return the SC_UNDEFINED => what to do, like before ?
264  2. The result is exact, three small cases:
265  2.1 The system is always false sc_empty => unreachable code ?
266  2.2 The system is always true sc_rn => we have nothing ?
267  2.3 The system is parametric =>
268 
269  Look for equality that contain e1
270  Delete e1 from the vector
271  Check if the remaining of the vectors contains only constant (TCTS)
272  or variables of mod2 => return*/
273  if (expression_equal_integer_p(e1,0)) return e1;
275  ne = NORMALIZE_EXPRESSION(e1);
276  if (normalized_linear_p(ne))
277  {
278  Pvecteur ve = normalized_linear(ne);
279  Variable vare = var_of(ve);
281  Psysteme ps_tmp = predicate_system(transformer_relation(binding_context));
282  Pbase b_tmp = ps_tmp->base;
283  /* Attention : here the transformer binding_context is consistent
284  but not the system ps_tmp. I do not understand why ?
285  fprintf(stderr, "consistent psystem ps_tmp before");
286  pips_assert("consistent psystem ps_tmp", sc_consistent_p(ps_tmp));*/
287  if (base_contains_variable_p(b_tmp,vare))
288  {
289  Psysteme ps = sc_dup(ps_tmp);
290  Pbase b = ps->base;
291  Pvecteur pv_var = VECTEUR_NUL;
292  for(; !VECTEUR_NUL_P(b); b = b->succ)
293  {
294  Variable var = vecteur_var(b);
295  if ((strcmp(module_local_name(mod1),entity_module_name((entity)var))==0)
296  && (var!=vare))
297  vect_add_elem(&pv_var, var, VALUE_ONE);
298  }
300  ps->nb_ineq = 0;
301  ps = sc_system_projection_along_variables(ps, pv_var);
302  vect_rm(pv_var);
303  if (ps != SC_UNDEFINED)
304  {
305  // the projection is exact
306  Pcontrainte egal, egal1;
307  for (egal = ps->egalites; egal != NULL; egal = egal1)
308  {
309  /* Take only the equations of the system */
310  Pvecteur vec = egal->vecteur;
311  if (vect_contains_variable_p(vec,vare))
312  {
313  Value vale = vect_coeff(vare,vec);
314  Pvecteur newv = VECTEUR_UNDEFINED;
315  if (value_one_p(vale) || value_mone_p(vale))
316  newv = vect_del_var(vec,vare);
317  if (value_one_p(vale))
318  vect_chg_sgn(newv);
319  if (!VECTEUR_UNDEFINED_P(newv))
320  {
321  /*the coefficient of e is 1 or -1.
322  Check if the remaining vector contains only constant
323  or variavbles of mod2*/
324  Pvecteur v;
325  bool check = true;
326  for (v = newv; (v !=NULL) && (check); v = v->succ)
327  {
328  Variable var = v->var;
329  if ((var != TCST) &&
330  (strcmp(module_local_name(mod2),entity_module_name((entity)var))!=0))
331  check = false;
332  }
333  if (check)
334  {
335  pips_debug(4,"\nThe variable %s is translated by using binding information\n",
336  entity_local_name(en));
337  return Pvecteur_to_expression(newv);
338  }
339  vect_rm(newv);
340  }
341  }
342  egal1 = egal->succ;
343  }
344  }
345  sc_rm(ps);
346  }
347  }
348  break;
349  }
350  case is_syntax_call:
351  {
352  call ca = syntax_call(syn);
353  entity fun = call_function(ca);
354  list l_args = call_arguments(ca);
355  if (l_args==NIL)
356  {
357  /* Numerical constant or symbolic value (PARAMETER) */
358  ifdebug(4)
359  {
360  pips_debug(4,"\nNumerical constant or symbolic value is translated\n");
361  print_expression(e1);
362  }
363  return e1;
364  }
365  /* e1 is a call, not a constant
366  Recursive : with the arguments of the call
367  As our generated expression e1 is a call with operators : +,-,* only,
368  we treat only these cases */
369  if (gen_length(l_args)==1)
370  {
371  expression ex1 = EXPRESSION(CAR(l_args));
372  expression ex2 = translate_to_module_frame(mod1, mod2,ex1,c);
373  if (!expression_undefined_p(ex2))
374  return MakeUnaryCall(fun,ex2);
375  }
376  if (gen_length(l_args)==2)
377  {
378  expression ex1 = EXPRESSION(CAR(l_args));
379  expression ey1 = EXPRESSION(CAR(CDR(l_args)));
380  expression ex2 = translate_to_module_frame(mod1,mod2,ex1,c);
381  expression ey2 = translate_to_module_frame(mod1,mod2,ey1,c);
383  return MakeBinaryCall(fun,ex2,ey2);
384  }
385  break;
386  }
387  default:
388  pips_internal_error("Abnormal cases ");
389  break;
390  }}
391  return expression_undefined;
392 }
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
#define value_mone_p(val)
#define value_one_p(val)
int Value
#define VALUE_ONE
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define pips_internal_error
Definition: misc-local.h:149
int tag
TAG.
Definition: newgen_types.h:92
#define NORMALIZE_EXPRESSION(e)
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
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
expression Pvecteur_to_expression(Pvecteur vect)
AP, sep 25th 95 : some usefull functions moved from static_controlize/utils.c.
Definition: expression.c:1825
void clean_all_normalized(expression e)
Definition: expression.c:4102
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
list make_list_of_constant(int val, int number)
of expression
Definition: expression.c:3369
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
bool variable_is_a_module_formal_parameter_p(entity, entity)
Definition: variable.c:1547
bool same_scalar_location_p(entity, entity)
FI: transferred from semantics (should be used for effect translation as well)
Definition: variable.c:1992
#define formal_offset(x)
Definition: ri.h:1408
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define normalized_linear_p(x)
Definition: ri.h:1779
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define storage_formal(x)
Definition: ri.h:2524
#define transformer_relation(x)
Definition: ri.h:2873
#define syntax_call(x)
Definition: ri.h:2736
#define variable_dimensions(x)
Definition: ri.h:3122
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define predicate_system(x)
Definition: ri.h:2069
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
void vect_chg_sgn(Pvecteur v)
void vect_chg_sgn(Pvecteur v): multiplie v par -1
Definition: scalaires.c:151
Pvecteur vecteur
struct Scontrainte * succ
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
Pbase base
Definition: sc-local.h:75
int nb_ineq
Definition: sc-local.h:73
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Variable var
Definition: vecteur-local.h:90
struct Svecteur * succ
Definition: vecteur-local.h:92
transformer formal_and_actual_parameters_association(call c, transformer pre)
formal_and_actual_parameters_association(call c, transformer pre): Add equalities between actual and ...
Definition: transformer.c:2542
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define VECTEUR_UNDEFINED
#define VECTEUR_NUL_P(v)
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
#define var_of(varval)
#define VECTEUR_UNDEFINED_P(v)
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72
Pvecteur vect_del_var(Pvecteur v_in, Variable var)
Pvecteur vect_del_var(Pvecteur v_in, Variable var): allocation d'un nouveau vecteur egal a la project...
Definition: unaires.c:206
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228
bool vect_contains_variable_p(Pvecteur v, Variable var)
bool vect_contains_variable_p(Pvecteur v, Variable var) BA 19/05/94 input : a vector and a variable o...
Definition: unaires.c:415

References array_entity_p(), Ssysteme::base, base_contains_variable_p(), call_arguments, call_function, CAR, CDR, clean_all_normalized(), code_declarations, contraintes_free(), Ssysteme::egalites, ENTITY, entity_code(), entity_local_name(), entity_module_name(), entity_storage, entity_to_expression(), entity_type, EXPRESSION, expression_equal_integer_p(), expression_syntax, expression_undefined, expression_undefined_p, find_ith_argument(), formal_and_actual_parameters_association(), formal_offset, gen_length(), ifdebug, Ssysteme::inegalites, is_syntax_call, is_syntax_reference, make_list_of_constant(), make_reference(), MakeBinaryCall(), MakeUnaryCall(), MAP, module_local_name(), Ssysteme::nb_ineq, NIL, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_debug, pips_internal_error, predicate_system, print_expression(), Pvecteur_to_expression(), ref, reference_to_expression(), reference_variable, same_entity_p(), same_scalar_location_p(), sc_dup(), sc_rm(), storage_formal, Scontrainte::succ, Svecteur::succ, syntax_call, syntax_reference, syntax_tag, TCST, transformer_identity(), transformer_relation, type_variable, value_mone_p, VALUE_ONE, value_one_p, Svecteur::var, var_of, variable_dimensions, variable_in_common_p(), variable_is_a_module_formal_parameter_p(), vect_add_elem(), vect_chg_sgn(), vect_coeff(), vect_contains_variable_p(), vect_del_var(), vect_rm(), Scontrainte::vecteur, VECTEUR_NUL, VECTEUR_NUL_P, VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by alias_check_array_and_scalar_variable_in_caller_flt(), alias_check_array_variable_in_caller_flt(), alias_check_scalar_and_array_variables_in_caller(), alias_check_two_array_variables_in_caller(), formal_variable_add_aliases(), interprocedural_abc_arrays(), ram_variable_add_aliases(), and same_or_equivalence_argument_add_aliases().

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

Variable Documentation

◆ caller_name

◆ current_caller

◆ current_mod

entity current_mod = entity_undefined
static

Define a static stack and related functions to remember the current statement.

Definition at line 165 of file alias_propagation.c.

Referenced by add_aliases_for_current_call_site(), alias_propagation(), formal_variable_add_aliases(), ram_variable_add_aliases(), and same_or_equivalence_argument_add_aliases().

◆ l_current_aliases

◆ l_traversed

list l_traversed = NIL
static

◆ number_of_alias_associations

◆ number_of_known_offsets

◆ number_of_processed_modules

int number_of_processed_modules = 0
static

Definition at line 173 of file alias_propagation.c.

Referenced by alias_propagation(), and display_alias_propagation_statistics().

◆ number_of_unknown_offsets

◆ unique_section_number

int unique_section_number = 0
static

Definition at line 174 of file alias_propagation.c.

Referenced by same_or_equivalence_argument_add_aliases().