PIPS
dbm_interface.c File Reference
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "database.h"
#include "resources.h"
#include "linear.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "workspace-util.h"
#include "effects-util.h"
#include "pipsdbm.h"
#include "effects-generic.h"
#include "effects-simple.h"
#include "control.h"
#include "misc.h"
#include "transformer.h"
#include "semantics.h"
#include "properties.h"
#include "preprocessor.h"
+ Include dependency graph for dbm_interface.c:

Go to the source code of this file.

Functions

transformer transformer_equality_fix_point (transformer)
 Let A be the affine loop transfert function. More...
 
transformer transformer_pattern_fix_point (transformer)
 This fixpoint function was developped to present a talk at FORMA. More...
 
transformer transformer_derivative_fix_point (transformer)
 Computation of a transitive closure using constraints on the discrete derivative. More...
 
transformer load_completed_statement_transformer (statement s)
 three mappings used throughout semantics analysis: More...
 
static void select_fix_point_operator ()
 
void add_declaration_list_information (transformer pre, list dl, bool precondition_p)
 
static void add_declaration_information (transformer pre, entity m, bool precondition_p)
 
static void transformer_add_declaration_information (transformer pre, entity m)
 
static void precondition_add_declaration_information (transformer pre, entity m)
 
bool transformers_intra_fast (char *module_name)
 Functions to make transformers. More...
 
bool transformers_intra_full (char *module_name)
 
bool transformers_inter_fast (char *module_name)
 
bool transformers_inter_full (char *module_name)
 
bool transformers_inter_full_with_points_to (char *module_name)
 
bool refine_transformers (char *module_name)
 
bool refine_transformers_with_points_to (char *module_name)
 
bool summary_transformer (char *module_name)
 
bool preconditions_intra (char *module_name)
 
bool preconditions_intra_fast (char *module_name)
 
bool preconditions_inter_fast (char *module_name)
 
bool preconditions_inter_full (char *module_name)
 
bool preconditions_inter_full_with_points_to (char *module_name)
 
bool total_preconditions_intra (char *module_name)
 
bool total_preconditions_inter (char *module_name)
 
bool old_summary_precondition (char *module_name)
 
bool intraprocedural_summary_precondition (char *module_name)
 
bool interprocedural_summary_precondition (char *module_name)
 
static void set_use_points_to ()
 
static void reset_use_points_to ()
 
bool use_points_to_p ()
 
bool interprocedural_summary_precondition_with_points_to (char *module_name)
 
static transformer main_summary_precondition (entity callee)
 Special case: main module. More...
 
static transformer ordinary_summary_precondition (const char *module_name, entity callee)
 Standard cases: called modules. More...
 
bool summary_precondition (char *module_name)
 
bool summary_total_postcondition (char *module_name)
 
bool summary_total_precondition (char *module_name)
 
void set_warning_counters (void)
 
bool test_warning_counters (void)
 
bool generic_module_name_to_transformers (const char *module_name, bool in_context)
 bool generic_module_name_to_transformers(char * module_name, bool in_context): compute a transformer for each statement of a module with a given name; compute also the global transformer for the module More...
 
bool module_name_to_transformers_in_context (const char *module_name)
 
bool module_name_to_transformers (const char *module_name)
 
bool module_name_to_preconditions (const char *module_name)
 resource module_name_to_preconditions(char * module_name): compute a transformer for each statement of a module with a given name; compute also the global transformer for the module More...
 
bool module_name_to_total_preconditions (const char *module_name)
 
transformer load_summary_transformer (entity e)
 
void update_summary_precondition (entity e, transformer t)
 void update_summary_precondition(e, t): t is supposed to be a precondition related to one of e's call sites and translated into e's basis; More...
 
transformer load_summary_precondition (entity e)
 summary_preconditions are expressed in any possible frame, in fact the frame of the last procedure that used/produced it More...
 
transformer load_summary_total_postcondition (entity e)
 summary_preconditions are expressed in any possible frame, in fact the frame of the last procedure that used/produced it More...
 
list load_summary_effects (entity e)
 FI->FI, FI->BC: these two functions should be moved into effects-util or effects-simple. More...
 
list load_body_effects (entity e)
 
list load_module_intraprocedural_effects (entity e)
 
void cumulated_effects_map_print (void)
 ca n'a rien a` faire ici, et en plus, il serait plus inte'ressant d'avoir une fonction void statement_map_print(statement_mapping htp) More...
 

Variables

transformer(* transformer_fix_point_operator )(transformer)
 Interface between the untyped database manager and clean code and between pipsmake and clean code. More...
 
bool refine_transformers_p = false
 Transformer recomputation cannot be of real use unless an interprocedural analysis is performed. More...
 
static bool use_points_to_information_p = false
 
static int wc = 0
 FI: Provisional management of warnings. More...
 

Function Documentation

◆ add_declaration_information()

static void add_declaration_information ( transformer  pre,
entity  m,
bool  precondition_p 
)
static

Definition at line 223 of file dbm_interface.c.

224 {
225  //list decls = code_declarations(value_code(entity_initial(m)));
227 
228  ifdebug(8) {
229  pips_debug(8, "Begin for module %s with precondition\n", module_local_name(m));
230  print_transformer(pre);
231  }
232 
233  add_declaration_list_information(pre, decls, precondition_p);
234 
235  ifdebug(8) {
236  pips_debug(8, "End for module %s with precondition\n", module_local_name(m));
237  print_transformer(pre);
238  }
239 
240 }
void add_declaration_list_information(transformer pre, list dl, bool precondition_p)
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define print_transformer(t)
Definition: print.c:357
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
list current_module_declarations()
Definition: module.c:78

References add_declaration_list_information(), current_module_declarations(), ifdebug, module_local_name(), pips_debug, and print_transformer.

Referenced by precondition_add_declaration_information(), and transformer_add_declaration_information().

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

◆ add_declaration_list_information()

void add_declaration_list_information ( transformer  pre,
list  dl,
bool  precondition_p 
)
Parameters
prere
dll
precondition_precondition_p

Definition at line 179 of file dbm_interface.c.

182 {
185  language l = code_language(c);
186 
187  FOREACH(ENTITY, v, dl) {
188  type t = entity_type(v);
189 
190  if(type_variable_p(t)) {
191  variable tv = type_variable(t);
192 
196 
198  Pvecteur vl = normalized_linear(nl);
199  Pvecteur vu = normalized_linear(nu);
200 
203  Pvecteur cv = vect_substract(vl, vu);
204 
205  if(language_c_p(l))
207 
208  if(!precondition_p) {
209  upwards_vect_rename(cv, pre);
210  }
211 
212  if(!vect_constant_p(cv) || vect_coeff(TCST, cv) > 0) {
214  }
215  }
216  }
217  }
218 
219  }
220  }
221 }
#define VALUE_MONE
transformer transformer_inequality_add(transformer tf, Pvecteur i)
Definition: basic.c:375
bool vect_constant_p(Pvecteur)
bool vect_constant_p(Pvecteur v): v contains only a constant term, may be zero
Definition: predicats.c:211
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#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 NORMALIZE_EXPRESSION(e)
#define normalized_linear_p(x)
Definition: ri.h:1779
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define language_c_p(x)
Definition: ri.h:1594
#define dimension_upper(x)
Definition: ri.h:982
#define value_code(x)
Definition: ri.h:3067
#define variable_dimensions(x)
Definition: ri.h:3122
#define entity_type(x)
Definition: ri.h:2792
#define code_language(x)
Definition: ri.h:792
#define normalized_linear(x)
Definition: ri.h:1781
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_initial(x)
Definition: ri.h:2796
bool value_mappings_compatible_vector_p(Pvecteur iv)
transform a vector based on variable entities into a vector based on new value entities when possible...
Definition: mappings.c:924
void upwards_vect_rename(Pvecteur v, transformer post)
Renaming of variables in v according to transformations occuring later.
Definition: mappings.c:1062
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75
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
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

References code_language, DIMENSION, dimension_lower, dimension_upper, ENTITY, entity_initial, entity_type, FOREACH, get_current_module_entity(), language_c_p, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, TCST, transformer_inequality_add(), type_variable, type_variable_p, upwards_vect_rename(), value_code, value_mappings_compatible_vector_p(), VALUE_MONE, variable_dimensions, vect_add_elem(), vect_coeff(), vect_constant_p(), and vect_substract().

Referenced by add_declaration_information().

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

◆ cumulated_effects_map_print()

void cumulated_effects_map_print ( void  )

ca n'a rien a` faire ici, et en plus, il serait plus inte'ressant d'avoir une fonction void statement_map_print(statement_mapping htp)

hash_table_print_header (htp,f);

Definition at line 1549 of file dbm_interface.c.

1550 {
1551  FILE * f =stderr;
1553 
1554  /* hash_table_print_header (htp,f); */
1555 
1556  STATEMENT_EFFECTS_MAP(k, v, {
1557  fprintf(f, "\n\n%td", statement_ordering((statement) k));
1559  },
1560  htp);
1561 }
statement_effects get_cumulated_rw_effects(void)
#define STATEMENT_EFFECTS_MAP(k, v, c, f)
Definition: effects.h:1057
#define effects_effects(x)
Definition: effects.h:710
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define print_effects(e)
Definition: print.c:334
#define statement_ordering(x)
Definition: ri.h:2454
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References effects_effects, f(), fprintf(), get_cumulated_rw_effects(), print_effects, STATEMENT_EFFECTS_MAP, and statement_ordering.

+ Here is the call graph for this function:

◆ generic_module_name_to_transformers()

bool generic_module_name_to_transformers ( const char *  module_name,
bool  in_context 
)

bool generic_module_name_to_transformers(char * module_name, bool in_context): compute a transformer for each statement of a module with a given name; compute also the global transformer for the module

intraprocedural preconditions: proper declarations

This stack is useful to document warnings and to retrieve points-to information.

could be a gen_find_tabulated as well...

cumulated_effects_map_print();

compute the basis related to module m

In the main module, transformers can be computed in context of the initial values

Add declaration information: arrays cannot be empty (Fortran standard, Section 5.1.2)

Get the preconditions: they might prove useful within loops where transformers cannot propagate enough information.

compute intraprocedural transformer

FI: side effect; compute and store the summary transformer, because every needed piece of data is available...

filter out local variables from the global intraprocedural effect

Two auxiliary hash tables allocated by effectsmap_to_listmap()

Parameters
module_nameodule_name
in_contextn_context

Definition at line 918 of file dbm_interface.c.

919 {
922  /* intraprocedural preconditions: proper declarations */
924  list e_inter;
925 
928 
929  /* This stack is useful to document warnings and to retrieve
930  points-to information. */
934  /* could be a gen_find_tabulated as well... */
936  (statement) db_get_memory_resource(DBR_CODE, module_name, true));
938  pips_internal_error("no statement for module %s", module_name);
939 
941  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
942 
944  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
945 
947 
948  /* cumulated_effects_map_print();*/
949 
950  e_inter = effects_to_list( (effects)
951  db_get_memory_resource(DBR_SUMMARY_EFFECTS, module_name, true));
952 
954 
955  /* compute the basis related to module m */
957 
958  /* In the main module, transformers can be computed in context of the
959  initial values */
961  && get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT"))
962  {
964  {
965  mod_pre = (transformer)
966  db_get_memory_resource(DBR_PROGRAM_PRECONDITION, "", false);
967  if(transformer_empty_p(mod_pre)) {
969  "Initial preconditions are not consistent.\n"
970  " The Fortran standard rules about variable initialization"
971  " with DATA statements are likely to be violated.\n"
972  "set property PARSER_ACCEPT_ANSI_EXTENSIONS to false\n"
973  "and CHECK_FORTRAN_SYNTAX_BEFORE_PIPS to true.\n");
974  }
975  }
976  else
978  }
979  else if(in_context) {
980  mod_pre =
982  }
983  else
984  mod_pre = transformer_identity();
985 
986  /* Add declaration information: arrays cannot be empty (Fortran
987  standard, Section 5.1.2) */
988  if(get_bool_property("SEMANTICS_TRUST_ARRAY_DECLARATIONS")) {
991  }
992 
993  /* Get the preconditions: they might prove useful within loops where
994  transformers cannot propagate enough information. */
995  if(in_context) {
997  db_get_memory_resource(DBR_PRECONDITIONS, module_name, true));
998  }
999 
1000  /* compute intraprocedural transformer */
1002  t_intra = statement_to_transformer(ms, mod_pre);
1003  free_transformer(mod_pre);
1004 
1005  DB_PUT_MEMORY_RESOURCE(DBR_TRANSFORMERS, module_name,
1006  (char*) get_transformer_map() );
1007 
1008  /* FI: side effect; compute and store the summary transformer, because
1009  every needed piece of data is available... */
1010 
1011  /* filter out local variables from the global intraprocedural effect */
1012  t_inter = transformer_intra_to_inter(t_intra, e_inter);
1013  t_inter = transformer_normalize(t_inter, 2);
1016  }
1017  if(!transformer_consistency_p(t_inter)) {
1018  (void) print_transformer(t_inter);
1019  pips_internal_error("Non-consistent summary transformer");
1020  }
1021  DB_PUT_MEMORY_RESOURCE(DBR_SUMMARY_TRANSFORMER,
1023  (char*) t_inter);
1024  pips_debug(8, "t_inter=%p\n", t_inter);
1025 
1028  /* Two auxiliary hash tables allocated by effectsmap_to_listmap() */
1033  if(in_context) reset_precondition_map();
1034 
1037 
1039  debug_off();
1040 
1041  return true;
1042 }
void free_transformer(transformer p)
Definition: ri.c:2616
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
bool transformer_consistency_p(transformer t)
FI: I do not know if this procedure should always return or fail when an inconsistency is found.
Definition: basic.c:612
#define database_undefined
Definition: database.h:42
static void transformer_add_declaration_information(transformer pre, entity m)
void set_warning_counters(void)
transformer load_summary_precondition(entity e)
summary_preconditions are expressed in any possible frame, in fact the frame of the last procedure th...
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void generic_effects_reset_all_methods(void)
void reset_cumulated_rw_effects(void)
void set_methods_for_simple_effects(void)
list effects_to_list(effects)
Definition: effects.c:209
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....
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
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 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 pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
#define MAKE_STATEMENT_MAPPING()
Definition: newgen-local.h:43
#define SEMANTICS_DEBUG_LEVEL
#define SEMANTICS_INTERPROCEDURAL
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool entity_main_module_p(entity e)
Definition: entity.c:700
void free_statement_global_stack(void)
Definition: static.c:358
void make_statement_global_stack(void)
Definition: static.c:318
#define transformer_undefined
Definition: ri.h:2847
struct _newgen_struct_transformer_ * transformer
Definition: ri.h:431
transformer data_to_precondition(entity m)
restricted to variables with effects.
transformer transformer_intra_to_inter(transformer tf, list le)
transformer statement_to_transformer(statement s, transformer spre)
stmt precondition
void sc_variable_name_pop(void)
Definition: sc_debug.c:239
void sc_variable_name_push(char *(*fun)(Variable))
Definition: sc_debug.c:217
transformer value_passing_summary_transformer(entity f, transformer tf)
With value passing, writes on formal parameters are not effective interprocedurally unless an array i...
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
void set_transformer_map(statement_mapping)
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
statement_mapping get_transformer_map(void)
void reset_transformer_map(void)
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
const char * readable_value_name(entity)
For debugging purposes, we might have to print system with temporary values.
Definition: value.c:1769
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

References c_module_p(), data_to_precondition(), database_undefined, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, effects_to_list(), entity_main_module_p(), free_statement_global_stack(), free_transformer(), free_value_mappings(), generic_effects_reset_all_methods(), get_bool_property(), get_current_module_entity(), get_current_module_statement(), get_transformer_map(), load_summary_precondition(), make_statement_global_stack(), MAKE_STATEMENT_MAPPING, module_local_name(), module_name(), module_name_to_entity(), module_to_value_mappings(), pips_debug, pips_internal_error, pips_user_warning, print_transformer, readable_value_name(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_precondition_map(), reset_proper_rw_effects(), reset_transformer_map(), sc_variable_name_pop(), sc_variable_name_push(), SEMANTICS_DEBUG_LEVEL, SEMANTICS_INTERPROCEDURAL, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_methods_for_simple_effects(), set_precondition_map(), set_proper_rw_effects(), set_transformer_map(), set_warning_counters(), statement_to_transformer(), transformer_add_declaration_information(), transformer_consistency_p(), transformer_dup(), transformer_empty_p(), transformer_identity(), transformer_intra_to_inter(), transformer_normalize(), transformer_undefined, and value_passing_summary_transformer().

Referenced by module_name_to_transformers(), and module_name_to_transformers_in_context().

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

◆ interprocedural_summary_precondition()

bool interprocedural_summary_precondition ( char *  module_name)

The DATA statement from all modules, called or not called, are used, as well as the preconditions at all call sites.

Parameters
module_nameodule_name

Definition at line 545 of file dbm_interface.c.

546 {
547  /* The DATA statement from all modules, called or not called, are used,
548  as well as the preconditions at all call sites. */
551 }
bool summary_precondition(char *module_name)
void set_bool_property(const char *, bool)

References module_name(), SEMANTICS_INTERPROCEDURAL, set_bool_property(), and summary_precondition().

+ Here is the call graph for this function:

◆ interprocedural_summary_precondition_with_points_to()

bool interprocedural_summary_precondition_with_points_to ( char *  module_name)

The DATA statement from all modules, called or not called, are used, as well as the preconditions at all call sites. Points_to information is required to perform a more accurate translation between callesr and callees.

Parameters
module_nameodule_name

Definition at line 571 of file dbm_interface.c.

572 {
573  /* The DATA statement from all modules, called or not called, are
574  * used, as well as the preconditions at all call sites. Points_to
575  * information is required to perform a more accurate translation
576  * between callesr and callees.
577  */
580  bool result_p = summary_precondition(module_name);
582  return result_p;
583 }
static void reset_use_points_to()
static void set_use_points_to()

References module_name(), reset_use_points_to(), SEMANTICS_INTERPROCEDURAL, set_bool_property(), set_use_points_to(), and summary_precondition().

+ Here is the call graph for this function:

◆ intraprocedural_summary_precondition()

bool intraprocedural_summary_precondition ( char *  module_name)

The current module is sufficient to derive it.

Parameters
module_nameodule_name

Definition at line 538 of file dbm_interface.c.

539 {
540  /* The current module is sufficient to derive it. */
543 }

References module_name(), SEMANTICS_INTERPROCEDURAL, set_bool_property(), and summary_precondition().

+ Here is the call graph for this function:

◆ load_body_effects()

list load_body_effects ( entity  e)

Definition at line 1508 of file dbm_interface.c.

1509 {
1510  string module_name = (string) module_local_name(e);
1511 
1512  pips_assert("load_summary_effects", entity_module_p(e));
1513 
1514  statement b = (statement) db_get_memory_resource(DBR_CODE, module_name, true);
1516  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true);
1517  effects be = (effects) (intptr_t)HASH_GET(p, p, statement_effects_hash_table(se), (void *) b);
1518  list bel = effects_effects(be);
1519 
1520  pips_assert("bel is defined", bel != list_undefined);
1521 
1522  return bel;
1523 }
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
#define statement_effects_hash_table(x)
Definition: effects.h:1054
struct _newgen_struct_effects_ * effects
Definition: effects.h:138
struct _newgen_struct_statement_effects_ * statement_effects
Definition: effects.h:210
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define HASH_GET(start, image, h, k)
Definition: newgen_map.h:30
char * string
STRING.
Definition: newgen_types.h:39
bool entity_module_p(entity e)
Definition: entity.c:683
#define intptr_t
Definition: stdint.in.h:294

References db_get_memory_resource(), effects_effects, entity_module_p(), HASH_GET, intptr_t, list_undefined, module_local_name(), module_name(), pips_assert, and statement_effects_hash_table.

Referenced by user_call_to_points_to_interprocedural().

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

◆ load_completed_statement_transformer()

transformer load_completed_statement_transformer ( statement  s)

three mappings used throughout semantics analysis:

  • transformer_map is computed in a first phase
  • precondition_map is computed in a second phase
  • cumulated_effects is used and assumed computed before (defined in effects.c)
  • proper_effects might be useless... only DO loop analysis could use it (idem) declaration of the previously described mappings with their access functions :

(DEFINE_CURRENT_MAPPING is a macro defined in ~pips/Newgen/mapping.h)

BA, August 26, 1993 Returns the entry to exit transformer associated to a statement, since all statements in PIPS internal representation have a unique exit.

The transformers associated to loops are the transformers linking the loop precondition to the loop body precondition. When dealing with sequences or test or... the transformer linking the loop precondition to its postcondition, i.e. the precondition hodling at the loop exit, is needed.

To complete the statement transformer, a precondition is required. Different preconditions can be used:

  • transformer_identity(): provides no information
  • load_statement_precondition(): provides as much information as possible
  • the transformer domain: provides information available when the transformers are computed, i.e. preconditions do not have to be available; this is unsafe as the loop entrance transition domain may be a subset of the precocndition, unless the loop is always entered.

Unlike load_statement_transformer(), this function allocates a new transformer. See comments associated to:

generic_complete_statement_transformer()

Definition at line 131 of file dbm_interface.c.

132 {
134 
135  // Unsafe if s is a loop, unless you check that the loop is always
136  //entered
137  //transformer pre = transformer_to_domain(t);
139 
141 
142  //pips_assert("te is defined", !transformer_undefined_p(te));
143 
144  free_transformer(pre);
145 
146  return te;
147 }
transformer complete_statement_transformer(transformer t, transformer pre, statement s)
Returns the effective transformer ct for a given statement s.
transformer load_statement_transformer(statement)

References complete_statement_transformer(), free_transformer(), load_statement_transformer(), and transformer_identity().

Referenced by set_methods_for_convex_effects(), and set_methods_for_convex_rw_pointer_effects().

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

◆ load_module_intraprocedural_effects()

list load_module_intraprocedural_effects ( entity  e)

memoization could be used to improve efficiency

Definition at line 1526 of file dbm_interface.c.

1527 {
1528  /* memoization could be used to improve efficiency */
1529  list t;
1530  statement s;
1531 
1532  pips_assert("is a module", entity_module_p(e));
1533  pips_assert("is the current module", e == get_current_module_entity());
1535  pips_assert("some statement", s!=statement_undefined);
1536 
1538 
1539  pips_assert("some list", t != list_undefined);
1540 
1541  return t;
1542 }
list load_cumulated_rw_effects_list(statement)
#define statement_undefined
Definition: ri.h:2419

References entity_module_p(), get_current_module_entity(), get_current_module_statement(), list_undefined, load_cumulated_rw_effects_list(), pips_assert, and statement_undefined.

Referenced by allocate_module_value_mappings(), data_to_precondition(), and module_to_value_mappings().

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

◆ load_summary_effects()

list load_summary_effects ( entity  e)

FI->FI, FI->BC: these two functions should be moved into effects-util or effects-simple.

memorization could be used to improve efficiency

Definition at line 1492 of file dbm_interface.c.

1493 {
1494  /* memorization could be used to improve efficiency */
1495  list t;
1496 
1497  pips_assert("load_summary_effects", entity_module_p(e));
1498 
1499  t = effects_to_list( (effects)
1500  db_get_memory_resource(DBR_SUMMARY_EFFECTS, module_local_name(e),
1501  true));
1502 
1503  pips_assert("t is defined", t != list_undefined);
1504 
1505  return t;
1506 }

References db_get_memory_resource(), effects_to_list(), entity_module_p(), list_undefined, module_local_name(), and pips_assert.

Referenced by add_module_call_site_precondition(), call_site_to_module_precondition_text(), compute_summary_reductions(), module_to_value_mappings(), pure_function_p(), update_precondition_with_call_site_preconditions(), and user_call_to_points_to_fast_interprocedural().

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

◆ load_summary_precondition()

transformer load_summary_precondition ( entity  e)

summary_preconditions are expressed in any possible frame, in fact the frame of the last procedure that used/produced it

memoization could be used to improve efficiency

Not done earlier, because the value mappings were not available. On the other hand, htis assumes that the value mappings have been initialized before a call to load_summary_precondition(0 is performed.

Definition at line 1431 of file dbm_interface.c.

1432 {
1433  /* memoization could be used to improve efficiency */
1434  transformer t;
1435 
1436  pips_assert("e is a module", entity_module_p(e));
1437 
1438  pips_debug(8, "begin\n for %s\n",
1439  module_local_name(e));
1440 
1441  t = (transformer)
1442  db_get_memory_resource(DBR_SUMMARY_PRECONDITION, module_local_name(e),
1443  true);
1444  /* Not done earlier, because the value mappings were not available. On
1445  the other hand, htis assumes that the value mappings have been
1446  initialized before a call to load_summary_precondition(0 is
1447  performed.*/
1449 
1450  pips_assert("the summary precondition t is defined", t != transformer_undefined);
1451 
1452  ifdebug(8) {
1453  pips_debug(8, " precondition for %s:\n",
1454  module_local_name(e));
1455  dump_transformer(t);
1456  pips_debug(8, " end\n");
1457  }
1458 
1459  return t;
1460 }
#define dump_transformer(t)
Definition: print.c:355
void translate_global_values(entity m, transformer tf)

References db_get_memory_resource(), dump_transformer, entity_module_p(), ifdebug, module_local_name(), pips_assert, pips_debug, transformer_undefined, and translate_global_values().

Referenced by generic_module_name_to_transformers(), and module_name_to_preconditions().

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

◆ load_summary_total_postcondition()

transformer load_summary_total_postcondition ( entity  e)

summary_preconditions are expressed in any possible frame, in fact the frame of the last procedure that used/produced it

Definition at line 1465 of file dbm_interface.c.

1466 {
1468 
1469  pips_assert("e is a module", entity_module_p(e));
1470 
1471  pips_debug(8, "begin\n for %s\n",
1472  module_local_name(e));
1473 
1474  t_post = (transformer)
1475  db_get_memory_resource(DBR_SUMMARY_TOTAL_POSTCONDITION, module_local_name(e),
1476  true);
1477 
1478  pips_assert("t is defined", t_post != transformer_undefined);
1479 
1480  ifdebug(8) {
1481  pips_debug(8, " total postcondition for %s:\n",
1482  module_local_name(e));
1483  dump_transformer(t_post);
1484  pips_debug(8, " end\n");
1485  }
1486 
1487  return t_post;
1488 }

References db_get_memory_resource(), dump_transformer, entity_module_p(), ifdebug, module_local_name(), pips_assert, pips_debug, and transformer_undefined.

Referenced by module_name_to_total_preconditions().

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

◆ load_summary_transformer()

transformer load_summary_transformer ( entity  e)

FI: I had to add a guard db_resource_p() on Nov. 14, 1995. I do not understand why the problem never occured before, although it should each time the intra-procedural option is selected.

This may partially be explained because summary transformers are implicitly computed with transformers instead of using an explicit call to summary_transformer (I guess I'm going to change that).

I think it would be better not to call load_summary_transformer() at all when no interprocedural options are selected. I should change that too.

memoization could be used to improve efficiency

db_get_memory_resource never returns database_undefined or resource_undefined

Let's be careful with people using an intraprocedural analysis of the transformers and requesting an interprocedural analysis of the preconditions...

Definition at line 1327 of file dbm_interface.c.

1328 {
1329  /* FI: I had to add a guard db_resource_p() on Nov. 14, 1995.
1330  * I do not understand why the problem never occured before,
1331  * although it should each time the intra-procedural option
1332  * is selected.
1333  *
1334  * This may partially be explained because summary transformers
1335  * are implicitly computed with transformers instead of using
1336  * an explicit call to summary_transformer (I guess I'm going
1337  * to change that).
1338  *
1339  * I think it would be better not to call load_summary_transformer()
1340  * at all when no interprocedural options are selected. I should
1341  * change that too.
1342  */
1343 
1344  /* memoization could be used to improve efficiency */
1346 
1347  pips_assert("e is a module", entity_module_p(e));
1348 
1349  if(db_resource_p(DBR_SUMMARY_TRANSFORMER, module_local_name(e))) {
1350  t = (transformer)
1351  db_get_memory_resource(DBR_SUMMARY_TRANSFORMER,
1352  entity_local_name(e),
1353  true);
1354 
1355  /* db_get_memory_resource never returns database_undefined or
1356  resource_undefined */
1357  pips_assert("load_summary_transformer", t != transformer_undefined);
1358  }
1359  else {
1361  }
1362 
1363  /* Let's be careful with people using an intraprocedural analysis
1364  of the transformers and requesting an interprocedural analysis
1365  of the preconditions... */
1366  if(transformer_undefined_p(t)) {
1367  if(db_resource_p(DBR_SUMMARY_EFFECTS, module_local_name(e))) {
1369  db_get_memory_resource(DBR_SUMMARY_EFFECTS,
1370  entity_local_name(e),
1371  true));
1372  t = effects_to_transformer(el);
1373  }
1374  }
1375 
1376  return t;
1377 }
bool db_resource_p(const char *rname, const char *oname)
true if exists and in loaded or stored state.
Definition: database.c:524
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
#define transformer_undefined_p(x)
Definition: ri.h:2848
transformer effects_to_transformer(list e)
list of effects

References db_get_memory_resource(), db_resource_p(), effects_effects, effects_to_transformer(), entity_local_name(), entity_module_p(), module_local_name(), pips_assert, transformer_undefined, and transformer_undefined_p.

Referenced by c_user_call_to_transformer(), and fortran_user_call_to_transformer().

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

◆ main_summary_precondition()

static transformer main_summary_precondition ( entity  callee)
static

Special case: main module.

Intraprocedural case: use the local DATA statement to define the initial store.

Interprocedural case: use the program precondition

Do we need to initialize the mappings before calling this subroutine?

Why not use a DB_GET of DBR_INITIAL_PRECONDITION?

t = data_to_precondition(callee);

Definition at line 593 of file dbm_interface.c.

594 {
596 
599  db_get_memory_resource(DBR_PROGRAM_PRECONDITION, "", false));
600  if(transformer_empty_p(t)) {
602  "Initial preconditions are not consistent.\n"
603  " The Fortran standard rules about variable initialization"
604  " with DATA statements are likely to be violated.\n"
605  "set property PARSER_ACCEPT_ANSI_EXTENSIONS to false\n"
606  "and CHECK_FORTRAN_SYNTAX_BEFORE_PIPS to true.\n");
607  }
608  }
609  else {
610  /* Do we need to initialize the mappings before calling this subroutine? */
611  /* Why not use a DB_GET of DBR_INITIAL_PRECONDITION? */
612  /* t = data_to_precondition(callee); */
613  t = copy_transformer
614  ((transformer) db_get_memory_resource(DBR_INITIAL_PRECONDITION,
616  false));
617  }
618 
619  return t;
620 }
transformer copy_transformer(transformer p)
TRANSFORMER.
Definition: ri.c:2613
static entity callee
Definition: alias_pairs.c:62

References callee, copy_transformer(), db_get_memory_resource(), get_bool_property(), module_local_name(), pips_user_warning, SEMANTICS_INTERPROCEDURAL, transformer_empty_p(), and transformer_undefined.

Referenced by summary_precondition().

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

◆ module_name_to_preconditions()

bool module_name_to_preconditions ( const char *  module_name)

resource module_name_to_preconditions(char * module_name): compute a transformer for each statement of a module with a given name; compute also the global transformer for the module

set_debug_level(get_int_property(SEMANTICS_DEBUG_LEVEL));

To provide information for warnings

could be a gen_find_tabulated as well...

Used to add reference information when it is trusted... which should always be, at least for automatic parallelization.

cumulated effects are used to compute the value mappings

p_inter is not used!!! FI, 9 February 1994

debug_on(SEMANTICS_DEBUG_LEVEL);

compute the mappings related to module m, that is likely to be unavailable during interprocedural analysis; a module reference should be kept with the mappings to avoid useless recomputation, allocation and frees, including those due to the prettyprinter

set the list of global values. This is a bit too restrictive in C as the formal arguments, even modified in the procedure body, will not appear in the transformer_arguments. Should we add missing formal arguments to this list? See for instance "character01.c".

debug_on(SEMANTICS_DEBUG_LEVEL);

Add declaration information: arrays cannot be empty (Fortran standard, Section 5.1.2). But according to summary_precondition(), this is now supposed to be performed by the transformer phase?

If the module is never called, its precondition is identity and by default no values are listed in its basis. Function add_type_information() has no effect.

if(transformer_identity_p(pre)) {

list el = effects_to_list(

(effects) db_get_memory_resource(DBR_SUMMARY_EFFECTS, module_name, true));

free_transformer(pre);

// FI: memory leak

pre = transformer_range(effects_to_transformer(el));

}

debug_on(SEMANTICS_DEBUG_LEVEL);

propagate the module precondition

post could be stored in the ri for later interprocedural uses but the ri cannot be modified so early before the DRET demo; also our current interprocedural algorithm does not propagate postconditions upwards in the call tree

Parameters
module_nameodule_name

Definition at line 1073 of file dbm_interface.c.

1074 {
1075  transformer t_inter;
1076  transformer pre;
1077  transformer post;
1078 
1079  /* set_debug_level(get_int_property(SEMANTICS_DEBUG_LEVEL)); */
1081  /* To provide information for warnings */
1084 
1086  /* could be a gen_find_tabulated as well... */
1088  (statement) db_get_memory_resource(DBR_CODE, module_name, true));
1090  pips_internal_error("no statement for module %s", module_name);
1091 
1092  /* Used to add reference information when it is trusted... which
1093  should always be, at least for automatic parallelization. */
1095  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
1096 
1097  /* cumulated effects are used to compute the value mappings */
1099  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
1100 
1102 
1104  db_get_memory_resource(DBR_TRANSFORMERS, module_name, true));
1105 
1106 
1107  /* p_inter is not used!!! FI, 9 February 1994 */
1108  /*
1109  if(get_bool_property(SEMANTICS_INTERPROCEDURAL)) {
1110  p_inter = (transformer)
1111  db_get_memory_resource(DBR_SUMMARY_PRECONDITION,
1112  module_name, true);
1113  }
1114  */
1115 
1116  t_inter = (transformer)
1117  db_get_memory_resource(DBR_SUMMARY_TRANSFORMER, module_name, true);
1118 
1119  /* debug_on(SEMANTICS_DEBUG_LEVEL); */
1120 
1122 
1123  /* compute the mappings related to module m, that is likely to be
1124  unavailable during interprocedural analysis; a module reference
1125  should be kept with the mappings to avoid useless recomputation,
1126  allocation and frees, including those due to the prettyprinter */
1127 
1129 
1130  /* set the list of global values. This is a bit too restrictive in
1131  C as the formal arguments, even modified in the procedure body,
1132  will not appear in the transformer_arguments. Should we add
1133  missing formal arguments to this list? See for instance
1134  "character01.c". */
1136 
1137  /* debug_on(SEMANTICS_DEBUG_LEVEL); */
1138 
1140 
1141  /* Add declaration information: arrays cannot be empty (Fortran
1142  standard, Section 5.1.2). But according to summary_precondition(),
1143  this is now supposed to be performed by the transformer phase? */
1144  if(get_bool_property("SEMANTICS_TRUST_ARRAY_DECLARATIONS")) {
1146  }
1147  if(get_bool_property("SEMANTICS_USE_TYPE_INFORMATION")
1148  || get_bool_property("SEMANTICS_USE_TYPE_INFORMATION_IN_PRECONDITIONS")) {
1149 
1150  /* If the module is never called, its precondition is identity
1151  and by default no values are listed in its basis. Function
1152  add_type_information() has no effect. */
1153 
1154  /* if(transformer_identity_p(pre)) { */
1155  /* list el = effects_to_list( */
1156  /* (effects) db_get_memory_resource(DBR_SUMMARY_EFFECTS, module_name, true)); */
1157  /* free_transformer(pre); */
1158  /* // FI: memory leak */
1159  /* pre = transformer_range(effects_to_transformer(el)); */
1160  /* } */
1161 
1163  }
1164 
1165  /* debug_on(SEMANTICS_DEBUG_LEVEL); */
1166 
1167  /* propagate the module precondition */
1170  close_reachable();
1171 
1172  /* post could be stored in the ri for later interprocedural uses
1173  but the ri cannot be modified so early before the DRET demo;
1174  also our current interprocedural algorithm does not propagate
1175  postconditions upwards in the call tree */
1176 
1177  DB_PUT_MEMORY_RESOURCE(DBR_PRECONDITIONS,
1178  module_name,
1179  (char*) get_precondition_map() );
1180 
1181  pips_debug(8, "postcondition computed for %s\n",
1183  ifdebug(8) (void) print_transformer(post);
1184  debug(1, "module_name_to_preconditions", "end\n");
1185 
1193 
1195 
1198  debug_off();
1199 
1200  return true;
1201 }
void close_reachable(void)
Remove reachability information about previously checked statements.
Definition: unreachable.c:252
void init_reachable(statement)
unreachable.c
Definition: unreachable.c:223
static void precondition_add_declaration_information(transformer pre, entity m)
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define transformer_arguments(x)
Definition: ri.h:2871
void set_module_global_arguments(list args)
transformer statement_to_postcondition(transformer, statement)
end of the non recursive section
void transformer_add_type_information(transformer)
type.c
Definition: type.c:162
statement_mapping get_precondition_map(void)

References close_reachable(), copy_transformer(), database_undefined, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug(), debug_off, debug_on, entity_local_name(), free_statement_global_stack(), free_value_mappings(), generic_effects_reset_all_methods(), get_bool_property(), get_current_module_entity(), get_current_module_statement(), get_precondition_map(), ifdebug, init_reachable(), load_summary_precondition(), make_statement_global_stack(), MAKE_STATEMENT_MAPPING, module_name(), module_name_to_entity(), module_to_value_mappings(), pips_debug, pips_internal_error, precondition_add_declaration_information(), print_transformer, readable_value_name(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_precondition_map(), reset_proper_rw_effects(), reset_transformer_map(), sc_variable_name_pop(), sc_variable_name_push(), SEMANTICS_DEBUG_LEVEL, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_methods_for_simple_effects(), set_module_global_arguments(), set_precondition_map(), set_proper_rw_effects(), set_transformer_map(), statement_to_postcondition(), transformer_add_type_information(), and transformer_arguments.

Referenced by preconditions_inter_fast(), preconditions_inter_full(), preconditions_inter_full_with_points_to(), preconditions_intra(), and preconditions_intra_fast().

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

◆ module_name_to_total_preconditions()

bool module_name_to_total_preconditions ( const char *  module_name)

set the list of global values

The program postcondition should be used DBR_PROGRAM_POSTCONDITION

that might be because we are at the call tree root or because no information is available; maybe, every module precondition should be initialized to a neutral value?

intra-procedural case, not a main module

propagate the module total postcondition

filter out local variables from the global intraprocedural effect

Parameters
module_nameodule_name

Definition at line 1203 of file dbm_interface.c.

1204 {
1207  transformer t_pre_inter = transformer_undefined;
1209  list e_inter = list_undefined;
1210 
1213 
1216  (statement) db_get_memory_resource(DBR_CODE, module_name, true));
1218  pips_internal_error("no statement for module %s", module_name);
1219 
1221  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
1222 
1224  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
1225 
1226  e_inter = effects_to_list((effects)
1227  db_get_memory_resource(DBR_SUMMARY_EFFECTS, module_name, true));
1228 
1230  db_get_memory_resource(DBR_TRANSFORMERS, module_name, true));
1231 
1233  db_get_memory_resource(DBR_PRECONDITIONS, module_name, true));
1234 
1235 
1236  t_inter = (transformer)
1237  db_get_memory_resource(DBR_SUMMARY_TRANSFORMER, module_name, true);
1238 
1240 
1242 
1243  /* set the list of global values */
1245 
1247  /* The program postcondition should be used DBR_PROGRAM_POSTCONDITION */
1248  t_post = transformer_identity();
1249  }
1250 
1251  ifdebug(3) {
1252  pips_debug(1, "considering final total postcondition for %s\n", module_name);
1253  print_transformer(t_post);
1254  }
1255 
1257  transformer ip =
1259  if( ip == transformer_undefined) {
1260  /* that might be because we are at the call tree root
1261  or because no information is available;
1262  maybe, every module precondition should be initialized
1263  to a neutral value? */
1264  pips_user_warning("no interprocedural module total postcondition for %s\n",
1266  ;
1267  }
1268  else {
1270  ifdebug(8) {
1271  pips_debug(8, "\t summary_total_postcondition %p after translation:\n",
1272  ip);
1273  print_transformer(ip);
1274  pips_assert("The summary total postcondition is consistent",
1276  }
1277  t_post = transformer_combine(transformer_dup(ip), t_post);
1278  }
1279  }
1280  else if(transformer_undefined_p(t_post)) {
1281  /* intra-procedural case, not a main module */
1282  t_post = transformer_identity();
1283  }
1284 
1285  /* propagate the module total postcondition */
1288  close_reachable();
1289 
1290  DB_PUT_MEMORY_RESOURCE(DBR_TOTAL_PRECONDITIONS,
1291  module_name,
1292  (char*) get_total_precondition_map() );
1293 
1294  /* filter out local variables from the global intraprocedural effect */
1295  t_pre_inter = transformer_intra_to_inter(t_pre, e_inter);
1296  t_pre_inter = transformer_normalize(t_pre_inter, 2);
1297  if(!transformer_consistency_p(t_pre_inter)) {
1298  (void) print_transformer(t_pre_inter);
1299  pips_internal_error("Non-consistent summary transformer");
1300  }
1301  DB_PUT_MEMORY_RESOURCE(DBR_SUMMARY_TOTAL_PRECONDITION,
1303  (char*) t_pre_inter);
1304 
1305  pips_debug(8, "total precondition computed for %s\n",
1307  ifdebug(8) (void) print_transformer(t_pre);
1308  pips_debug(1, "end\n");
1309 
1317 
1319 
1321  debug_off();
1322 
1323  return true;
1324 }
transformer load_summary_total_postcondition(entity e)
summary_preconditions are expressed in any possible frame, in fact the frame of the last procedure th...
transformer statement_to_total_precondition(transformer, statement)
semantical analysis
void set_total_precondition_map(statement_mapping)
void reset_total_precondition_map(void)
statement_mapping get_total_precondition_map(void)
transformer transformer_combine(volatile transformer t1, transformer t2)
transformer transformer_combine(transformer t1, transformer t2): compute the composition of transform...
Definition: transformer.c:238

References close_reachable(), database_undefined, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, effects_to_list(), entity_local_name(), entity_main_module_p(), free_value_mappings(), get_bool_property(), get_current_module_entity(), get_current_module_statement(), get_total_precondition_map(), ifdebug, init_reachable(), list_undefined, load_summary_total_postcondition(), MAKE_STATEMENT_MAPPING, module_local_name(), module_name(), module_name_to_entity(), module_to_value_mappings(), pips_assert, pips_debug, pips_internal_error, pips_user_warning, print_transformer, readable_value_name(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_precondition_map(), reset_proper_rw_effects(), reset_total_precondition_map(), reset_transformer_map(), sc_variable_name_pop(), sc_variable_name_push(), SEMANTICS_DEBUG_LEVEL, SEMANTICS_INTERPROCEDURAL, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_module_global_arguments(), set_precondition_map(), set_proper_rw_effects(), set_total_precondition_map(), set_transformer_map(), statement_to_total_precondition(), transformer_arguments, transformer_combine(), transformer_consistency_p(), transformer_dup(), transformer_identity(), transformer_intra_to_inter(), transformer_normalize(), transformer_undefined, transformer_undefined_p, and translate_global_values().

Referenced by total_preconditions_inter(), and total_preconditions_intra().

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

◆ module_name_to_transformers()

bool module_name_to_transformers ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 1062 of file dbm_interface.c.

1063 {
1064  bool rc = false;
1066  return rc;
1067 }
bool generic_module_name_to_transformers(const char *module_name, bool in_context)
bool generic_module_name_to_transformers(char * module_name, bool in_context): compute a transformer ...

References generic_module_name_to_transformers(), and module_name().

Referenced by transformers_inter_fast(), transformers_inter_full(), transformers_inter_full_with_points_to(), transformers_intra_fast(), and transformers_intra_full().

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

◆ module_name_to_transformers_in_context()

bool module_name_to_transformers_in_context ( const char *  module_name)
Parameters
module_nameodule_name

Definition at line 1044 of file dbm_interface.c.

1045 {
1046  bool rc = false;
1047  bool save_prop = get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT");
1048 
1049  if(!save_prop) {
1050  pips_user_warning("Although property SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT"
1051  " is not set, it is used because it is necessary for this "
1052  "recomputation to be useful\n");
1053  set_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT", true);
1054  }
1055 
1057 
1058  set_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT", save_prop);
1059  return rc;
1060 }

References generic_module_name_to_transformers(), get_bool_property(), module_name(), pips_user_warning, and set_bool_property().

Referenced by refine_transformers(), and refine_transformers_with_points_to().

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

◆ old_summary_precondition()

bool old_summary_precondition ( char *  module_name)

do not nothing because it has been computed by side effects; or provide an empty precondition for root modules; maybe a touch to look nicer?

touch it

Parameters
module_nameodule_name

Definition at line 500 of file dbm_interface.c.

501 {
502  /* do not nothing because it has been computed by side effects;
503  * or provide an empty precondition for root modules;
504  * maybe a touch to look nicer?
505  */
506 
507  transformer t;
508 
510 
511  debug(8, "summary_precondition", "begin\n");
512 
513  if(db_resource_p(DBR_SUMMARY_PRECONDITION, module_name)) {
514  /* touch it */
515  t = (transformer) db_get_memory_resource(DBR_SUMMARY_PRECONDITION,
516  module_name,
517  true);
518  }
519  else {
520  t = transformer_identity();
521  }
522 
523  DB_PUT_MEMORY_RESOURCE(DBR_SUMMARY_PRECONDITION,
524  module_name, (char * )t);
525 
526  ifdebug(8) {
527  pips_debug(8, "initial summary precondition %p for %s:\n",
528  t, module_name);
529  dump_transformer(t);
530  pips_debug(8, "end\n");
531  }
532 
533  debug_off();
534 
535  return true;
536 }

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, db_resource_p(), debug(), debug_off, debug_on, dump_transformer, ifdebug, module_name(), pips_debug, SEMANTICS_DEBUG_LEVEL, and transformer_identity().

+ Here is the call graph for this function:

◆ ordinary_summary_precondition()

static transformer ordinary_summary_precondition ( const char *  module_name,
entity  callee 
)
static

Standard cases: called modules.

If a main is present, modules which are never called receive an unfeasible summary_precondition.

If no main is present in the current workspace, modules which are never called receive an identity summary precondition, i.e. no information.

If an interprocedural analysis is required, the preconditions of all call sites are translated and then unioned.

Look for all call sites in the callers

no callers => empty precondition if a main is being analyzed FC. 08/01/1999.

No main in the application? Do declare every module executed.

Try to eliminate (some) redundancy at a reasonnable cost.

What is a reasonnable cost?

Level 7 core dumps with Semantics-New/summary_precondition04.c unless formal parameter "_c" is renamed... external_value_name is called when the value mapping hash-tables are not available. Validations of Semantics and Semantics-new are not improved by level 7 wrt level 2.

t = transformer_normalize(t, 7);

Corinne's best one... for YPENT2 in ARC2D, but be ready to pay the price! And in case an overflow occurs, you may loose a lot of accuracy without any control.

t = transformer_normalize(t, 8);

No consistency check possible here because value_mappings are not available

pips_assert("The summary precondition is consistent", transformer_consistency_p(t));

Intraprocedural case

Definition at line 636 of file dbm_interface.c.

638 {
640 
642  /* Look for all call sites in the callers
643  */
644  callees callers = (callees) db_get_memory_resource(DBR_CALLERS,
645  module_name,
646  true);
647  list lc = callees_callees(callers);
648 
649  ifdebug(1) {
650  pips_debug(1, "begin for %s with %zd callers\n",
651  module_name,
652  gen_length(lc));
653  FOREACH(STRING, caller_name, lc) {
654  (void) fprintf(stderr, "%s, ", caller_name);
655  }
656  (void) fprintf(stderr, "\n");
657  }
658 
660  // FI: it might be safer to make and free this stack in the loop
661  // body, once for each caller. The initialization is located in
662  // summary_preconditions()
663 
664  // make_statement_global_stack();
665 
669  }
670 
671  // free_statement_global_stack();
672 
673  if (ENDP(callees_callees(callers)) &&
674  some_main_entity_p()) {
675  /* no callers => empty precondition if a main is being analyzed
676  FC. 08/01/1999.
677  */
678  pips_user_warning("empty precondition to %s "
679  "because not in call tree from main.\n", module_name);
680  t = transformer_empty();
681  }
682  else if (transformer_undefined_p(t)) {
683  /* No main in the application? Do declare every module executed. */
684  t = transformer_identity();
685  }
686  else {
687  /* Try to eliminate (some) redundancy at a reasonnable cost. */
688  /* What is a reasonnable cost? */
689 
690  t = transformer_normalize(t, 2);
691  /* Level 7 core dumps with
692  * Semantics-New/summary_precondition04.c unless formal
693  * parameter "_c" is renamed... external_value_name is called
694  * when the value mapping hash-tables are not
695  * available. Validations of Semantics and Semantics-new are not
696  * improved by level 7 wrt level 2.
697  */
698  /* t = transformer_normalize(t, 7); */
699 
700  /* Corinne's best one... for YPENT2 in ARC2D, but be ready to pay
701  the price! And in case an overflow occurs, you may loose a lot of
702  accuracy without any control. */
703  /* t = transformer_normalize(t, 8); */
704 
705  /* No consistency check possible here because value_mappings are
706  not available */
707  /* pips_assert("The summary precondition is consistent",
708  transformer_consistency_p(t));*/
709  }
710  }
711  else {
712  /* Intraprocedural case */
713  t = transformer_identity();
714  }
715 
716  return t;
717 }
static const char * caller_name
Definition: alias_check.c:122
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
#define STRING(x)
Definition: genC.h:87
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
size_t gen_length(const list l)
Definition: list.c:150
bool some_main_entity_p(void)
util.c
Definition: util.c:37
struct _newgen_struct_callees_ * callees
Definition: ri.h:55
#define callees_callees(x)
Definition: ri.h:675
transformer update_precondition_with_call_site_preconditions(transformer t, entity caller, entity callee)
Update precondition t for callee with preconditions of call sites to callee in caller.
void reset_call_site_number()

References callee, callees_callees, caller_name, db_get_memory_resource(), ENDP, FOREACH, fprintf(), gen_length(), get_bool_property(), ifdebug, module_name(), module_name_to_entity(), pips_debug, pips_user_warning, reset_call_site_number(), SEMANTICS_INTERPROCEDURAL, some_main_entity_p(), STRING, transformer_empty(), transformer_identity(), transformer_normalize(), transformer_undefined, transformer_undefined_p, and update_precondition_with_call_site_preconditions().

Referenced by summary_precondition().

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

◆ precondition_add_declaration_information()

static void precondition_add_declaration_information ( transformer  pre,
entity  m 
)
static

Definition at line 247 of file dbm_interface.c.

248 {
249  add_declaration_information(pre, m, true);
250 }
static void add_declaration_information(transformer pre, entity m, bool precondition_p)

References add_declaration_information().

Referenced by module_name_to_preconditions().

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

◆ preconditions_inter_fast()

bool preconditions_inter_fast ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 435 of file dbm_interface.c.

436 {
443  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
445 }
static void select_fix_point_operator()
bool module_name_to_preconditions(const char *module_name)
resource module_name_to_preconditions(char * module_name): compute a transformer for each statement o...
#define SEMANTICS_FIX_POINT
#define SEMANTICS_FLOW_SENSITIVE
#define SEMANTICS_STDOUT
#define SEMANTICS_INEQUALITY_INVARIANT

References module_name(), module_name_to_preconditions(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INEQUALITY_INVARIANT, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ preconditions_inter_full()

bool preconditions_inter_full ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 447 of file dbm_interface.c.

448 {
455  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
457 }

References module_name(), module_name_to_preconditions(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INEQUALITY_INVARIANT, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ preconditions_inter_full_with_points_to()

bool preconditions_inter_full_with_points_to ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 459 of file dbm_interface.c.

460 {
467  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
469  db_get_memory_resource(DBR_POINTS_TO, module_name, true) );
470  bool result_p = module_name_to_preconditions(module_name);
472  return result_p;
473 }
void set_pt_to_list(statement_points_to)
void reset_pt_to_list(void)

References db_get_memory_resource(), module_name(), module_name_to_preconditions(), reset_pt_to_list(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INEQUALITY_INVARIANT, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, set_bool_property(), and set_pt_to_list().

+ Here is the call graph for this function:

◆ preconditions_intra()

bool preconditions_intra ( char *  module_name)

nothing to do: transformers are preconditions for this intraprocedural option

Maybe we should have an intra fast and an intra full as with other semantics entries

set_bool_property(SEMANTICS_FIX_POINT, false);

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 399 of file dbm_interface.c.

400 {
401  /* nothing to do: transformers are preconditions for this
402  intraprocedural option */
403 
406  /* Maybe we should have an intra fast and an intra full as with other
407  semantics entries */
408  /* set_bool_property(SEMANTICS_FIX_POINT, false); */
413  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
415 }

References module_name(), module_name_to_preconditions(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INEQUALITY_INVARIANT, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ preconditions_intra_fast()

bool preconditions_intra_fast ( char *  module_name)

nothing to do: transformers are preconditions for this intraprocedural option

Maybe we should have an intra fast and an intra full as with other semantics entries

set_bool_property(SEMANTICS_FIX_POINT, false);

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 417 of file dbm_interface.c.

418 {
419  /* nothing to do: transformers are preconditions for this
420  intraprocedural option */
421 
424  /* Maybe we should have an intra fast and an intra full as with other
425  semantics entries */
426  /* set_bool_property(SEMANTICS_FIX_POINT, false); */
431  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
433 }

References module_name(), module_name_to_preconditions(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INEQUALITY_INVARIANT, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ refine_transformers()

bool refine_transformers ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 354 of file dbm_interface.c.

355 {
356  bool res;
362  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
363  refine_transformers_p = true;
365  refine_transformers_p = false;
366  return res;
367 }
bool refine_transformers_p
Transformer recomputation cannot be of real use unless an interprocedural analysis is performed.
bool module_name_to_transformers_in_context(const char *module_name)

References module_name(), module_name_to_transformers_in_context(), refine_transformers_p, select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ refine_transformers_with_points_to()

bool refine_transformers_with_points_to ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 369 of file dbm_interface.c.

370 {
371  bool res;
377  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
379  db_get_memory_resource(DBR_POINTS_TO, module_name, true) );
380  refine_transformers_p = true;
382  refine_transformers_p = false;
384  return res;
385 }

References db_get_memory_resource(), module_name(), module_name_to_transformers_in_context(), refine_transformers_p, reset_pt_to_list(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, set_bool_property(), and set_pt_to_list().

+ Here is the call graph for this function:

◆ reset_use_points_to()

static void reset_use_points_to ( )
static

Definition at line 560 of file dbm_interface.c.

561 {
563 }
static bool use_points_to_information_p

References use_points_to_information_p.

Referenced by interprocedural_summary_precondition_with_points_to().

+ Here is the caller graph for this function:

◆ select_fix_point_operator()

static void select_fix_point_operator ( )
static

This fix-point is not debugged nor used

Definition at line 150 of file dbm_interface.c.

151 {
153  const char* fp_name = get_string_property("SEMANTICS_FIX_POINT_OPERATOR");
154  if(strcmp(fp_name, "transfer")==0) {
156  }
157  else if(strcmp(fp_name, "pattern")==0) {
159  }
160  else if(strcmp(fp_name, "derivative")==0) {
162  }
163  else {
164  user_error("select_fix_point_operator", "Unknown value %s for property %s\n",
165  fp_name, "SEMANTICS_FIX_POINT_OPERATOR");
166  }
167  }
168  else {
170  }
171  /* This fix-point is not debugged nor used */
172  /*
173  if(pips_flag_p(SEMANTICS_INEQUALITY_INVARIANT)) {
174  tf = transformer_halbwachs_fix_point(tfb);
175  }
176  */
177 }
transformer transformer_equality_fix_point(transformer)
Let A be the affine loop transfert function.
Definition: fix_point.c:266
transformer(* transformer_fix_point_operator)(transformer)
Interface between the untyped database manager and clean code and between pipsmake and clean code.
Definition: fix_point.c:114
transformer transformer_pattern_fix_point(transformer)
This fixpoint function was developped to present a talk at FORMA.
Definition: fix_point.c:709
transformer transformer_derivative_fix_point(transformer)
Computation of a transitive closure using constraints on the discrete derivative.
Definition: fix_point.c:1067
char * get_string_property(const char *)
transformer transformer_basic_fix_point(transformer tf)
Computation of a fix point: drop all constraints, remember which variables are changed.
Definition: fix_point.c:1280
#define user_error(fn,...)
Definition: misc-local.h:265

References get_bool_property(), get_string_property(), SEMANTICS_FIX_POINT, transformer_basic_fix_point(), transformer_derivative_fix_point(), transformer_equality_fix_point(), transformer_fix_point_operator, transformer_pattern_fix_point(), and user_error.

Referenced by preconditions_inter_fast(), preconditions_inter_full(), preconditions_inter_full_with_points_to(), preconditions_intra(), preconditions_intra_fast(), refine_transformers(), refine_transformers_with_points_to(), total_preconditions_inter(), total_preconditions_intra(), transformers_inter_fast(), transformers_inter_full(), transformers_inter_full_with_points_to(), transformers_intra_fast(), and transformers_intra_full().

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

◆ set_use_points_to()

static void set_use_points_to ( )
static

Definition at line 555 of file dbm_interface.c.

556 {
558 }

References use_points_to_information_p.

Referenced by interprocedural_summary_precondition_with_points_to().

+ Here is the caller graph for this function:

◆ set_warning_counters()

void set_warning_counters ( void  )

Definition at line 903 of file dbm_interface.c.

904 {
905  wc = 0;
906 }
static int wc
FI: Provisional management of warnings.

References wc.

Referenced by generic_module_name_to_transformers().

+ Here is the caller graph for this function:

◆ summary_precondition()

bool summary_precondition ( char *  module_name)

transformer t = transformer_identity();

Add declaration information: arrays cannot be empty (Fortran standard, Section 5.1.2)

It does not seem to be a good idea for the semantics of SUMMARY_PRECONDITION. It seems better to have this information in the summary transformer as an input validity condition.

Try to put the summary precondition in a (partially) canonical form.

Parameters
module_nameodule_name

Definition at line 719 of file dbm_interface.c.

720 {
721  /* transformer t = transformer_identity(); */
724 
726 
730 
733  }
734  else {
736  }
737 
738  /* Add declaration information: arrays cannot be empty (Fortran
739  * standard, Section 5.1.2)
740  *
741  * It does not seem to be a good idea for the semantics of
742  * SUMMARY_PRECONDITION. It seems better to have this information in the
743  * summary transformer as an input validity condition.
744  *
745  */
746  if(false && get_bool_property("SEMANTICS_TRUST_ARRAY_DECLARATIONS")) {
748  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
750  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
757  }
758 
759  pips_assert("t is defined", !transformer_undefined_p(t));
760 
761  /* Try to put the summary precondition in a (partially) canonical form. */
762  t = transformer_normalize(t, 4);
763  t = transformer_normalize(t, 4);
764 
765  ifdebug(3) {
766  pips_debug(1, "considering summary precondition for %s\n", module_name);
767  dump_transformer(t);
768  }
769 
770  DB_PUT_MEMORY_RESOURCE(DBR_SUMMARY_PRECONDITION,
771  module_name, (char * )t);
772 
773  ifdebug(1) {
774  pips_debug(1,
775  "initial summary precondition %p for %s (%d call sites):\n",
777  dump_transformer(t);
778  pips_debug(1, "end for module %s\n", module_name);
779  }
780 
784  debug_off();
785 
786  return true;
787 }
static transformer main_summary_precondition(entity callee)
Special case: main module.
static transformer ordinary_summary_precondition(const char *module_name, entity callee)
Standard cases: called modules.
int get_call_site_number()

References callee, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug_off, debug_on, dump_transformer, entity_main_module_p(), free_statement_global_stack(), free_value_mappings(), get_bool_property(), get_call_site_number(), get_current_module_entity(), ifdebug, main_summary_precondition(), make_statement_global_stack(), module_name(), module_name_to_entity(), module_to_value_mappings(), ordinary_summary_precondition(), pips_assert, pips_debug, reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_proper_rw_effects(), SEMANTICS_DEBUG_LEVEL, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_proper_rw_effects(), transformer_add_declaration_information(), transformer_normalize(), transformer_undefined, and transformer_undefined_p.

Referenced by interprocedural_summary_precondition(), interprocedural_summary_precondition_with_points_to(), and intraprocedural_summary_precondition().

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

◆ summary_total_postcondition()

bool summary_total_postcondition ( char *  module_name)

Look for all call sites in the callers

transformer t = transformer_identity();

no callers => empty precondition (but the main). FC. 08/01/1999.

try to eliminate (some) redundancy at a reasonnable cost

t = transformer_normalize(t, 2);

what cost?

Add declaration information: arrays cannot be empty (Fortran standard, Section 5.1.2)

It does not seem to be a good idea for the semantics of SUMMARY_PRECONDITION. It seems better to have this information in the summary transformer as an input validity condition.

Parameters
module_nameodule_name

Definition at line 789 of file dbm_interface.c.

790 {
791  /* Look for all call sites in the callers
792  */
793  callees callers = (callees) db_get_memory_resource(DBR_CALLERS,
794  module_name,
795  true);
797  /* transformer t = transformer_identity(); */
799 
801 
802  pips_assert("Not implemented yet", false);
803 
805 
806  ifdebug(1) {
807  debug(1, "summary_precondition", "begin for %s with %d callers\n",
808  module_name,
809  gen_length(callees_callees(callers)));
811  (void) fprintf(stderr, "%s, ", caller_name);
812  }, callees_callees(callers));
813  (void) fprintf(stderr, "\n");
814  }
815 
817 
819  {
822  }, callees_callees(callers));
823 
824  if (!callees_callees(callers) &&
827  {
828  /* no callers => empty precondition (but the main).
829  FC. 08/01/1999.
830  */
831  pips_user_warning("empty precondition to %s "
832  "because not in call tree from main.\n", module_name);
833  t = transformer_empty();
834  } else if (transformer_undefined_p(t)) {
835  t = transformer_identity();
836  } else {
837  /* try to eliminate (some) redundancy at a reasonnable cost */
838  /* t = transformer_normalize(t, 2); */
839 
840  /* what cost? */
841  t = transformer_normalize(t, 7);
842  }
843 
844  /* Add declaration information: arrays cannot be empty (Fortran
845  * standard, Section 5.1.2)
846  *
847  * It does not seem to be a good idea for the semantics of
848  * SUMMARY_PRECONDITION. It seems better to have this information in the
849  * summary transformer as an input validity condition.
850  *
851  */
852  if(false && get_bool_property("SEMANTICS_TRUST_ARRAY_DECLARATIONS")) {
854  (statement) db_get_memory_resource(DBR_CODE, module_name, true));
856  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
858  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
866  }
867 
868  DB_PUT_MEMORY_RESOURCE(DBR_SUMMARY_TOTAL_POSTCONDITION,
869  module_name, (char * )t);
870 
871  ifdebug(1) {
872  pips_debug(1,
873  "summary total postcondition %p for %s (%d call sites):\n",
875  dump_transformer(t);
876  pips_debug(1, "end for module %s\n", module_name);
877  }
878 
880  debug_off();
881 
882  return true;
883 }
#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

References callee, callees_callees, caller_name, db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug(), debug_off, debug_on, dump_transformer, entity_main_module_p(), fprintf(), free_value_mappings(), gen_length(), get_bool_property(), get_call_site_number(), get_current_module_entity(), ifdebug, MAP, module_name(), module_name_to_entity(), module_to_value_mappings(), pips_assert, pips_debug, pips_user_warning, reset_call_site_number(), reset_cumulated_rw_effects(), reset_current_module_entity(), reset_current_module_statement(), reset_proper_rw_effects(), SEMANTICS_DEBUG_LEVEL, set_cumulated_rw_effects(), set_current_module_entity(), set_current_module_statement(), set_proper_rw_effects(), some_main_entity_p(), STRING, transformer_add_declaration_information(), transformer_empty(), transformer_identity(), transformer_normalize(), transformer_undefined, transformer_undefined_p, and update_precondition_with_call_site_preconditions().

+ Here is the call graph for this function:

◆ summary_total_precondition()

bool summary_total_precondition ( char *  module_name)

there is a choice: do nothing and leave the effective computation in module_name_to_total_preconditions or move it here

Parameters
module_nameodule_name

Definition at line 885 of file dbm_interface.c.

886 {
887  /* there is a choice: do nothing and leave the effective computation
888  in module_name_to_total_preconditions or move it here */
889  pips_debug(1, "considering module %s\n", module_name);
890  return true;
891 }

References module_name(), and pips_debug.

+ Here is the call graph for this function:

◆ summary_transformer()

bool summary_transformer ( char *  module_name)

There is a choice: do nothing and leave the effective computation in module_name_to_transformers, or move it here

There is another choice: distinguish between inter- and intra-procedural analyses at the summary level or in module_name_to_transformers(). The choice does not have to be consistent with the similar choice made for summary_precondition.

Parameters
module_nameodule_name

Definition at line 387 of file dbm_interface.c.

388 {
389  /* There is a choice: do nothing and leave the effective computation
390  in module_name_to_transformers, or move it here */
391  /* There is another choice: distinguish between inter- and
392  intra-procedural analyses at the summary level or in
393  module_name_to_transformers(). The choice does not have to be
394  consistent with the similar choice made for summary_precondition. */
395  pips_debug(1, "considering module %s\n", module_name);
396  return true;
397 }

References module_name(), and pips_debug.

+ Here is the call graph for this function:

◆ test_warning_counters()

bool test_warning_counters ( void  )

Definition at line 908 of file dbm_interface.c.

909 {
910  return wc++==0;
911 }

References wc.

Referenced by points_to_unary_operation_to_transformer().

+ Here is the caller graph for this function:

◆ total_preconditions_inter()

bool total_preconditions_inter ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 487 of file dbm_interface.c.

488 {
495  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
497 }
bool module_name_to_total_preconditions(const char *module_name)

References module_name(), module_name_to_total_preconditions(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INEQUALITY_INVARIANT, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ total_preconditions_intra()

bool total_preconditions_intra ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 475 of file dbm_interface.c.

476 {
483  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
485 }

References module_name(), module_name_to_total_preconditions(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INEQUALITY_INVARIANT, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ transformer_add_declaration_information()

static void transformer_add_declaration_information ( transformer  pre,
entity  m 
)
static

Definition at line 242 of file dbm_interface.c.

243 {
244  add_declaration_information(pre, m, false);
245 }

References add_declaration_information().

Referenced by generic_module_name_to_transformers(), summary_precondition(), and summary_total_postcondition().

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

◆ transformer_derivative_fix_point()

transformer transformer_derivative_fix_point ( transformer  tf)

Computation of a transitive closure using constraints on the discrete derivative.

See http://www.cri.ensmp.fr/classement/doc/A-429.pdf

Implicit equations, n::new - n::old = 0, are not added. Instead, invariant constraints in tf are obtained by projection and added.

Intermediate values are used to encode the differences. For instance, i::int = i::new - i::old

I tried to use the standard procedure but arguments are not removed when the transformer tf is not feasible. Since we compute the * fix point and not the + fix point, the fix point is the identity.

sc is going to be modified and destroyed and eventually replaced in fix_tf

Do not handle variable which do not appear explicitly in constraints!

initial and final basis

basis vector

basis of difference vectors

Compute constraints with difference equations

Only generate difference equations if the old value is used

Project all variables but differences to get T'

Multiply the constant terms by the iteration number ik and add a positivity constraint for the iteration number ik and then eliminate the iteration number ik to get T*(dx).

Difference variables must substituted back to differences between old and new values.

Only generate difference equations if the old value is used

Project all difference variables

The full basis must be used again

Plug sc back into fix_tf

Add constraints about invariant variables. This could be avoided if implicit equalities were added before the derivative are processed: each invariant variable would generate an implicit null difference.

Such invariant constraints do not exist in general. We have them when array references are trusted.

This is wrong because we compute f* and not f+ and this is not true for the initial store.

What can be done instead is to refine fix_tf as :

dom(tf) U tf(fix_tf(dom(tf)))

But this fails because tf loops back to the beginning of the next iteration. Hence, the domain of tf implies two iterations instead of one. For instance, "i<n" becomes "i<=n-2" for a while loop such as "while(i<n) i++;".

So this refinement should be performed at a higher level where t_init and t_enter are know... so as to have:

dom_tf = transformer_range(t_enter(t_init)).

That's all!

Definition at line 1067 of file fix_point.c.

1068 {
1069  transformer fix_tf = transformer_dup(tf);
1070 
1071  ifdebug(8) {
1072  pips_debug(8, "Begin for transformer %p:\n", tf);
1074  }
1075 
1076  if(transformer_empty_p(tf)) {
1077  /* I tried to use the standard procedure but arguments are not removed
1078  when the transformer tf is not feasible. Since we compute the * fix
1079  point and not the + fix point, the fix point is the identity. */
1080  free_transformer(fix_tf);
1081  fix_tf = transformer_identity();
1082  }
1083  else {
1084  //transformer inv_tf = transformer_undefined; /* invariant constraints of tf */
1085  /* sc is going to be modified and destroyed and eventually
1086  replaced in fix_tf */
1088  /* Do not handle variable which do not appear explicitly in constraints! */
1089  Pbase b = sc_to_minimal_basis(sc);
1090  Pbase ib = base_dup(sc_base(sc)); /* initial and final basis */
1091  Pbase bv = BASE_NULLE; /* basis vector */
1092  Pbase diffb = BASE_NULLE; /* basis of difference vectors */
1093 
1094  /* Compute constraints with difference equations */
1095 
1096  for(bv = b; !BASE_NULLE_P(bv); bv = bv->succ) {
1097  entity oldv = (entity) vecteur_var(bv);
1098 
1099  /* Only generate difference equations if the old value is used */
1100  if(old_value_entity_p(oldv)) {
1101  entity var = value_to_variable(oldv);
1102  entity newv = entity_to_new_value(var);
1103  entity diffv = entity_to_intermediate_value(var);
1104  Pvecteur diff = VECTEUR_NUL;
1106 
1107  diff = vect_make(diff,
1108  (Variable) diffv, VALUE_ONE,
1109  (Variable) newv, VALUE_MONE,
1110  (Variable) oldv, VALUE_ONE,
1111  TCST, VALUE_ZERO);
1112 
1113  eq = contrainte_make(diff);
1114  sc = sc_equation_add(sc, eq);
1115  }
1116  }
1117 
1118  ifdebug(8) {
1119  pips_debug(8, "with difference equations=\n");
1120  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1121  }
1122 
1123  /* Project all variables but differences to get T' */
1124 
1125  sc = sc_projection_ofl_along_variables(sc, b);
1126 
1127  ifdebug(8) {
1128  pips_debug(8, "Non-homogeneous constraints on derivatives=\n");
1129  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1130  }
1131 
1132  /* Multiply the constant terms by the iteration number ik and add a
1133  positivity constraint for the iteration number ik and then
1134  eliminate the iteration number ik to get T*(dx). */
1136  //Psysteme sc_t_prime_k = sc_dup(sc);
1137  //sc_t_prime_k = sc_multiply_constant_terms(sc_t_prime_k, (Variable) ik);
1138  sc = sc_multiply_constant_terms(sc, (Variable) ik, true);
1139  //Psysteme sc_t_prime_star = sc_projection_ofl(sc_t_prime_k, (Variable) ik);
1140  sc = sc_projection_ofl(sc, (Variable) ik);
1141  sc->base = base_remove_variable(sc->base, (Variable) ik);
1142  sc->dimension--;
1143  // FI: I do not remember nor find how to get rid of local values...
1144  //sc_rm(sc);
1145  //sc = sc_t_prime_star;
1146 
1147  ifdebug(8) {
1148  pips_debug(8, "All invariants on derivatives=\n");
1149  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1150  }
1151 
1152  /* Difference variables must substituted back to differences
1153  * between old and new values.
1154  */
1155 
1156  for(bv = b; !BASE_NULLE_P(bv); bv = bv->succ) {
1157  entity oldv = (entity) vecteur_var(bv);
1158 
1159  /* Only generate difference equations if the old value is used */
1160  if(old_value_entity_p(oldv)) {
1161  entity var = value_to_variable(oldv);
1162  entity newv = entity_to_new_value(var);
1163  entity diffv = entity_to_intermediate_value(var);
1164  Pvecteur diff = VECTEUR_NUL;
1166 
1167  diff = vect_make(diff,
1168  (Variable) diffv, VALUE_ONE,
1169  (Variable) newv, VALUE_MONE,
1170  (Variable) oldv, VALUE_ONE,
1171  TCST, VALUE_ZERO);
1172 
1173  eq = contrainte_make(diff);
1174  sc = sc_equation_add(sc, eq);
1175  diffb = base_add_variable(diffb, (Variable) diffv);
1176  }
1177  }
1178 
1179  ifdebug(8) {
1180  pips_debug(8,
1181  "All invariants on derivatives with difference variables=\n");
1182  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1183  }
1184 
1185  /* Project all difference variables */
1186 
1187  sc = sc_projection_ofl_along_variables(sc, diffb);
1188 
1189  ifdebug(8) {
1190  pips_debug(8, "All invariants on differences=\n");
1191  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1192  }
1193 
1194  /* The full basis must be used again */
1195  base_rm(sc_base(sc)), sc_base(sc) = BASE_NULLE;
1196  sc_base(sc) = ib;
1197  sc_dimension(sc) = vect_size(ib);
1198  base_rm(b), b = BASE_NULLE;
1199 
1200  ifdebug(8) {
1201  pips_debug(8, "All invariants with proper basis =\n");
1202  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1203  }
1204 
1205  /* Plug sc back into fix_tf */
1206  predicate_system(transformer_relation(fix_tf)) = sc;
1207 
1208  /* Add constraints about invariant variables. This could be avoided if
1209  implicit equalities were added before the derivative are processed:
1210  each invariant variable would generate an implicit null
1211  difference.
1212 
1213  Such invariant constraints do not exist in general. We have them when
1214  array references are trusted.
1215 
1216  This is wrong because we compute f* and not f+ and this is not true
1217  for the initial store.
1218 
1219  */
1220  /*
1221  inv_tf = transformer_arguments_projection(transformer_dup(tf));
1222  fix_tf = transformer_image_intersection(fix_tf, inv_tf);
1223  free_transformer(inv_tf);
1224  */
1225 
1226  /* What can be done instead is to refine fix_tf as :
1227  *
1228  * dom(tf) U tf(fix_tf(dom(tf)))
1229  *
1230  * But this fails because tf loops back to the beginning of the
1231  * next iteration. Hence, the domain of tf implies *two*
1232  * iterations instead of one. For instance, "i<n" becomes "i<=n-2"
1233  * for a while loop such as "while(i<n) i++;".
1234  *
1235  * So this refinement should be performed at a higher level where
1236  * t_init and t_enter are know... so as to have:
1237  *
1238  * dom_tf = transformer_range(t_enter(t_init)).
1239  */
1240  /*
1241  transformer dom_tf = transformer_to_domain(tf);
1242  transformer tf_plus = transformer_combine(copy_transformer(dom_tf), fix_tf);
1243  tf_plus = transformer_combine(tf_plus, tf);
1244  free_transformer(fix_tf);
1245  fix_tf = transformer_convex_hull(dom_tf, tf_plus);
1246  free_transformer(dom_tf);
1247  free_transformer(tf_plus);
1248  */
1249  }
1250  /* That's all! */
1251 
1252  ifdebug(8) {
1253  pips_debug(8, "fix-point fix_tf=\n");
1255  transformer_consistency_p(fix_tf);
1256  pips_debug(8, "end\n");
1257  }
1258 
1259  return fix_tf;
1260 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
#define VALUE_ZERO
#define VALUE_ONE
Pbase base_add_variable(Pbase b, Variable var)
Pbase base_add_variable(Pbase b, Variable v): add variable v as a new dimension to basis b at the end...
Definition: base.c:88
Pbase base_remove_variable(Pbase b, Variable v)
Pbase base_remove_variable(b, v): remove basis vector relative to v from b; abort if v is not in b;.
Definition: base.c:122
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
Psysteme sc_multiply_constant_terms(Psysteme sc, Variable ik, bool star_p)
Specific for the derivative fix point: each constant term in the constraints is multiplied by ik whic...
Definition: fix_point.c:1013
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
transformer fprint_transformer(FILE *fd, transformer tf, get_variable_name_t value_name)
Definition: io.c:69
#define transformer_relation(x)
Definition: ri.h:2873
#define predicate_system(x)
Definition: ri.h:2069
Pbase sc_to_minimal_basis(Psysteme ps)
creation d'une base contenant toutes les variables apparaissant avec des coefficients non-nuls dans l...
Definition: sc_alloc.c:76
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Psysteme sc_equation_add(Psysteme sc, Pcontrainte c)
The basis of the constraint system is updated.
Definition: sc_insert_eq.c:101
void sc_fprint(FILE *fp, Psysteme ps, get_variable_name_t nom_var)
void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()): cette fonction imprime dans le fichier po...
Definition: sc_io.c:220
Pbase base
Definition: sc-local.h:75
int dimension
Definition: sc-local.h:74
struct Svecteur * succ
Definition: vecteur-local.h:92
const char * external_value_name(entity)
Definition: value.c:753
bool old_value_entity_p(entity)
Definition: value.c:936
entity entity_to_intermediate_value(entity)
Definition: value.c:879
entity entity_to_new_value(entity)
Definition: value.c:859
entity make_local_temporary_integer_value_entity(void)
Definition: value.c:629
entity value_to_variable(entity)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624
#define vecteur_var(v)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
#define base_rm(b)
#define BASE_NULLE
MACROS SUR LES BASES.
#define BASE_NULLE_P(b)
Pvecteur vect_make(Pvecteur v, Variable var, Value val,...)
Pvecteur vect_make(v, [var, val,]* 0, val) Pvecteur v; // may be NULL, use assigne anyway Variable va...
Definition: alloc.c:165
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268

References Ssysteme::base, base_add_variable(), base_dup(), BASE_NULLE, BASE_NULLE_P, base_remove_variable(), base_rm, contrainte_make(), CONTRAINTE_UNDEFINED, Ssysteme::dimension, entity_to_intermediate_value(), entity_to_new_value(), eq, external_value_name(), fprint_transformer(), free_transformer(), ifdebug, make_local_temporary_integer_value_entity(), old_value_entity_p(), pips_debug, predicate_system, sc_equation_add(), sc_fprint(), sc_multiply_constant_terms(), sc_to_minimal_basis(), Svecteur::succ, TCST, transformer_consistency_p(), transformer_dup(), transformer_empty_p(), transformer_identity(), transformer_relation, VALUE_MONE, VALUE_ONE, value_to_variable(), VALUE_ZERO, vect_make(), vect_size(), VECTEUR_NUL, and vecteur_var.

Referenced by invariant_wrt_transformer(), and select_fix_point_operator().

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

◆ transformer_equality_fix_point()

transformer transformer_equality_fix_point ( transformer  tf)

Let A be the affine loop transfert function.

The affine transfer fix-point T is such that T(A-I) = 0

T A = 0 also gives a fix-point when merged with the initial state. It can only be used to compute preconditions.

Algorithm (let H be A's Smith normal form):

A = A - I (if necessary) H = P A Q A = P^-1 H Q^-1 T A = T P^-1 H Q^-1 = 0 T P^-1 H = 0 (by multipliying by Q)

Soit X t.q. X H = 0 A basis for all solutions is given by X chosen such that X is a rectangular matrix (0 I) selecting the zero submatrix of H

T P^-1 = X T = X P

Note: I (FI) believe this functions is wrong because it does not return the appropriate arguments. The fix point transformer should modify as many variables as the input tf. A new basis should not be recomputed according to the transition matrix. This problem seems to be fixed in the callers, see loop_to_transformer() and whileloop_to_transformer().

result

do not modify an input argument

number of transfer equalities plus the homogeneous constraint which states that 1 == 1

use a matrix a to store these equalities in a dense form

Pbase t = BASE_UNDEFINED;

If the input transformer is not feasible, so is not its fixpoint because the number of iterations may be zero which implies identity.

fix_tf = transformer_identity();

find or build explicit transfer equations: v::new = f(v1::old, v2::old,...) and the corresponding sub-basis

FI: for each constant variable, whose constance is implictly implied by not having it in the argument field, an equation should be added...

lieq = build_implicit_equalities(tf); lieq->succ = leq; leq = lieq;

build matrix a from lteq and b_new: this should be moved in a function

Subtract the identity matrix

Compute the Smith normal form: H = P A Q

Find out the number of invariants n_inv

Convert p's last n_inv rows into constraints

FI: maybe I should retrieve fix_tf system...

is it a non-trivial invariant?

Set fix_tf's argument list

Fix the basis and the dimension

get rid of dense matrices

Definition at line 266 of file fix_point.c.

267 {
268  /* result */
270 
271  /* do not modify an input argument */
272  transformer tf_copy = transformer_dup(tf);
273 
274  /* number of transfer equalities plus the homogeneous constraint which
275  states that 1 == 1 */
276  int n_eq = 1;
277  /* use a matrix a to store these equalities in a dense form */
282  Pbase b_new = BASE_NULLE;
284  Pcontrainte leq = sc_egalites((Psysteme) predicate_system(transformer_relation(tf_copy)));
285 
286  Psysteme sc_inv = SC_UNDEFINED;
287  int n_inv = 0;
288 
289  int i = 0;
290  /* Pbase t = BASE_UNDEFINED; */
291 
292  ifdebug(8) {
293  pips_debug(8, "begin for transformer %p\n", tf);
294  fprint_transformer(stderr, tf,
296  }
297 
298  /* If the input transformer is not feasible, so is not its fixpoint
299  * because the number of iterations may be zero which implies identity.
300  */
301  if(transformer_empty_p(tf)) {
302  /* fix_tf = transformer_identity(); */
303  ifdebug(8) {
304  pips_debug(8, "fix-point fix_tf=\n");
305  fprint_transformer(stderr, fix_tf,
307  pips_debug(8, "end\n");
308  }
309  return fix_tf;
310  }
311 
312  /* find or build explicit transfer equations: v#new = f(v1#old, v2#old,...)
313  * and the corresponding sub-basis
314  *
315  * FI: for each constant variable, whose constance is implictly
316  * implied by not having it in the argument field, an equation
317  * should be added...
318  *
319  * lieq = build_implicit_equalities(tf);
320  * lieq->succ = leq;
321  * leq = lieq;
322  */
323  build_transfer_equations(leq, &lteq, &b_new);
324 
325  /* build matrix a from lteq and b_new: this should be moved in a function */
326  n_eq = base_dimension(b_new)+1;
327  build_transfer_matrix(&a , lteq, n_eq, b_new);
328  ifdebug(8) {
329  pips_debug(8, "transfer matrix:\n");
330  matrice_fprint(stderr, a, n_eq, n_eq);
331  }
332 
333  /* Subtract the identity matrix */
334  for(i=1; i<= n_eq; i++) {
335  value_substract(ACCESS(a, n_eq, i, i),VALUE_ONE);
336  }
337 
338  /* Compute the Smith normal form: H = P A Q */
339  h = matrice_new(n_eq, n_eq);
340  p = matrice_new(n_eq, n_eq);
341  q = matrice_new(n_eq, n_eq);
342  DENOMINATOR(h) = VALUE_ONE;
343  DENOMINATOR(p) = VALUE_ONE;
344  DENOMINATOR(q) = VALUE_ONE;
345  matrice_smith(a, n_eq, n_eq, p, h, q);
346 
347  ifdebug(8) {
348  pips_debug(8, "smith matrix h=p.a.q:\n");
349  matrice_fprint(stderr, h, n_eq, n_eq);
350  pips_debug(8, "p matrix:\n");
351  matrice_fprint(stderr, p, n_eq, n_eq);
352  pips_debug(8, "q matrix:\n");
353  matrice_fprint(stderr, q, n_eq, n_eq);
354  }
355 
356  /* Find out the number of invariants n_inv */
357  for(i=1; i <= n_eq &&
358  value_notzero_p(ACCESS(h, n_eq, i, i)) ; i++)
359  ;
360  n_inv = n_eq - i + 1;
361  pips_debug(8, "number of useful invariants: %d\n", n_inv-1);
362  pips_assert("n_inv>=1", n_inv >= 1);
363 
364  /* Convert p's last n_inv rows into constraints */
365  /* FI: maybe I should retrieve fix_tf system... */
366  sc_inv = sc_new();
367 
368  for(i = n_eq - n_inv + 1 ; i <= n_eq; i++) {
369  int j;
370  /* is it a non-trivial invariant? */
371  for(j=1; j<= n_eq-1 && value_zero_p(ACCESS(p, n_eq, i, j)); j++)
372  ;
373  if( j != n_eq) {
374  Pvecteur v_inv = VECTEUR_NUL;
376 
377  for(j = 1; j<= n_eq; j++) {
378  Value coeff = ACCESS(p, n_eq, i, j);
379 
380  if(value_notzero_p(coeff)) {
381  entity n_eb = (entity) variable_of_rank(b_new, j);
382  entity o_eb = new_value_to_old_value(n_eb);
383 
384  vect_add_elem(&v_inv, (Variable)n_eb, coeff);
385  vect_add_elem(&v_inv, (Variable)o_eb, value_uminus(coeff));
386  }
387  }
388  c_inv = contrainte_make(v_inv);
389  sc_add_egalite(sc_inv, c_inv);
390  }
391  }
392 
393  sc_creer_base(sc_inv);
394 
395  ifdebug(8) {
396  pips_debug(8, "fix-point sc_inv=\n");
397  sc_fprint(stderr, sc_inv, (char * (*)(Variable)) external_value_name);
398  pips_debug(8, "end\n");
399  }
400 
401  /* Set fix_tf's argument list */
402  /*
403  for(t = b_new; !BASE_NULLE_P(t); t = t->succ) {
404  I should use a conversion function from value_to_variable()
405  entity arg = (entity) vecteur_var(t);
406 
407  transformer_arguments(fix_tf) = arguments_add_entity(transformer_arguments(fix_tf), arg);
408  }
409  */
411  /* Fix the basis and the dimension */
412  sc_base(sc_inv) = base_dup(sc_base(predicate_system(transformer_relation(tf))));
413  sc_dimension(sc_inv) = sc_dimension(predicate_system(transformer_relation(tf)));
414  transformer_relation(fix_tf) = make_predicate(sc_inv);
415 
416  /* get rid of dense matrices */
417  matrice_free(a);
418  matrice_free(h);
419  matrice_free(p);
420  matrice_free(q);
421 
422  free_transformer(tf_copy);
423 
424  ifdebug(8) {
425  pips_debug(8, "fix-point fix_tf=\n");
427  pips_debug(8, "end\n");
428  }
429 
430  return fix_tf;
431 }
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
cons * dup_arguments(cons *args)
Definition: arguments.c:225
#define value_notzero_p(val)
#define value_uminus(val)
unary operators on values
#define value_zero_p(val)
int Value
#define value_substract(ref, val)
void build_transfer_equations(Pcontrainte leq, Pcontrainte *plteq, Pbase *pb_new)
Definition: fix_point.c:433
static void build_transfer_matrix(matrice *, Pcontrainte, int, Pbase)
Must be declared explicity to keep a logical order in this C file.
Definition: fix_point.c:601
#define DENOMINATOR(matrix)
int DENOMINATEUR(matrix): acces au denominateur global d'une matrice matrix La combinaison *(&()) est...
Definition: matrice-local.h:93
#define matrice_free(m)
Definition: matrice-local.h:78
#define ACCESS(matrix, column, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrice-local.h:86
#define matrice_new(n, m)
Allocation et desallocation d'une matrice.
Definition: matrice-local.h:77
Value * matrice
package matrice
Definition: matrice-local.h:71
#define MATRICE_UNDEFINED
Definition: matrice-local.h:73
void matrice_smith(matrice, int, int, matrice, matrice, matrice)
smith.c
Definition: smith.c:68
void matrice_fprint(FILE *, matrice, int, int)
matrice_io.c
Definition: matrice_io.c:62
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
Variable variable_of_rank()
entity new_value_to_old_value(entity)
Definition: value.c:1710
#define base_dimension(b)

References ACCESS, base_dimension, base_dup(), BASE_NULLE, build_transfer_equations(), build_transfer_matrix(), contrainte_make(), CONTRAINTE_UNDEFINED, DENOMINATOR, dup_arguments(), external_value_name(), fprint_transformer(), free_transformer(), ifdebug, make_predicate(), matrice_fprint(), matrice_free, matrice_new, matrice_smith(), MATRICE_UNDEFINED, new_value_to_old_value(), pips_assert, pips_debug, predicate_system, sc_add_egalite(), sc_creer_base(), sc_fprint(), sc_new(), transformer_arguments, transformer_dup(), transformer_empty_p(), transformer_identity(), transformer_relation, value_notzero_p, VALUE_ONE, value_substract, value_uminus, value_zero_p, variable_of_rank(), vect_add_elem(), and VECTEUR_NUL.

Referenced by select_fix_point_operator(), and standard_whileloop_to_transformer().

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

◆ transformer_pattern_fix_point()

transformer transformer_pattern_fix_point ( transformer  tf)

This fixpoint function was developped to present a talk at FORMA.

I used examples published by Pugh and I realized that the fixpoint constraints were obvious in the loop body transformer. You just had to identify them. This is not a clever algorithm. It certainly would not resist any messing up with the constraints, i.e. a change of basis. But it provides very good result for a class of applications.

Algorithm:

  1. Find a loop counter
  2. Use it to eliminate all constant terms
  3. Look for invariant constraints

Let d_i = i::new - i::old. An invariant constraint is a sum of d_i which is equal to zero or greater than zero. Such a constraint is its own fixpoint: if you combine it with itself after renaming i::new as i::int on one hand and i::old as i::int on the other, the global sum for and equation or its sign for an inequality is unchanged.

result

Look for the best loop counter: the smallest increment is chosen

eliminate sharing between v_inc and fix_sc

Replace constant terms in equalities and inequalities by loop counter differences

Remove all constraints to build the invariant transformer

Definition at line 709 of file fix_point.c.

710 {
711  /* result */
712  transformer fix_tf = transformer_dup(tf);
714  Pvecteur v_inc = VECTEUR_UNDEFINED;
715 
716  ifdebug(8) {
717  pips_debug(8, "Begin for transformer %p:\n", tf);
718  fprint_transformer(stderr, tf,
720  }
721 
722  /* Look for the best loop counter: the smallest increment is chosen */
723  v_inc = look_for_the_best_counter(sc_egalites(fix_sc));
724 
725  if(!VECTEUR_UNDEFINED_P(v_inc)) {
726 
727  ifdebug(8) {
728  pips_debug(8, "incrementation vector=\n");
729  vect_fprint(stderr, v_inc, (char * (*)(Variable)) external_value_name);
730  }
731 
732  /* eliminate sharing between v_inc and fix_sc */
733  v_inc = vect_dup(v_inc);
734 
735  /* Replace constant terms in equalities and inequalities by
736  * loop counter differences
737  */
738  fix_sc = sc_eliminate_constant_terms(fix_sc, v_inc);
739 
740  ifdebug(8) {
741  pips_debug(8, "after constant term elimination=\n");
742  sc_fprint(stderr, fix_sc, (char * (*)(Variable)) external_value_name);
743  }
744 
745  fix_sc = sc_elim_redund(fix_sc);
746 
747  ifdebug(8) {
748  pips_debug(8, "after normalization=\n");
749  sc_fprint(stderr, fix_sc, (char * (*)(Variable)) external_value_name);
750  }
751 
752  fix_sc = sc_keep_invariants_only(fix_sc);
753 
754  ifdebug(8) {
755  pips_debug(8, "after non-invariant elimination=\n");
756  sc_fprint(stderr, fix_sc, (char * (*)(Variable)) external_value_name);
757  }
758 
759  fix_sc = sc_elim_redund(fix_sc);
760 
761  ifdebug(8) {
762  pips_debug(8, "after 2nd normalization=\n");
763  sc_fprint(stderr, fix_sc, (char * (*)(Variable)) external_value_name);
764  }
765  }
766  else {
767  pips_debug(8, "No counter found\n");
768  /* Remove all constraints to build the invariant transformer */
769  contraintes_free(sc_egalites(fix_sc));
770  sc_egalites(fix_sc) = CONTRAINTE_UNDEFINED;
771  sc_nbre_egalites(fix_sc) = 0;
772  contraintes_free(sc_inegalites(fix_sc));
773  sc_inegalites(fix_sc) = CONTRAINTE_UNDEFINED;
774  sc_nbre_inegalites(fix_sc) = 0;
775  }
776 
777  ifdebug(8) {
778  pips_debug(8, "fix-point fix_tf=\n");
780  pips_debug(8, "end\n");
781  }
782 
783  return fix_tf;
784 }
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226
Pvecteur look_for_the_best_counter(Pcontrainte egs)
Try to identify a loop counter among the equation egs.
Definition: fix_point.c:797
Psysteme sc_keep_invariants_only(Psysteme sc)
This function cannot be moved into the Linear library.
Definition: fix_point.c:902
Psysteme sc_eliminate_constant_terms(Psysteme sc, Pvecteur v)
Eliminate all constant terms in sc using v.
Definition: fix_point.c:853
void vect_fprint(FILE *f, Pvecteur v, get_variable_name_t variable_name)
void vect_fprint(FILE * f, Pvecteur v, char * (*variable_name)()): impression d'un vecteur creux v su...
Definition: io.c:124
struct Ssysteme * Psysteme
Psysteme sc_elim_redund(Psysteme ps)
Psysteme sc_elim_redund(Psysteme ps): elimination des contraintes lineaires redondantes dans le syste...
#define VECTEUR_UNDEFINED
#define VECTEUR_UNDEFINED_P(v)
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51

References CONTRAINTE_UNDEFINED, contraintes_free(), external_value_name(), fprint_transformer(), ifdebug, look_for_the_best_counter(), pips_debug, predicate_system, sc_elim_redund(), sc_eliminate_constant_terms(), sc_fprint(), sc_keep_invariants_only(), transformer_dup(), transformer_relation, vect_dup(), vect_fprint(), VECTEUR_UNDEFINED, and VECTEUR_UNDEFINED_P.

Referenced by select_fix_point_operator().

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

◆ transformers_inter_fast()

bool transformers_inter_fast ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 310 of file dbm_interface.c.

311 {
317  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
319 }
bool module_name_to_transformers(const char *module_name)

References module_name(), module_name_to_transformers(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ transformers_inter_full()

bool transformers_inter_full ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 321 of file dbm_interface.c.

322 {
328  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
330 }

References module_name(), module_name_to_transformers(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ transformers_inter_full_with_points_to()

bool transformers_inter_full_with_points_to ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 332 of file dbm_interface.c.

333 {
339  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
341  db_get_memory_resource(DBR_POINTS_TO, module_name, true) );
344 
345  return result;
346 }

References db_get_memory_resource(), module_name(), module_name_to_transformers(), reset_pt_to_list(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, set_bool_property(), and set_pt_to_list().

+ Here is the call graph for this function:

◆ transformers_intra_fast()

bool transformers_intra_fast ( char *  module_name)

Functions to make transformers.

Set properties as required for a very fast semantics analysis

No need to select a fix point operator given the above property, but just in case...

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Restaure initial values of modified properties

Parameters
module_nameodule_name

Definition at line 254 of file dbm_interface.c.

255 {
259  bool result = true;
260 
261  /* Set properties as required for a very fast semantics analysis */
262  if(si) {
263  pips_user_warning("Property SEMANTICS_INTERPROCEDURAL is ignored\n");
265  }
266  if(!sfs) {
267  pips_user_warning("Property SEMANTICS_FLOW_SENSITIVE is ignored\n");
269  }
270  if(sfp) {
271  pips_user_warning("Property SEMANTICS_FIX_POINT is ignored\n");
273  }
274  /* No need to select a fix point operator given the above property, but just in case... */
276 
278  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
279 
280  if(get_bool_property("SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT")) {
281  pips_user_warning("If you really want to set property "
282  "SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT, "
283  "you should activate TRANSFORMERS_INTER_FULL\n");
284  }
285 
287 
288  /* Restaure initial values of modified properties */
289  if(si)
291  if(!sfs)
293  if(sfp)
295 
296  return result;
297 }

References get_bool_property(), module_name(), module_name_to_transformers(), pips_user_warning, select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ transformers_intra_full()

bool transformers_intra_full ( char *  module_name)

set_int_property(SEMANTICS_DEBUG_LEVEL, 0);

Parameters
module_nameodule_name

Definition at line 299 of file dbm_interface.c.

300 {
306  /* set_int_property(SEMANTICS_DEBUG_LEVEL, 0); */
308 }

References module_name(), module_name_to_transformers(), select_fix_point_operator(), SEMANTICS_FIX_POINT, SEMANTICS_FLOW_SENSITIVE, SEMANTICS_INTERPROCEDURAL, SEMANTICS_STDOUT, and set_bool_property().

+ Here is the call graph for this function:

◆ update_summary_precondition()

void update_summary_precondition ( entity  e,
transformer  t 
)

void update_summary_precondition(e, t): t is supposed to be a precondition related to one of e's call sites and translated into e's basis;

the current global precondition for e is replaced by its convex hull with t;

t may be slightly modified by transformer_convex_hull because of bad design (FI)

Definition at line 1390 of file dbm_interface.c.

1391 {
1394 
1395  pips_assert("update_summary_precondition", entity_module_p(e));
1396 
1397  debug(8, "update_summary_precondition", "begin\n");
1398 
1399  t_old = (transformer)
1400  db_get_memory_resource(DBR_SUMMARY_PRECONDITION, module_local_name(e),
1401  true);
1402 
1403  ifdebug(8) {
1404  debug(8, "update_summary_precondition", " old precondition for %s:\n",
1405  entity_local_name(e));
1406  print_transformer(t_old);
1407  }
1408 
1409  if(t_old == transformer_undefined)
1410  t_new = transformer_dup(t);
1411  else {
1412  t_new = transformer_convex_hull(t_old, t);
1413  transformer_free(t_old);
1414  }
1415 
1416  DB_PUT_MEMORY_RESOURCE(DBR_SUMMARY_PRECONDITION,
1417  module_local_name(e),
1418  (char*) t_new );
1419 
1420  ifdebug(8) {
1421  debug(8, "update_summary_precondition", "new precondition for %s:\n",
1422  entity_local_name(e));
1423  print_transformer(t_new);
1424  debug(8, "update_summary_precondition", "end\n");
1425  }
1426 }
void transformer_free(transformer t)
Definition: basic.c:68
transformer transformer_convex_hull(transformer t1, transformer t2)
transformer transformer_convex_hull(t1, t2): compute convex hull for t1 and t2; t1 and t2 are slightl...
Definition: convex_hull.c:216

References db_get_memory_resource(), DB_PUT_MEMORY_RESOURCE, debug(), entity_local_name(), entity_module_p(), ifdebug, module_local_name(), pips_assert, print_transformer, transformer_convex_hull(), transformer_dup(), transformer_free(), and transformer_undefined.

+ Here is the call graph for this function:

◆ use_points_to_p()

bool use_points_to_p ( void  )

Definition at line 565 of file dbm_interface.c.

566 {
568 }

References use_points_to_information_p.

Referenced by update_precondition_with_call_site_preconditions().

+ Here is the caller graph for this function:

Variable Documentation

◆ refine_transformers_p

bool refine_transformers_p = false

Transformer recomputation cannot be of real use unless an interprocedural analysis is performed.

For intraprocedural analyses, using property SEMANTICS_COMPUTE_TRANSFORMERS_IN_CONTEXT is sufficient.

Definition at line 352 of file dbm_interface.c.

Referenced by process_ready_node(), refine_transformers(), refine_transformers_with_points_to(), statement_to_transformer(), and statement_to_transformer_list().

◆ transformer_fix_point_operator

transformer(* transformer_fix_point_operator) (transformer) ( transformer  )
extern

Interface between the untyped database manager and clean code and between pipsmake and clean code.

There are other interface routines in prettyprint.c

The top routines should be called by the PIPS make utility. They might eventually be integrated into it.

The lower level routines are dealing with "statement_mapping"s. They might have to be updated when mappings are integrated into NewGen. At that time, the whole file should disappear in a typed pipsmake.

Francois Irigoin, August 1990 the lowest level routines dealing with "statement_mapping"s are now generated by a macro defined in mapping.h : DEFINE_CURRENT_MAPPING. see this file for more details.

Be'atrice Apvrille, August 1993 FC 2015-07-21: redundant declarations to help with include cycle issues there are expected in "transformer.h"

Interface between the untyped database manager and clean code and between pipsmake and clean code.

Several algorithms are available:

  • two untested versions using Halwachs approach; sc_elarg() was found to be very slow in an earlier implementation by Malik; experimentally, we did not find scientific Frotran programs that required such an algorithm.
  • a fix point algorithm based on the transfer matrix linking the new values to the old values; this is sufficient for induction variables but only equations can be found.
  • a fix point algorithm based on pattern matching which was developped experimentally for examples presented at FORMA; once the constant terms are eliminated using a loop counter, the constraints which are their own fixpoints are easy to pattern match; equations and inequalities can both be found.
  • a fix point algorithm combining the last two algorithms above. This algorithm adds difference variables d_i = i::new - i::old for each variable i. All non d_i variables are thn projected. If the projection algorithm is sophisticated enough, the projection ordering will be "good". Left over inequalities are invariant or useless. Let N be the strictly positive iteration count:

    sum ai di <= -k implies N sum ai di <= -Nk <= -k (OK)

    sum ai di <= k implies N sum ai di <= Nk <= infinity (useless unless k == 0)

    Left over equations can stay equations if the constant term is 0, or be degraded into an inequation if not. The nw inequation depends on the sign of the constant:

    sum ai di == -k implies N sum ai di == -Nk <= -k

    sum ai di == k implies N sum ai di == Nk >= k

    sum ai di == 0 implies N sum ai di == 0

    In a second step, the constant terms are eliminated to obtain new constraints leading to new invariants, using the same rules as above.

    This algorithm was designed for while loops such as:

    WHILE( I > 0 ) J = J + I I = I - 1

    to find as loop transformer T(I,J) {I::new <= I::old - 1, J::new >= J::old + 1, I::new+J::new >= I::old + J::old}

    Note that the second constraint is redundant with the other two, but the last one cannot be found before the constant terms are eliminated.

The current algorithm, the derivative version, is published and describes in NSAD 2010, A/426/CRI. See also A/429/CRI: http://www.cri.ensmp.fr/classement/doc/A-429.pdf

Francois Irigoin, 21 April 1990 The fixpoint operator is selected according to properties

Definition at line 114 of file fix_point.c.

Referenced by select_fix_point_operator(), and standard_whileloop_to_transformer().

◆ use_points_to_information_p

bool use_points_to_information_p = false
static

Definition at line 553 of file dbm_interface.c.

Referenced by reset_use_points_to(), set_use_points_to(), and use_points_to_p().

◆ wc

int wc = 0
static

FI: Provisional management of warnings.

To avoid repetitive warnings.

A hash table could be used to count warnings according to the function and line number in the C file.

Definition at line 901 of file dbm_interface.c.

Referenced by set_warning_counters(), test_warning_counters(), and VASNPRINTF().